pax_global_header00006660000000000000000000000064150041624200014504gustar00rootroot0000000000000052 comment=a7749d7b54e8d899e99ef2f1c8ee099f822dc6ad qatengine-1.9.0/000077500000000000000000000000001500416242000134665ustar00rootroot00000000000000qatengine-1.9.0/.github/000077500000000000000000000000001500416242000150265ustar00rootroot00000000000000qatengine-1.9.0/.github/dependabot.yml000066400000000000000000000010011500416242000176460ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "github-actions" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" qatengine-1.9.0/.gitignore000066400000000000000000000012321500416242000154540ustar00rootroot00000000000000# Object files *.o *.obj *.ko *.lo *.m4 *.d # Editor artefacts *.swp *.bak .#* \#*# *~ tags TAGS cscope.out /.dir-locals.el testapp.log QAT_HW.tar.gz QAT_HW/ # Top level and qat_contig_mem excludes *.mod* *.cmd *.symvers *.order *.old *.tmp_versions qat_contig_mem_test # Shared objects *.so* *.so.* *.dylib* *.dll* *.exe *.lib *.la testapp qatengine_test kpttool # Autotools generated files *.deps *.dirstamp *.libs /m4 /aclocal.m4 /autom4te.cache/ /config.log /Makefile /Makefile.in /Makefile.save /config.h /config.h.in /config.status /config.guess /config.sub /configure /install-sh /missing /libtool /stamp-h1 /ar-lib /compile /depcomp /ltmain.sh /rpmbuild qatengine-1.9.0/.gitmodules000066400000000000000000000006361500416242000156500ustar00rootroot00000000000000[submodule "openssl"] path = openssl url = https://github.com/openssl/openssl.git [submodule "intel-ipsec-mb"] path = intel-ipsec-mb url = https://github.com/intel/intel-ipsec-mb.git [submodule "cryptography-primitives"] path = cryptography-primitives url = https://github.com/intel/cryptography-primitives [submodule "haproxy"] path = dockerfiles/haproxy/haproxy url = https://github.com/haproxy/haproxy qatengine-1.9.0/LICENSE000066400000000000000000000030411500416242000144710ustar00rootroot00000000000000 BSD-3-Clause License Copyright(c) 2016-2025 Intel Corporation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. qatengine-1.9.0/LICENSE.BORINGSSL000066400000000000000000000303361500416242000160410ustar00rootroot00000000000000BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL licensing. Files that are completely new have a Google copyright and an ISC license. This license is reproduced at the bottom of this file. Contributors to BoringSSL are required to follow the CLA rules for Chromium: https://cla.developers.google.com/clas Files in third_party/ have their own licenses, as described therein. The MIT license, for third_party/fiat, which, unlike other third_party directories, is compiled into non-test libraries, is included below. The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit. See below for the actual license texts. Actually both licenses are BSD-style Open Source licenses. In case of any license issues related to OpenSSL please contact openssl-core@openssl.org. The following are Google-internal bug numbers where explicit permission from some authors is recorded for use of their work. (This is purely for our own record keeping.) 27287199 27287880 27287883 OpenSSL License --------------- /* ==================================================================== * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@openssl.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ Original SSLeay License ----------------------- /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ ISC license used for completely new code in BoringSSL: /* Copyright (c) 2015, Google Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ The code in third_party/fiat carries the MIT license: Copyright (c) 2015-2016 the fiat-crypto authors (see https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Licenses for support code ------------------------- Parts of the TLS test suite are under the Go license. This code is not included in BoringSSL (i.e. libcrypto and libssl) when compiled, however, so distributing code linked against BoringSSL does not trigger this license: Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. BoringSSL uses the Chromium test infrastructure to run a continuous build, trybots etc. The scripts which manage this, and the script for generating build metadata, are under the Chromium license. Distributing code linked against BoringSSL does not trigger this license. Copyright 2015 The Chromium Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. qatengine-1.9.0/LICENSE.OPENSSL000066400000000000000000000236771500416242000156340ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS qatengine-1.9.0/LICENSE.PLOCK000066400000000000000000000022201500416242000153360ustar00rootroot00000000000000/* plock - progressive locks * * Copyright (C) 2012-2025 Willy Tarreau * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */qatengine-1.9.0/Makefile.am000066400000000000000000000220251500416242000155230ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = subdir-objects lib_LTLIBRARIES = @LIBQATNAME@.la bin_PROGRAMS = if !QAT_BORINGSSL QAT_COMMON_SRC = e_qat.c \ qat_fork.c \ qat_events.c \ qat_utils.c \ qat_evp.c \ qat_err.c if QAT_PROVIDER QAT_PROV_SRC = qat_prov_init.c \ qat_prov_kmgmt_rsa.c \ qat_prov_sign_rsa.c \ qat_prov_rsa.c \ qat_prov_rsa_enc_dec.c \ qat_prov_kmgmt_ecx.c \ qat_prov_exch_ecx.c \ qat_prov_ciphers.c \ qat_prov_kmgmt_ec.c \ qat_prov_ecdsa.c \ qat_prov_ecdh.c \ qat_prov_dsa.c \ qat_prov_kmgmt_dsa.c \ qat_prov_dh.c \ qat_prov_kmgmt_dh.c \ qat_prov_hkdf.c \ qat_prov_prf.c \ qat_prov_cbc.c \ qat_prov_sha3.c \ qat_prov_bio.c \ qat_prov_capabilities.c \ qat_prov_chachapoly.c \ qat_prov_sign_sm2.c \ qat_prov_hkdf_packet.c \ qat_prov_sm4_gcm.c \ qat_prov_sm4_ccm.c \ qat_prov_sm4_cbc.c \ qat_prov_sm3.c \ qat_prov_aes_ccm.c if QAT_FIPS QAT_FIPS_SRC = qat_fips.c \ qat_self_test_kats.c \ qat_self_test_tls_prf.c \ qat_prov_cmvp.c \ qat_prov_sha2.c \ qat_sw_sha2.c endif endif if QAT_HW QAT_HW_SRC = qat_hw_init.c \ qat_hw_asym_common.c \ qat_hw_polling.c \ qat_hw_callback.c \ qat_hw_usdm_inf.c \ qat_hw_rsa.c \ qat_hw_ciphers.c \ qat_hw_dh.c \ qat_hw_dsa.c \ qat_hw_ec.c \ qat_hw_prf.c \ qat_hw_gcm.c \ qat_hw_hkdf.c \ qat_hw_ecx.c \ qat_hw_sha3.c \ qat_hw_chachapoly.c \ qat_hw_sm4_cbc.c \ qat_hw_sm3.c \ qat_hw_sm2.c \ qat_hw_ccm.c if ENABLE_QAT_HW_KPT QAT_HW_KPT_SRC = qat_hw_kpt.c endif endif if QAT_SW QAT_SW_SRC = qat_sw_init.c \ qat_sw_polling.c \ qat_sw_freelist.c \ qat_sw_queue.c \ qat_sw_rsa.c \ qat_sw_ecx.c \ qat_sw_ec.c \ qat_sw_sm2.c \ qat_sw_sm3.c \ qat_sw_sm4_cbc.c \ qat_sw_sm4_gcm.c \ qat_sw_sm4_ccm.c endif if QAT_SW_IPSEC QAT_SW_IPSEC_SRC = qat_sw_gcm.c \ qat_sw_ipsec_inf.c endif endif if QAT_BORINGSSL QAT_COMMON_SRC = e_qat.c \ qat_utils.c \ qat_fork.c \ qat_events.c \ qat_evp.c \ qat_bssl.c \ qat_bssl_err.c if QAT_HW QAT_HW_SRC = qat_hw_init.c \ qat_hw_asym_common.c \ qat_hw_usdm_inf.c \ qat_hw_polling.c \ qat_hw_callback.c \ qat_hw_rsa.c \ qat_hw_ec.c endif if QAT_SW QAT_SW_SRC = qat_sw_init.c \ qat_sw_polling.c \ qat_sw_freelist.c \ qat_sw_queue.c \ qat_sw_rsa.c \ qat_sw_ec.c endif endif @LIBQATNAME@_la_SOURCES = ${QAT_COMMON_SRC} \ ${QAT_PROV_SRC} \ ${QAT_FIPS_SRC} \ ${QAT_HW_SRC} \ ${QAT_SW_SRC} \ ${QAT_SW_IPSEC_SRC} \ ${QAT_HW_KPT_SRC} AM_CPPFLAGS = $(includes_openssl) $(includes_qat_hw) $(includes_qat_sw_crypto_mb) \ $(includes_qat_sw_ipsec_mb) $(includes_kpt_lib) AM_CFLAGS = $(cflags_cc_opt) $(cflags_qat_hw_intree) \ $(cflags_openssl_3) $(cflags_boringssl) \ $(cflags_qat_hw) $(cflags_qat_sw) \ $(cflags_qat_sw_ipsec) $(cflags_common) \ $(cflags_qat_debug) if QAT_BORINGSSL bin_PROGRAMS += qatengine_test @LIBQATNAME@_la_LDFLAGS = -no-undefined -avoid-version \ $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) \ $(QAT_SW_CRYPTO_MB_LIB) \ $(QAT_SW_IPSEC_MB_LIB) $(QAT_BORINGSSL_LIB) qatengine_test_LDFLAGS = $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) \ $(QAT_SW_CRYPTO_MB_LIB) \ $(QAT_SW_IPSEC_MB_LIB) $(QAT_BORINGSSL_LIB) qatengine_test_SOURCES = test_bssl/main.c \ test_bssl/test_bssl_rsa.c \ test_bssl/test_bssl_ecdsa.c \ test_bssl/test_bssl_utils.c qatengine_test_LDADD = $(lib_LTLIBRARIES) -lpthread else @LIBQATNAME@_la_LDFLAGS = -module -no-undefined -avoid-version \ -shared $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) \ $(QAT_SW_CRYPTO_MB_LIB) $(QAT_SW_IPSEC_MB_LIB) endif if QAT_PLOCK lib_LTLIBRARIES += libplock.la libplock_la_LDFLAGS = --shared -fPIC -Wextra -Wundef \ -Wdeclaration-after-statement -Wfatal-errors \ -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 \ -Wduplicated-cond -Wnull-dereference \ -Wno-address-of-packed-member -Wno-unused-label \ -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \ -Wno-missing-field-initializers -Wno-cast-function-type \ -Wno-string-plus-int -Wno-atomic-alignment libplock_la_SOURCES = plock.c endif if ENABLE_QAT_HW_KPT noinst_LTLIBRARIES = libkpt.la libkpt_la_SOURCES = kpt/lib/kpt.c libkpt_la_CFLAGS = $(includes_qat_hw) $(includes_openssl) \ $(cflags) $(cflags_openssl_3) \ $(cflags_common) libkpt_la_LDFLAGS = $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) \ $(OPENSSL_LIB) -ldl -lrt -lpthread EXTRA_PROGRAMS = kpttool testapp kpttool_SOURCES = kpt/apps/main.c \ kpt/apps/kpt_swk.c \ kpt/apps/kpt_rsa_key.c \ kpt/apps/kpt_ecc_key.c \ kpt/apps/kpt_dev_pp.c kpttool_CFLAGS = $(includes_qat_hw) $(includes_openssl) \ $(cflags_openssl_3) \ -fPIE -pie -g -static -z relro -z now kpttool_LDFLAGS = $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) kpttool_LDADD = $(OPENSSL_LIB) -lpthread -ldl -lrt @LIBQATNAME@_la_LIBADD = libkpt.la endif mostlyclean-generic: -rm -rf *.obj bin lib tags core .pure .nfs* \ *.old *.bak fluff *.so *.sl *.dll test/*.obj testapp \ test/.dirstamp test/*.o test_bssl/*obj test_bssl/.dirstamp \ test_bssl/*.o qatengine_test rpmbuild kpttool if QAT_ERR_FILES_BUILD MAKE = make err-files && make endif err-files: perl -I$(with_openssl_dir) $(with_openssl_dir)/util/mkerr.pl -conf qat.ec \ -rebuild -reindex `ls *.c` if QAT_FIPS intkat: $(shell ./intkat.sh) endif if QAT_HW depend: OpenSSL qat_hw_driver endif if QAT_SW depend: OpenSSL ipsec_mb crypto_mb endif OpenSSL: cd openssl && ./config -Wl,-rpath,$(with_openssl_install_dir)/lib64 --prefix=$(with_openssl_install_dir) && make clean && make -j$(nproc) && make install -j$(nproc) if QAT_HW qat_hw_driver: bash ./driver_install.sh $(with_qat_hw_dir) if QAT_4XXX if !QAT_HW_INTREE cflags_qat_hw += "-DQAT20_OOT" endif endif endif if QAT_SW ipsec_mb: cd intel-ipsec-mb && make uninstall && make clean && make -j$(nproc) && make install -j$(nproc) crypto_mb: cd cryptography-primitives/sources/ippcp/crypto_mb && rm -rf build && cmake . -B"build" -DOPENSSL_INCLUDE_DIR=$(with_openssl_install_dir)/include -DOPENSSL_LIBRARIES=$(with_openssl_install_dir) -DOPENSSL_ROOT_DIR=$(PWD)/openssl && cd build && make clean && make -j$(nproc) && make install -j$(nproc) endif if QAT_4XXX rpm_oot: mkdir -p rpmbuild/BUILD rpmbuild/RPMS rpmbuild/SOURCES rpmbuild/SPECS rpmbuild/SRPMS cp qatengine-oot.spec rpmbuild/SPECS/ rpmbuild --undefine=_disable_source_fetch --define "_topdir $(abs_srcdir)/rpmbuild" -ba rpmbuild/SPECS/qatengine-oot.spec endif rpm_intree: mkdir -p rpmbuild/BUILD rpmbuild/RPMS rpmbuild/SOURCES rpmbuild/SPECS rpmbuild/SRPMS rpmbuild --undefine=_disable_source_fetch --define "_topdir $(abs_srcdir)/rpmbuild" -ba qatengine.spec include test.am qatengine-1.9.0/README.md000066400000000000000000000130521500416242000147460ustar00rootroot00000000000000# Intel® QuickAssist Technology(QAT) OpenSSL\* Engine Intel® QuickAssist Technology OpenSSL\* Engine (QAT_Engine) supports acceleration through the QAT hardware (via the QAT_HW path) and through Optimized Software using the Intel instruction set (via the QAT_SW Path from 3rd Generation Intel® Xeon® Scalable Processors family). The image below illustrates the high-level software architecture of the QAT_Engine. Applications such as NGINX and HAProxy are common applications which interfaces to crypto libraries like OpenSSL\* and its fork like Tongsuo(BabaSSL)\*, BoringSSL\*, etc. OpenSSL\* is a toolkit for TLS/SSL protocols and has developed a modular system to plugin device-specific engines and provider. Depending on the particular use case, the QAT_Engine can be configured to accelerate via the QAT Hardware or QAT Software or both based on the platform to meet your specific acceleration needs.

drawing

## Features Features of the QAT_Engine are described [here](docs/features.md). ## Limitations and Known Issues Limitations and known issues for the QAT_Engine are described [here](docs/limitations.md). ## Requirements - [Hardware Requirements](docs/hardware_requirements.md) - [Software Requirements](docs/software_requirements.md) ## Installation Instructions Installation instructions are described [here](docs/install.md) ## Testing
Test using OpenSSL Engine command ### Test using OpenSSL\* Engine command Run this command to verify the Intel® QAT OpenSSL\* Engine is loaded correctly: This should not be used to determine QAT Engine capabilities as it will not display all the algorithms that are supported in QAT Engine. ```text cd /path/to/openssl_install/bin ./openssl engine -t -c -v qatengine ``` qat_hw target output will be: ```text (qatengine) Reference implementation of QAT crypto engine(qat_hw) [RSA, DSA, DH, AES-128-CBC-HMAC-SHA1, AES-128-CBC-HMAC-SHA256, AES-256-CBC-HMAC-SHA1, AES-256-CBC-HMAC-SHA256, TLS1-PRF, HKDF, X25519, X448] [ available ] ENABLE_EXTERNAL_POLLING, POLL, SET_INSTANCE_FOR_THREAD, GET_NUM_OP_RETRIES, SET_MAX_RETRY_COUNT, SET_INTERNAL_POLL_INTERVAL, GET_EXTERNAL_POLLING_FD, ENABLE_EVENT_DRIVEN_POLLING_MODE, GET_NUM_CRYPTO_INSTANCES, DISABLE_EVENT_DRIVEN_POLLING_MODE, SET_EPOLL_TIMEOUT, SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD, ENABLE_INLINE_POLLING, ENABLE_HEURISTIC_POLLING, GET_NUM_REQUESTS_IN_FLIGHT, INIT_ENGINE, SET_CONFIGURATION_SECTION_NAME, ENABLE_SW_FALLBACK, HEARTBEAT_POLL, DISABLE_QAT_OFFLOAD ``` qat_sw target output will be: ```text (qatengine) Reference implementation of QAT crypto engine(qat_sw) [RSA, id-aes128-GCM, id-aes192-GCM, id-aes256-GCM, X25519] [ available ] ENABLE_EXTERNAL_POLLING, POLL, ENABLE_HEURISTIC_POLLING, GET_NUM_REQUESTS_IN_FLIGHT, INIT_ENGINE ``` Detailed information about the engine specific messages is available [here](docs/engine_specific_messages.md). Also `./openssl engine -t -c -vvvv qatengine` gives brief description about each ctrl command.
Test using OpenSSL speed utility ### Test using OpenSSL\* speed utility ```text cd /path/to/openssl_install/bin qat_hw * RSA 2K Sign/Verify taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 72 rsa2048 * ECDH Compute Key taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 72 ecdh * ECDSA Sign/Verify taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 72 ecdsa * AES-128-CBC-HMAC-SHA256 taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 72 -evp aes-128-cbc-hmac-sha256 qat_sw * RSA 2K Sign/Verify taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 8 rsa2048 * ECDH X25519 Compute Key taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 8 ecdhx25519 * ECDH P-256 Compute Key taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 8 ecdhp256 * ECDSA P-256 Sign/Verify taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 8 ecdsap256 * ECDH P-384 Sign/Verify taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 8 ecdhp384 * ECDSA P-384 Sign/Verify taskset -c 1 ./openssl speed -engine qatengine -elapsed -async_jobs 8 ecdsap384 * AES-128-GCM taskset -c 1 ./openssl speed -engine qatengine -elapsed -evp aes-128-gcm ``` Note: Run the test without "-engine qatengine" for each algorithm to see the performance against OpenSSL. This only covers key algorithms, additional algorithms can be tested by changing algo parameter.
Test using inbuilt testapp utility ## Test using inbuilt testapp utility ```text cd /path/to/qat_engine make test ./testapp.sh QAT_HW (For testing algorithms supported by QAT_HW) ./testapp.sh QAT_SW (For testing algorithms supported by QAT_SW) ``` The `testapp.sh` script will run the corresponding functional tests supported by QAT_HW and QAT_SW. Please note that the QAT Engine should be built with that support for the tests. Additional information for testapp tests available with the help option `./testapp -help`
## Application integration & Case studies Links to additional content is available [here](docs/apps.md). ## Troubleshooting Troubleshooting information is available [here](docs/troubleshooting.md). ## Licensing Information Licensing information is available [here](docs/licensing.md). ## Legal Legal information is available [here](docs/legal.md). qatengine-1.9.0/SECURITY.md000066400000000000000000000006321500416242000152600ustar00rootroot00000000000000# Security Policy Intel® is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. ## Reporting a Vulnerability Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). qatengine-1.9.0/atomic-ops.h000077500000000000000000001006621500416242000157220ustar00rootroot00000000000000/* generic atomic operations used by progressive locks * * Copyright (C) 2012-2025 Willy Tarreau * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #ifndef PL_ATOMIC_OPS_H #define PL_ATOMIC_OPS_H /* compiler-only memory barrier, for use around locks */ #define pl_barrier() do { \ asm volatile("" ::: "memory"); \ } while (0) #if defined(__i386__) || defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__x86_64__) /* full memory barrier using mfence when SSE2 is supported, falling back to * "lock add %esp" (gcc uses "lock add" or "lock or"). */ #if defined(__SSE2__) #define pl_mb() do { \ asm volatile("mfence" ::: "memory"); \ } while (0) #elif defined(__x86_64__) #define pl_mb() do { \ asm volatile("lock addl $0,0 (%%rsp)" ::: "memory", "cc"); \ } while (0) #else /* ix86 */ #define pl_mb() do { \ asm volatile("lock addl $0,0 (%%esp)" ::: "memory", "cc"); \ } while (0) #endif /* end of pl_mb() case for sse2/x86_64/x86 */ /* * Generic functions common to the x86 family */ #define pl_cpu_relax() do { \ asm volatile("rep;nop\n"); \ } while (0) /* increment integer value pointed to by pointer , and return non-zero if * result is non-null. */ #define pl_inc(ptr) ( \ (sizeof(long) == 8 && sizeof(*(ptr)) == 8) ? ({ \ unsigned char ret; \ asm volatile("lock incq %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 4) ? ({ \ unsigned char ret; \ asm volatile("lock incl %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 2) ? ({ \ unsigned char ret; \ asm volatile("lock incw %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 1) ? ({ \ unsigned char ret; \ asm volatile("lock incb %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_inc__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_inc__(__FILE__,__LINE__); \ 0; \ }) \ ) /* decrement integer value pointed to by pointer , and return non-zero if * result is non-null. */ #define pl_dec(ptr) ( \ (sizeof(long) == 8 && sizeof(*(ptr)) == 8) ? ({ \ unsigned char ret; \ asm volatile("lock decq %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 4) ? ({ \ unsigned char ret; \ asm volatile("lock decl %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 2) ? ({ \ unsigned char ret; \ asm volatile("lock decw %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 1) ? ({ \ unsigned char ret; \ asm volatile("lock decb %0\n" \ "setne %1\n" \ : "+m" (*(ptr)), "=qm" (ret) \ : \ : "cc"); \ ret; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_dec__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_dec__(__FILE__,__LINE__); \ 0; \ }) \ ) /* increment integer value pointed to by pointer , no return */ #define pl_inc_noret(ptr) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock incq %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock incl %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock incw %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock incb %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_inc_noret__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_inc_noret__(__FILE__,__LINE__); \ } \ }) /* decrement integer value pointed to by pointer , no return */ #define pl_dec_noret(ptr) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock decq %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock decl %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock decw %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock decb %0\n" \ : "+m" (*(ptr)) \ : \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_dec_noret__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_dec_noret__(__FILE__,__LINE__); \ } \ }) /* add integer constant to integer value pointed to by pointer , * no return. Size of is not checked. */ #define pl_add(ptr, x) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock addq %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned long)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock addl %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned int)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock addw %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned short)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock addb %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned char)(x)) \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_add__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_add__(__FILE__,__LINE__); \ } \ }) /* subtract integer constant from integer value pointed to by pointer * , no return. Size of is not checked. */ #define pl_sub(ptr, x) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock subq %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned long)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock subl %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned int)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock subw %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned short)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock subb %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned char)(x)) \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_sub__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_sub__(__FILE__,__LINE__); \ } \ }) /* binary and integer value pointed to by pointer with constant , no * return. Size of is not checked. */ #define pl_and(ptr, x) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock andq %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned long)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock andl %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned int)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock andw %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned short)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock andb %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned char)(x)) \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_and__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_and__(__FILE__,__LINE__); \ } \ }) /* binary or integer value pointed to by pointer with constant , no * return. Size of is not checked. */ #define pl_or(ptr, x) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock orq %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned long)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock orl %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned int)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock orw %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned short)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock orb %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned char)(x)) \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_or__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_or__(__FILE__,__LINE__); \ } \ }) /* binary xor integer value pointed to by pointer with constant , no * return. Size of is not checked. */ #define pl_xor(ptr, x) ({ \ if (sizeof(long) == 8 && sizeof(*(ptr)) == 8) { \ asm volatile("lock xorq %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned long)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 4) { \ asm volatile("lock xorl %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned int)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 2) { \ asm volatile("lock xorw %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned short)(x)) \ : "cc"); \ } else if (sizeof(*(ptr)) == 1) { \ asm volatile("lock xorb %1, %0\n" \ : "+m" (*(ptr)) \ : "er" ((unsigned char)(x)) \ : "cc"); \ } else { \ void __unsupported_argument_size_for_pl_xor__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_xor__(__FILE__,__LINE__); \ } \ }) /* test and set bit in integer value pointed to by pointer . Returns * 0 if the bit was not set, or ~0 of the same type as *ptr if it was set. Note * that there is no 8-bit equivalent operation. */ #define pl_bts(ptr, bit) ( \ (sizeof(long) == 8 && sizeof(*(ptr)) == 8) ? ({ \ unsigned long ret; \ asm volatile("lock btsq %2, %0\n\t" \ "sbb %1, %1\n\t" \ : "+m" (*(ptr)), "=r" (ret) \ : "Ir" ((unsigned long)(bit)) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 4) ? ({ \ unsigned int ret; \ asm volatile("lock btsl %2, %0\n\t" \ "sbb %1, %1\n\t" \ : "+m" (*(ptr)), "=r" (ret) \ : "Ir" ((unsigned int)(bit)) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 2) ? ({ \ unsigned short ret; \ asm volatile("lock btsw %2, %0\n\t" \ "sbb %1, %1\n\t" \ : "+m" (*(ptr)), "=r" (ret) \ : "Ir" ((unsigned short)(bit)) \ : "cc"); \ ret; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_bts__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_bts__(__FILE__,__LINE__); \ 0; \ }) \ ) /* Note: for an unclear reason, gcc's __sync_fetch_and_add() implementation * produces less optimal than hand-crafted asm code so let's implement here the * operations we need for the most common archs. */ /* fetch-and-add: fetch integer value pointed to by pointer , add to * to <*ptr> and return the previous value. */ #define pl_xadd(ptr, x) ( \ (sizeof(long) == 8 && sizeof(*(ptr)) == 8) ? ({ \ unsigned long ret = (unsigned long)(x); \ asm volatile("lock xaddq %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 4) ? ({ \ unsigned int ret = (unsigned int)(x); \ asm volatile("lock xaddl %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 2) ? ({ \ unsigned short ret = (unsigned short)(x); \ asm volatile("lock xaddw %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 1) ? ({ \ unsigned char ret = (unsigned char)(x); \ asm volatile("lock xaddb %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_xadd__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_xadd__(__FILE__,__LINE__); \ 0; \ }) \ ) /* exchange value with integer value pointed to by pointer , and return * previous <*ptr> value. must be of the same size as <*ptr>. */ #define pl_xchg(ptr, x) ( \ (sizeof(long) == 8 && sizeof(*(ptr)) == 8) ? ({ \ unsigned long ret = (unsigned long)(x); \ asm volatile("xchgq %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 4) ? ({ \ unsigned int ret = (unsigned int)(x); \ asm volatile("xchgl %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 2) ? ({ \ unsigned short ret = (unsigned short)(x); \ asm volatile("xchgw %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 1) ? ({ \ unsigned char ret = (unsigned char)(x); \ asm volatile("xchgb %0, %1\n" \ : "=r" (ret), "+m" (*(ptr)) \ : "0" (ret) \ : "cc"); \ ret; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_xchg__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_xchg__(__FILE__,__LINE__); \ 0; \ }) \ ) /* compare integer value <*ptr> with and exchange it with if * it matches, and return . and must be of the same size as * <*ptr>. */ #define pl_cmpxchg(ptr, old, new) ( \ (sizeof(long) == 8 && sizeof(*(ptr)) == 8) ? ({ \ unsigned long ret; \ asm volatile("lock cmpxchgq %2,%1" \ : "=a" (ret), "+m" (*(ptr)) \ : "r" ((unsigned long)(new)), \ "0" ((unsigned long)(old)) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 4) ? ({ \ unsigned int ret; \ asm volatile("lock cmpxchgl %2,%1" \ : "=a" (ret), "+m" (*(ptr)) \ : "r" ((unsigned int)(new)), \ "0" ((unsigned int)(old)) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 2) ? ({ \ unsigned short ret; \ asm volatile("lock cmpxchgw %2,%1" \ : "=a" (ret), "+m" (*(ptr)) \ : "r" ((unsigned short)(new)), \ "0" ((unsigned short)(old)) \ : "cc"); \ ret; /* return value */ \ }) : (sizeof(*(ptr)) == 1) ? ({ \ unsigned char ret; \ asm volatile("lock cmpxchgb %2,%1" \ : "=a" (ret), "+m" (*(ptr)) \ : "r" ((unsigned char)(new)), \ "0" ((unsigned char)(old)) \ : "cc"); \ ret; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_cmpxchg__(char *,int); \ if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 && \ sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \ __unsupported_argument_size_for_pl_cmpxchg__(__FILE__,__LINE__); \ 0; \ }) \ ) #else /* generic implementations */ #if defined(__aarch64__) /* This was shown to improve fairness on modern ARMv8 such as Neoverse N1 */ #define pl_cpu_relax() do { \ asm volatile("isb" ::: "memory"); \ } while (0) #else #define pl_cpu_relax() do { \ asm volatile(""); \ } while (0) #endif /* full memory barrier */ #define pl_mb() do { \ __sync_synchronize(); \ } while (0) #define pl_inc_noret(ptr) ({ __sync_add_and_fetch((ptr), 1); }) #define pl_dec_noret(ptr) ({ __sync_sub_and_fetch((ptr), 1); }) #define pl_inc(ptr) ({ __sync_add_and_fetch((ptr), 1); }) #define pl_dec(ptr) ({ __sync_sub_and_fetch((ptr), 1); }) #define pl_add(ptr, x) ({ __sync_add_and_fetch((ptr), (x)); }) #define pl_and(ptr, x) ({ __sync_and_and_fetch((ptr), (x)); }) #define pl_or(ptr, x) ({ __sync_or_and_fetch((ptr), (x)); }) #define pl_xor(ptr, x) ({ __sync_xor_and_fetch((ptr), (x)); }) #define pl_sub(ptr, x) ({ __sync_sub_and_fetch((ptr), (x)); }) #define pl_bts(ptr, bit) ({ typeof(*(ptr)) __pl_t = (1u << (bit)); \ __sync_fetch_and_or((ptr), __pl_t) & __pl_t; \ }) #define pl_xadd(ptr, x) ({ __sync_fetch_and_add((ptr), (x)); }) #define pl_cmpxchg(ptr, o, n) ({ __sync_val_compare_and_swap((ptr), (o), (n)); }) #define pl_xchg(ptr, x) ({ typeof(*(ptr)) __pl_t; \ do { __pl_t = *(ptr); \ } while (!__sync_bool_compare_and_swap((ptr), __pl_t, (x))); \ __pl_t; \ }) #endif #endif /* PL_ATOMIC_OPS_H */qatengine-1.9.0/autogen.sh000077500000000000000000000001401500416242000154620ustar00rootroot00000000000000#!/usr/bin/env bash if [ ! -d "m4" ] then mkdir m4 fi autoreconf -ivf chmod +x configure qatengine-1.9.0/configure.ac000066400000000000000000001103531500416242000157570ustar00rootroot00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) AC_INIT([qatengine], [1.9.0], []) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE([foreign subdir-objects]) AM_SILENT_RULES([yes]) #Libtool for generating shared library LT_INIT AC_PROG_LN_S AC_CONFIG_MACRO_DIR([m4]) # Checks for programs. AC_PROG_CXX AC_PROG_CC # Parameter parsing for enable/disable algo AC_ARG_ENABLE(qat_hw_rsa, AS_HELP_STRING([--disable-qat_hw_rsa], [Disable qat_hw RSA acceleration])) AC_SUBST(enable_qat_hw_rsa) AC_ARG_ENABLE(qat_hw_ecdh, AS_HELP_STRING([--disable-qat_hw_ecdh], [Disable qat_hw ECDH acceleration])) AC_SUBST(enable_qat_hw_ecdh) AC_ARG_ENABLE(qat_hw_ecdsa, AS_HELP_STRING([--disable-qat_hw_ecdsa], [Disable qat_hw ECDSA acceleration])) AC_SUBST(enable_qat_hw_ecdsa) AC_ARG_ENABLE(qat_hw_dsa, AS_HELP_STRING([--disable-qat_hw_dsa], [Disable qat_hw DSA acceleration])) AC_SUBST(enable_qat_hw_dsa) AC_ARG_ENABLE(qat_hw_dh, AS_HELP_STRING([--disable-qat_hw_dh], [Disable qat_hw DH acceleration])) AC_SUBST(enable_qat_hw_dh) AC_ARG_ENABLE(qat_hw_prf, AS_HELP_STRING([--disable-qat_hw_prf], [Disable qat_hw PRF acceleration])) AC_SUBST(enable_qat_hw_prf) AC_ARG_ENABLE(qat_hw_hkdf, AS_HELP_STRING([--enable-qat_hw_hkdf], [Enable qat_hw HKDF acceleration])) AC_SUBST(enable_qat_hw_hkdf) AC_ARG_ENABLE(qat_hw_ecx, AS_HELP_STRING([--disable-qat_hw_ecx], [Disable qat_hw X25519/X448 acceleration])) AC_SUBST(enable_qat_hw_ecx) AC_ARG_ENABLE(qat_hw_ciphers, AS_HELP_STRING([--disable-qat_hw_ciphers], [Disable qat_hw CIPHERS acceleration])) AC_SUBST(enable_qat_hw_ciphers) AC_ARG_ENABLE(qat_hw_gcm, AS_HELP_STRING([--enable-qat_hw_gcm], [Enable qat_hw AES-GCM acceleration (experimental)])) AC_SUBST(enable_qat_hw_gcm) AC_ARG_ENABLE(qat_hw_sha3, AS_HELP_STRING([--enable-qat_hw_sha3], [Enable qat_hw SHA3 offload])) AC_SUBST(enable_qat_hw_sha3) AC_ARG_ENABLE(qat_hw_chachapoly, AS_HELP_STRING([--enable-qat_hw_chachapoly], [Enable qat_hw CHACHA-POLY acceleration])) AC_SUBST(enable_qat_hw_chachapoly) AC_ARG_ENABLE(qat_hw_sm4_cbc, AS_HELP_STRING([--enable-qat_hw_sm4_cbc], [Enable qat_hw SM4-CBC acceleration])) AC_SUBST(enable_qat_hw_sm4_cbc) AC_ARG_ENABLE(qat_hw_sm2, AS_HELP_STRING([--enable-qat_hw_sm2], [Enable qat_hw SM2 acceleration])) AC_SUBST(enable_qat_hw_sm2) AC_ARG_ENABLE(qat_hw_sm3, AS_HELP_STRING([--enable-qat_hw_sm3], [Enable qat_hw SM3 acceleration])) AC_SUBST(enable_qat_hw_sm3) AC_ARG_ENABLE(qat_hw_ccm, AS_HELP_STRING([--disable-qat_hw_ccm], [Disable qat_hw AES-CCM acceleration])) AC_SUBST(enable_qat_hw_ccm) AC_ARG_ENABLE(qat_sw_gcm, AS_HELP_STRING([--disable-qat_sw_gcm], [Disable qat_sw AES-GCM acceleration])) AC_SUBST(enable_qat_sw_gcm) AC_ARG_ENABLE(qat_sw_sha2, AS_HELP_STRING([--disable-qat_sw_sha2], [Disable qat_sw SHA2 acceleration])) AC_SUBST(enable_qat_sw_sha2) AC_ARG_ENABLE(qat_sw_rsa, AS_HELP_STRING([--disable-qat_sw_rsa], [Disable qat_sw RSA acceleration])) AC_SUBST(enable_qat_sw_rsa) AC_ARG_ENABLE(qat_sw_ecx, AS_HELP_STRING([--disable-qat_sw_ecx], [Disable qat_sw X25519 acceleration])) AC_SUBST(enable_qat_sw_ecx) AC_ARG_ENABLE(qat_sw_ecdsa, AS_HELP_STRING([--disable-qat_sw_ecdsa], [Disable qat_sw ECDSA acceleration])) AC_SUBST(enable_qat_sw_ecdsa) AC_ARG_ENABLE(qat_sw_ecdh, AS_HELP_STRING([--disable-qat_sw_ecdh], [Disable qat_sw ECDH acceleration])) AC_SUBST(enable_qat_sw_ecdh) AC_ARG_ENABLE(qat_sw_sm2, AS_HELP_STRING([--disable-qat_sw_sm2], [Disable qat_sw SM2 acceleration])) AC_SUBST(enable_qat_sw_sm2) AC_ARG_ENABLE(qat_sw_sm3, AS_HELP_STRING([--enable-qat_sw_sm3], [Enable qat_sw SM3 acceleration])) AC_SUBST(enable_qat_sw_sm3) AC_ARG_ENABLE(qat_sw_sm4_gcm, AS_HELP_STRING([--enable-qat_sw_sm4_gcm], [Enable qat_sw SM4 GCM acceleration])) AC_SUBST(enable_qat_sw_sm4_gcm) AC_ARG_ENABLE(qat_sw_sm4_ccm, AS_HELP_STRING([--enable-qat_sw_sm4_ccm], [Enable qat_sw SM4 CCM acceleration])) AC_SUBST(enable_qat_sw_sm4_ccm) AC_ARG_ENABLE(qat_sw_sm4_cbc, AS_HELP_STRING([--enable-qat_sw_sm4_cbc], [Enable qat_sw SM4-CBC acceleration])) AC_SUBST(enable_qat_sw_sm4_cbc) AC_ARG_ENABLE(qat_small_pkt_offload, AS_HELP_STRING([--enable-qat_small_pkt_offload], [Enable small packet CIPHER acceleration])) AC_SUBST(enable_qat_small_pkt_offload) AC_ARG_ENABLE(qat_hw, AS_HELP_STRING([--disable-qat_hw], [Disable Intel(R) QAT Hardware acceleration])) AC_SUBST(enable_qat_hw) AC_ARG_ENABLE(qat_sw, AS_HELP_STRING([--enable-qat_sw], [Enable qat_sw acceleration using Intel(R) Crypto Multi-buffer library])) AC_SUBST(enable_qat_sw) AC_ARG_ENABLE(qat_provider, AS_HELP_STRING([--enable-qat_provider], [Enable Provider Support for Openssl 3.x.x])) AC_SUBST(enable_qat_provider) # Parameter parsing for self tuning of the timeout in the qat_sw polling thread AC_ARG_ENABLE(qat_sw_heuristic_timeout, AS_HELP_STRING([--enable-qat_sw_heuristic_timeout], [Enable self tuning of the timeout in the qat_sw polling thread])) AC_SUBST(enable_qat_sw_heuristic_timeout) AC_ARG_ENABLE(qat_cycle_counts, AS_HELP_STRING([--enable-qat_cycle_counts], [Enable CPU Cycle Counts])) AC_SUBST(enable_qat_cycle_counts) # Parameter parsing for enable debug/warnings AC_ARG_ENABLE(qat_debug, AS_HELP_STRING([--enable-qat_debug], [Enable Engine Debug Messages])) AC_SUBST(enable_qat_debug) AC_ARG_ENABLE(qat_warnings, AS_HELP_STRING([--enable-qat_warnings], [Enable Engine Warning Messages])) AC_SUBST(enable_qat_warnings) AC_ARG_ENABLE(qat_mem_debug, AS_HELP_STRING([--enable-qat_mem_debug], [Enable Memory Driver Debug Messages])) AC_SUBST(enable_qat_mem_debug) AC_ARG_ENABLE(qat_mem_warnings, AS_HELP_STRING([--enable-qat_mem_warnings], [Enable Memory Driver Warning Messages])) AC_SUBST(enable_qat_mem_warnings) # Mandatory QAT driver source path if building against QAT_HW Version 1.7 driver source package AC_ARG_WITH(qat_hw_dir, AS_HELP_STRING([--with-qat_hw_dir], [Path to the Intel Quickassist Technology Driver source code]), [qat_hw_dir_prefix="$withval"], [qat_hw_dir_prefix="/usr"]) AC_SUBST(with_qat_hw_dir) # Other non mandatory parameters AC_ARG_WITH(openssl_install_dir, AS_HELP_STRING([--with-openssl_install_dir], [Path to where the OpenSSL libraries are installed to. The Engine will be installed to the lib/engines subdirectory of this path. If you are using BoringSSL, please use the source code dir, because BoringSSL cannot be installed.])) AC_SUBST(with_openssl_install_dir) AC_ARG_WITH(openssl_dir, AS_HELP_STRING([--with-openssl_dir], [Path to the OpenSSL source code. The error files will get regenerated using the mkerr.pl script included with the OpenSSL source])) AC_SUBST(with_openssl_dir) AC_ARG_WITH(qat_hw_install_dir, AS_HELP_STRING([--with-qat_hw_install_dir], [Path to the Intel Quickassist Technology Driver build output])) AC_SUBST(with_qat_hw_install_dir) AC_ARG_WITH(qat_sw_crypto_mb_install_dir, AS_HELP_STRING([--with-qat_sw_crypto_mb_install_dir], [Path to the Multi-buffer based Intel(R) Crypto Multi-buffer library install location])) AC_SUBST(with_qat_sw_crypto_mb_install_dir) AC_ARG_WITH(qat_sw_ipsec_mb_install_dir, AS_HELP_STRING([--with-qat_sw_ipsec_mb_install_dir], [Path to the Intel(R) Multi-Buffer Crypto for IPsec library install location])) AC_SUBST(with_qat_sw_ipsec_mb_install_dir) AC_ARG_WITH(qat_debug_file, AS_HELP_STRING([--with-qat_debug_file], [Path and filename to log debug output to. Combine with other flags that enable the debug and warning output])) AC_SUBST(with_qat_debug_file) AC_ARG_WITH(qat_engine_id, AS_HELP_STRING([--with-qat_engine_id], [This should be specified to force the Engine to use engine id other than default "qatengine"])) AC_SUBST(with_qat_engine_id) AC_ARG_WITH(cc_opt, AS_HELP_STRING([--with-cc_opt], [Sets additional parameters that will be added to the CFLAGS])) AC_SUBST(with_cc_opt) AC_ARG_WITH(ld_opt, AS_HELP_STRING([--with-ld_opt], [Sets additional parameters that will be used during linking])) AC_SUBST(with_ld_opt) AC_ARG_ENABLE(qat_hw_lenstra_protection, AS_HELP_STRING([--disable-qat_hw_lenstra_protection], [Disable protection against Lenstra attack])) AC_SUBST(enable_qat_hw_lenstra_protection) AC_ARG_ENABLE(qat_hw_lenstra_verify_hw, AS_HELP_STRING([--enable-qat_hw_lenstra_verify_hw], [Enable Lenstra Verify using QAT_HW instead of OpenSSL SW])) AC_SUBST(enable_qat_hw_lenstra_verify_hw) AC_ARG_ENABLE(qat_auto_engine_init_on_fork, AS_HELP_STRING([--disable-qat_auto_engine_init_on_fork], [Disable auto initialization of the engine following a fork])) AC_SUBST(enable_qat_auto_engine_init_on_fork) AC_ARG_ENABLE(qat_plock, AS_HELP_STRING([--enable-qat_plock], [Enable plock, an optimized read-write lock which replaces pthread read/write lock])) AC_SUBST(enable_qat_plock) AC_ARG_ENABLE(qat_fips, AS_HELP_STRING([--enable-qat_fips], [Enables FIPS support])) AC_SUBST(enable_qat_fips) AC_ARG_ENABLE(qat_ntls, AS_HELP_STRING([--enable-qat_ntls], [Enable ntls in engine for handing NTLS requests])) AC_SUBST(enable_qat_ntls) AC_ARG_ENABLE(qat_insecure_algorithms, AS_HELP_STRING([--enable-qat_insecure_algorithms], [Enable insecure algorithms (DSA, DH, SHA1, SHA3-224, EC <256 & RSA<2048, AES-128-GCM, AES-128-CCM, AES-192-GCM & AES-128-CBC-HMAC-SHA256])) AC_SUBST(enable_qat_insecure_algorithms) AC_ARG_ENABLE(qat_hw_kpt, AS_HELP_STRING([--enable-qat_hw_kpt], [Enable QAT HW Key Protection technology(KPT) support])) AC_SUBST(enable_qat_hw_kpt) #Default library name is qatengine AC_SUBST([LIBQATNAME], "qatengine") AC_CHECK_FILE(${qat_hw_dir_prefix}/include/qat/icp_sal_versions.h, [with_icp_sal_versions_h=yes], [with_icp_sal_versions_h=no]) if test "x$with_icp_sal_versions_h" = "xyes" -a "x$enable_qat_hw" != "xno" then if grep "define SAL_INFO2_DRIVER_SW_VERSION_TYPE \"in-tree\"" ${qat_hw_dir_prefix}/include/qat/icp_sal_versions.h then AC_SUBST([cflags_qat_hw_intree], ["-DQAT_HW_INTREE"]) AC_SUBST([with_qat_hw_dir], ["${qat_hw_dir_prefix}"]) AC_MSG_NOTICE([QAT in-tree driver using QATlib in ${with_qat_hw_dir}]) else if grep "define SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER 3" ${qat_hw_dir_prefix}/include/qat/icp_sal_versions.h then AC_SUBST([cflags_qat_hw_intree], ["-DQAT_HW_FBSD_OOT"]) AC_SUBST([with_qat_hw_dir], ["${qat_hw_dir_prefix}"]) AC_MSG_NOTICE([QAT FBSD OOT driver using libs from ${with_qat_hw_dir}]) else AC_SUBST([cflags_qat_hw_intree], ["-DQAT_HW_FBSD_INTREE"]) AC_SUBST([with_qat_hw_dir], ["${qat_hw_dir_prefix}"]) AC_MSG_NOTICE([QAT in-tree driver using FBSD QATlib in ${with_qat_hw_dir}]) fi fi fi AM_CONDITIONAL([QAT_HW_INTREE], [test "x$cflags_qat_hw_intree" != "x"]) # ERROR message if mandatory options are not provided if test "x$cflags_qat_hw_intree" = "x" then if test "x$with_qat_hw_dir" = "x" -a "x$enable_qat_sw" = "x" then AC_MSG_ERROR([qatlib library not installed or --with-qat_hw_dir or --enable-qat_sw not set, If you like to use QAT Hardware acceleration, set it to the path to the Intel Quickassist Technology Driver source code. e.g: --with-qat_hw_dir=/path/to/qat_driver or If you like to use QAT Software acceleration using Intel crypto multibuffer library and Intel IPSec (AES-GCM), provide --enable-qat_sw after installing crypto_mb and IPSec_mb libraries as per README]) fi fi #OpenSSL 3.x.x uses lib location based on ARCH AS_IF([test "$host_cpu" = "x86_64"], [AC_SUBST([openssl3_lib], "lib64")], [AC_SUBST([openssl3_lib], "lib")]) # OpenSSL/BabaSSL/BoringSSL install dir or set system default if not provided if test "x$with_openssl_install_dir" != "x" then #BoringSSL from Source if test -f $with_openssl_install_dir/include/openssl/base.h then if grep "define BORINGSSL_API_VERSION" $with_openssl_install_dir/include/openssl/base.h then AC_MSG_NOTICE([Build QAT Engine against BoringSSL]) AC_SUBST([cflags_boringssl], ["-DQAT_BORINGSSL"]) AC_CHECK_FILE(${with_openssl_install_dir}/lib/libcrypto.so, [AC_SUBST([QAT_BORINGSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/lib -L\$(with_openssl_install_dir)/lib -ldecrepit -lcrypto -lssl"])], [AC_MSG_ERROR([BoringSSL libraries not found in the path $(with_openssl_install_dir)/lib !])]) AS_IF([test -d "$with_openssl_install_dir/crypto"], [AC_SUBST([cflags_boringssl], ["-DQAT_BORINGSSL -DBSSL_SOURCE -DOPENSSL_NO_ERR"])]) AC_SUBST([with_openssl_dir], [""]) #Err files are updated manually for BoringSSL AC_SUBST([LIBQATNAME], "libqatengine") fi elif grep "define OPENSSL_SHLIB_VERSION 81.3" $with_openssl_install_dir/include/openssl/opensslv.h #Build with QuicTLS 3.x libraries then if test "x$enable_qat_provider" = "xyes" then AC_MSG_NOTICE([Build QAT Provider against QuicTLS 3.x]) libdir="\$(with_openssl_install_dir)/\$(openssl3_lib)/ossl-modules" AC_SUBST([cflags_openssl_3], ["-DQAT_OPENSSL_3 -DOPENSSL_SUPPRESS_DEPRECATED -DQAT_OPENSSL_PROVIDER"]) AC_SUBST([OPENSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/\$(openssl3_lib) -L\$(with_openssl_install_dir)/\$(openssl3_lib) -lcrypto"]) AC_SUBST([LIBQATNAME], "qatprovider") else AC_MSG_NOTICE([Build QAT Engine against QuicTLS 3.x]) libdir="\$(with_openssl_install_dir)/\$(openssl3_lib)/engines-81.3" AC_SUBST([cflags_openssl_3], ["-DQAT_OPENSSL_3 -DOPENSSL_SUPPRESS_DEPRECATED"]) AC_SUBST([OPENSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/\$(openssl3_lib) -L\$(with_openssl_install_dir)/\$(openssl3_lib) -lcrypto"]) fi else ac_default_prefix=$with_openssl_install_dir if grep "define OPENSSL_VERSION_NUMBER 0x1010" $with_openssl_install_dir/include/openssl/opensslv.h then #OPENSSL 1.1.1 AC_MSG_ERROR([OpenSSL 1.1.1 is not supported]) else #OPENSSL 3.x.x if test "x$enable_qat_provider" = "xyes" then AC_MSG_NOTICE([Build QAT Provider against OpenSSL 3.x.x]) libdir="\$(with_openssl_install_dir)/\$(openssl3_lib)/ossl-modules" AC_SUBST([cflags_openssl_3], ["-DQAT_OPENSSL_3 -DOPENSSL_SUPPRESS_DEPRECATED -DQAT_OPENSSL_PROVIDER"]) AC_SUBST([OPENSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/\$(openssl3_lib) -L\$(with_openssl_install_dir)/\$(openssl3_lib) -lcrypto"]) AC_SUBST([LIBQATNAME], "qatprovider") else AC_MSG_NOTICE([Build QAT Engine against OpenSSL 3.x.x]) libdir="\$(with_openssl_install_dir)/\$(openssl3_lib)/engines-3" AC_SUBST([cflags_openssl_3], ["-DQAT_OPENSSL_3 -DOPENSSL_SUPPRESS_DEPRECATED"]) AC_SUBST([OPENSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/\$(openssl3_lib) -L\$(with_openssl_install_dir)/\$(openssl3_lib) -lcrypto"]) fi fi fi AC_SUBST([includes_openssl], ["-I\$(with_openssl_install_dir)/include"]) else # Default OPENSSL from the system AC_PATH_TOOL(PKGCONFIG, pkg-config) AS_IF([test "x$PKGCONFIG" = "x"], [AC_MSG_ERROR(pkg-config not found.)], ) libdir="`pkg-config --variable=enginesdir libcrypto`" includes_openssl="`pkg-config --variable=includedir libcrypto`" if grep "define OPENSSL_VERSION_NUMBER 0x1010" $includes_openssl/openssl/opensslv.h then AC_MSG_ERROR([OpenSSL 1.1.1 is not supported]) else if test "x$enable_qat_provider" = "xyes" then AC_MSG_NOTICE([Build QAT Provider against system OpenSSL 3.x.x]) AC_SUBST([cflags_openssl_3], ["-DQAT_OPENSSL_3 -DOPENSSL_SUPPRESS_DEPRECATED -DQAT_OPENSSL_PROVIDER"]) AC_SUBST([LIBQATNAME], "qatprovider") openssl3_lib="`pkg-config --variable=libdir libcrypto`" libdir="\$(openssl3_lib)/ossl-modules" else AC_MSG_NOTICE([Build QAT Engine against system OpenSSL 3.x.x]) AC_SUBST([cflags_openssl_3], ["-DQAT_OPENSSL_3 -DOPENSSL_SUPPRESS_DEPRECATED"]) libdir="`pkg-config --variable=enginesdir libcrypto`" fi fi AC_MSG_NOTICE([Install engine/provider in the system OpenSSL Path]) AC_SUBST([includes_openssl], ["-I`pkg-config --variable=includedir libcrypto`"]) AC_SUBST([OPENSSL_LIB], ["-lcrypto"]) AC_SUBST([libdir]) fi AM_CONDITIONAL([QAT_OPENSSL_3], [test "x$cflags_openssl_3" != "x"]) AM_CONDITIONAL([QAT_PROVIDER], [test "x$enable_qat_provider" = "xyes"]) AM_CONDITIONAL([QAT_BORINGSSL], [test "x$cflags_boringssl" != "x"]) AM_CONDITIONAL([ENABLE_QAT_HW_KPT], [test "x$enable_qat_hw_kpt" = "xyes"]) # qat_hw_dir configured, enable qat_hw if test "x$with_qat_hw_dir" != "x" then if test "x$enable_qat_hw" != "xno" then AC_SUBST([cflags_qat_hw], ["-DQAT_HW"]) AC_CHECK_FILE(${with_qat_hw_dir}/quickassist/lookaside/access_layer/src/common/crypto/kpt/crypto/lac_kpt_crypto_qat_comms.c, [cflags_qat_hw="${cflags_qat_hw} -DQAT20_OOT"], []) AC_MSG_NOTICE([QAT_HW acceleration enabled]) else AC_MSG_NOTICE([QAT_HW acceleration disabled]) fi fi AM_CONDITIONAL([QAT_HW], [test "x$cflags_qat_hw" != "x"]) case "$host_os" in linux*) AS_IF([test `lspci -vnd 8086: | grep -c -E '4940|4942|4944|4946'` != "0"], [AC_SUBST([enable_qat20_oot], ["-DQAT20_OOT"])]) esac AM_CONDITIONAL([QAT_4XXX], [test "x$enable_qat20_oot" != "x"]) # QAT_SW acceleration enabled if test "x$enable_qat_sw" = "xyes" then #Crypto_mb install path provided if test "x$with_qat_sw_crypto_mb_install_dir" != "x" then AC_MSG_NOTICE([QAT_SW enabled for PKE with crypto_mb from user provided path]) AC_SUBST([cflags_qat_sw], ["-DQAT_SW"]) AC_SUBST([includes_qat_sw_crypto_mb], ["-I\${with_qat_sw_crypto_mb_install_dir}/include"]) AC_CHECK_FILE(${with_qat_sw_crypto_mb_install_dir}/lib/libcrypto_mb.so, [AC_SUBST([QAT_SW_CRYPTO_MB_LIB], ["-Wl,-rpath,${with_qat_sw_crypto_mb_install_dir}/lib -L\${with_qat_sw_crypto_mb_install_dir}/lib -lcrypto_mb"])], [AC_MSG_ERROR([$with_qat_sw_crypto_mb_install_dir/lib/libcrypto_mb.so not found. Install it and try again.])]) else AC_SUBST([cflags_qat_sw], ["-DQAT_SW"]) AC_SUBST([includes_qat_sw_crypto_mb], ["-I/usr/local/include -I/usr/include"]) AC_CHECK_FILE(/usr/local/lib/libcrypto_mb.so, [AC_SUBST([QAT_SW_CRYPTO_MB_LIB], ["-Wl,-rpath,/usr/local/lib -L/usr/local/lib -lcrypto_mb"])], [AC_SUBST([QAT_SW_CRYPTO_MB_LIB], ["-lcrypto_mb"])]) fi #IPSEC_MB install path provided if test "x$with_qat_sw_ipsec_mb_install_dir" != "x" then AC_MSG_NOTICE([QAT_SW for AES-GCM enabled with IPsec_mb library from the path provided]) AC_SUBST([cflags_qat_sw_ipsec], ["-DQAT_SW_IPSEC"]) AC_SUBST([includes_qat_sw_ipsec_mb], ["-I\${with_qat_sw_ipsec_mb_install_dir}/include"]) AC_CHECK_FILE(${with_qat_sw_ipsec_mb_install_dir}/lib/libIPSec_MB.so, [AC_SUBST([QAT_SW_IPSEC_MB_LIB], ["-Wl,-rpath,${with_qat_sw_ipsec_mb_install_dir}/lib -L\${with_qat_sw_ipsec_mb_install_dir}/lib -lIPSec_MB"])], [AC_MSG_ERROR([$with_qat_sw_ipsec_mb_install_dir/lib/libIPSec_MB.so not found. Install it and try again.])]) else AC_SUBST([cflags_qat_sw_ipsec], ["-DQAT_SW_IPSEC"]) AC_SUBST([includes_qat_sw_ipsec_mb], ["-I/usr/include"]) AC_SUBST([QAT_SW_IPSEC_MB_LIB], ["-lIPSec_MB"]) fi fi AM_CONDITIONAL([QAT_SW], [test "x$cflags_qat_sw" != "x"]) AM_CONDITIONAL([QAT_SW_IPSEC], [test "x$cflags_qat_sw_ipsec" != "x"]) # OpenSSL source dir to regenerate err files if any changes in err messages if test "x$with_openssl_dir" = "x" then if test "x$cflags_boringssl" != "x" then AC_MSG_NOTICE([Build with existing error files for BoringSSL]) else AC_MSG_NOTICE([Build with existing error files without regenerating from OpenSSL source]) fi fi AM_CONDITIONAL([QAT_ERR_FILES_BUILD], [test "x$with_openssl_dir" != "x"]) # Disable unsupported algorithms with BoringSSl enabled if test "x$cflags_boringssl" != "x" then if test "x$cflags_qat_hw" != "x" then AC_SUBST([enable_qat_hw_ciphers], ["no"]) AC_SUBST([enable_qat_hw_sm4_cbc], ["no"]) AC_SUBST([enable_qat_hw_ecdh], ["no"]) AC_SUBST([enable_qat_hw_dsa], ["no"]) AC_SUBST([enable_qat_hw_dh], ["no"]) AC_SUBST([enable_qat_hw_prf], ["no"]) AC_SUBST([enable_qat_hw_hkdf], ["no"]) AC_SUBST([enable_qat_hw_ecx], ["no"]) AC_SUBST([enable_qat_hw_gcm], ["no"]) AC_SUBST([enable_qat_hw_sm2], ["no"]) AC_SUBST([enable_qat_hw_ccm], ["no"]) fi if test "x$cflags_qat_sw" != "x" then AC_SUBST([enable_qat_sw_ciphers], ["no"]) AC_SUBST([enable_qat_sw_ecdh], ["no"]) AC_SUBST([enable_qat_sw_ecx], ["no"]) AC_SUBST([enable_qat_sw_gcm], ["no"]) AC_SUBST([enable_qat_sw_sm2], ["no"]) AC_SUBST([enable_qat_sw_sm4_cbc], ["no"]) AC_SUBST([enable_qat_sw_heuristic_timeout], ["no"]) AC_SUBST([enable_qat_sw_sha2], ["no"]) fi fi if test "x$enable_qat_hw_kpt" = "xyes" -a "x$cflags_qat_hw" != "x" then AC_SUBST([includes_kpt_lib], ["-Ikpt/lib"]) fi # Compiler security flags AC_SUBST([cflags_common], ["-Wall -Wformat -Wformat-security -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong"]) # Disable insecure algorithms by default if test "x$enable_qat_insecure_algorithms" = "xyes" then AC_MSG_NOTICE([Insecure Algorithms enabled]) cflags_common="${cflags_common} -DQAT_INSECURE_ALGO" else AC_MSG_NOTICE([Insecure Algorithms disabled]) AC_SUBST([enable_qat_hw_dsa], ["no"]) AC_SUBST([enable_qat_hw_dh], ["no"]) fi AM_CONDITIONAL([QAT_INSECURE_ALGO], [test "enable_qat_insecure_algorithms" = "xyes"]) # Enable QAT_HW Algorithms based on enable/disable Flags if test "x$cflags_qat_hw" != "x" then AS_IF([test "x$enable_qat_hw_rsa" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_RSA"; AC_MSG_NOTICE([Accelerating RSA to Hardware])]) AS_IF([test "x$enable_qat_hw_ecdsa" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_ECDSA"; AC_MSG_NOTICE([Accelerating ECDSA to Hardware])]) AS_IF([test "x$enable_qat_hw_ecdh" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_ECDH"; AC_MSG_NOTICE([Accelerating ECDH to Hardware])]) AS_IF([test "x$enable_qat_hw_ecx" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_ECX"; AC_MSG_NOTICE([Accelerating X25519/X448 to Hardware])]) AS_IF([test "x$enable_qat_hw_dsa" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_DSA"; AC_MSG_NOTICE([Accelerating DSA to Hardware])]) AS_IF([test "x$enable_qat_hw_dh" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_DH"; AC_MSG_NOTICE([Accelerating DH to Hardware])]) AS_IF([test "x$enable_qat_hw_prf" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_PRF"; AC_MSG_NOTICE([Accelerating PRF to Hardware])]) AS_IF([test "x$enable_qat_hw_hkdf" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_HKDF"; AC_MSG_NOTICE([Accelerating HKDF to Hardware])]) AS_IF([test "x$enable_qat_hw_sha3" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_SHA3"; AC_MSG_NOTICE([Accelerating SHA3 to Hardware])]) AS_IF([test "x$enable_qat_hw_sm3" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_SM3"; AC_MSG_NOTICE([Accelerating SM3 to Hardware])]) AS_IF([test "x$enable_qat_hw_ciphers" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_CIPHERS"; AC_MSG_NOTICE([Accelerating CIPHERS to Hardware])]) AS_IF([test "x$enable_qat_hw_gcm" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_GCM"; AC_MSG_NOTICE([Accelerating GCM to Hardware (experimental)])]) AS_IF([test "x$enable_qat_hw_chachapoly" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_CHACHAPOLY"; AC_MSG_NOTICE([Accelerating CHACHA-POLY to Hardware])]) AS_IF([test "x$enable_qat_hw_sm4_cbc" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_SM4_CBC"; AC_MSG_NOTICE([Accelerating SM4-CBC to Hardware])]) AS_IF([test "x$enable_qat_hw_sm2" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_SM2"; AC_MSG_NOTICE([Accelerating SM2 to Hardware])]) AS_IF([test "x$enable_qat_hw_ccm" != "xno"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_CCM"; AC_MSG_NOTICE([Accelerating AES-CCM to Hardware])]) AS_IF([test "x$enable_qat_hw_kpt" = "xyes"], [cflags_qat_hw="${cflags_qat_hw} -DENABLE_QAT_HW_KPT"; AC_MSG_NOTICE([QAT_HW KPT Support enabled])]) fi # Enable QAT_SW Algorithms based on enable/disable Flags if test "x$cflags_qat_sw" != "x" then AS_IF([test "x$enable_qat_sw_rsa" != "xno"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_RSA"; AC_MSG_NOTICE([Accelerating RSA to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_ecdsa" != "xno"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_ECDSA"; AC_MSG_NOTICE([Accelerating ECDSA to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_ecdh" != "xno"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_ECDH"; AC_MSG_NOTICE([Accelerating ECDH to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_ecx" != "xno"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_ECX"; AC_MSG_NOTICE([Accelerating X25519/X448 to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_sm2" != "xno"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_SM2"; AC_MSG_NOTICE([Accelerating SM2 to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_sm3" = "xyes"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_SM3"; AC_MSG_NOTICE([Accelerating SM3 to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_sm4_cbc" = "xyes"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_SM4_CBC"; AC_MSG_NOTICE([Accelerating SM4-CBC to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_sm4_gcm" = "xyes"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_SM4_GCM"; AC_MSG_NOTICE([Accelerating SM4-GCM to Software (Multi-buffer)])]) AS_IF([test "x$enable_qat_sw_sm4_ccm" = "xyes"], [cflags_qat_sw="${cflags_qat_sw} -DENABLE_QAT_SW_SM4_CCM"; AC_MSG_NOTICE([Accelerating SM4-CCM to Software (Multi-buffer)])]) fi if test "x$cflags_qat_sw_ipsec" != "x" then AS_IF([test "x$enable_qat_sw_gcm" != "xno"], [cflags_qat_sw_ipsec="${cflags_qat_sw_ipsec} -DENABLE_QAT_SW_GCM"; AC_MSG_NOTICE([Accelerating GCM to Software (IPSec_mb)])]) AS_IF([test "x$enable_qat_sw_sha2" != "xno"], [cflags_qat_sw_ipsec="${cflags_qat_sw_ipsec} -DENABLE_QAT_SW_SHA2"; AC_MSG_NOTICE([Accelerating SHA2 to Software (IPSec_mb)])]) fi if test "x$cflags_qat_hw" != "x" -a "x$cflags_qat_sw" != "x" then AC_MSG_NOTICE([QAT_HW & QAT_SW Co-existence]) if test "x$enable_qat_hw_sm3" != "x" -a "x$enable_qat_sw_sm3" != "x" then AC_MSG_ERROR(Co-existence not supported by SM3) fi fi #System OpenSSL if test "x$with_openssl_install_dir" = "x" then AC_CHECK_LIB([crypto],[EVP_sm3],[with_sm3_support_h=yes],[with_sm3_support_h=no]) if test "x$with_sm3_support_h" = "xno" then AC_SUBST([cflags_qat_hw], ["${cflags_qat_hw} -DOPENSSL_NO_SM2_SM3"]) AC_MSG_NOTICE([SM3 support not available in system OpenSSL]) fi fi #Enable additional QAT_HW & QAT_SW flags AS_IF([test "x$enable_qat_debug" = "xyes"], [cflags_common="${cflags_common} -DQAT_DEBUG"; AC_MSG_NOTICE([Debug messages enabled])]) AS_IF([test "x$enable_qat_warnings" = "xyes"], [cflags_common="${cflags_common} -DQAT_WARN"; AC_MSG_NOTICE([Warning messages enabled])]) AS_IF([test "x$enable_qat_mem_debug" = "xyes"], [cflags_common="${cflags_common} -DQAT_MEM_DEBUG"; AC_MSG_NOTICE([Memory driver debug messages enabled])]) AS_IF([test "x$enable_qat_mem_warnings" = "xyes"], [cflags_common="${cflags_common} -DQAT_MEM_WARN"; AC_MSG_NOTICE([Memory driver warning messages enabled])]) AS_IF([test "x$enable_qat_cycle_counts" = "xyes"], [cflags_common="${cflags_common} -DQAT_CPU_CYCLES_COUNT"; AC_MSG_NOTICE([CPU Cycle Counts enabled])]) AS_IF([test "x$enable_qat_auto_engine_init_on_fork" = "xno"], [cflags_common="${cflags_common} -DDISABLE_QAT_AUTO_ENGINE_INIT_ON_FORK" ; AC_MSG_NOTICE([Auto engine init on fork disabled])]) AS_IF([test "x$enable_qat_small_pkt_offload" = "xyes"], [cflags_common="${cflags_common} -DENABLE_QAT_SMALL_PKT_OFFLOAD"; AC_MSG_NOTICE([Accelerating symmetric small packets enabled])]) AS_IF([test "x$enable_qat_plock" = "xyes"], [cflags_common="${cflags_common} -DQAT_PLOCK"; AC_MSG_NOTICE([plock enabled])]) AM_CONDITIONAL([QAT_PLOCK], [test "x$enable_qat_plock" != "x"]) AS_IF([test "x$enable_qat_fips" = "xyes"], [cflags_common="${cflags_common} -DENABLE_QAT_FIPS"; AC_MSG_NOTICE([FIPS Support enabled])]) AM_CONDITIONAL([QAT_FIPS], [test "x$enable_qat_fips" != "x"]) AS_IF([test "x$enable_qat_sw_heuristic_timeout" = "xyes" -a "x$cflags_qat_sw" != "x"], [cflags_common="${cflags_common} -DQAT_SW_HEURISTIC_TIMEOUT"; AC_MSG_NOTICE([QAT_SW Heuristic Timeout enabled])]) AS_IF([test "x$with_qat_engine_id" != "x"], [cflags_common="${cflags_common} -DQAT_ENGINE_ID=\$(with_qat_engine_id)"; AC_MSG_NOTICE([Using engine id other than default])]) AS_IF([test "x$enable_qat_ntls" = "xyes"], [cflags_common="${cflags_common} -DQAT_NTLS"; AC_MSG_NOTICE([Enabling NTLS for Engine])]) # Enable Additional QAT_HW Flags if test "x$cflags_qat_hw" != "x" then AS_IF([test "x$enable_qat_hw_lenstra_protection" = "xno"], [cflags_common="${cflags_common} -DDISABLE_QAT_HW_LENSTRA_PROTECTION"; AC_MSG_NOTICE([Lenstra attack protection disabled])]) AS_IF([test "x$enable_qat_hw_lenstra_verify_hw" = "xyes" -a "x$enable_qat_hw_lenstra_protection" != "xno"], [cflags_common="${cflags_common} -DENABLE_QAT_HW_LENSTRA_VERIFY_HW"; AC_MSG_NOTICE([Lenstra check via QAT_HW enabled])]) AS_IF([test "x$enable_qat_hw_set_inst_thread" = "xyes"], [cflags_common="${cflags_common} -DQAT_HW_SET_INSTANCE_THREAD"; AC_MSG_NOTICE([QAT_HW set instance for thread enabled])]) fi # Additional cflags if any to be passed if test "x$with_cc_opt" != "x" then AC_SUBST([cflags_cc_opt], ["\$(with_cc_opt)"]) fi # Additional LD_flags if any to be passed if test "x$with_ld_opt" != "x" then AC_SUBST([QAT_LD_LIB], ["\$(with_ld_opt)"]) fi # Write logs to a debug file if test "x$with_qat_debug_file" != "x" then AC_SUBST([cflags_qat_debug], ["-DQAT_DEBUG_FILE_PATH=\$(with_qat_debug_file)"]) AC_MSG_NOTICE([Debugs to file enabled]) fi #glibc detection for AVX512 memcpy optimization (not related to QAT_SW AVX512) case "$host_os" in linux*) AC_CHECK_PROG(USE_LDD, ldd, yes, no) AC_CHECK_PROG(USE_HEAD, head, yes, no) if test $USE_LDD == "yes" -a $USE_HEAD then if test "`ldd --version | head -1 | awk '{print ($4>=2.23)?"1":"0"}' 2>/dev/null`" = "1" then AC_MSG_NOTICE([glibc version >= 2.23. glibc AVX-512 memcpy optimisation supported.]) else AC_MSG_NOTICE([glibc version < 2.23. glibc AVX-512 memcpy optimisation not supported.]) fi if test "`ldd --version | head -1 | awk '{print ($4<2.17)?"1":"0"}' 2>/dev/null`" = "1" then AC_ARG_WITH(LIBS, AS_HELP_STRING(), , LIBS+="-lrt") AC_SUBST(LIBS) fi else AC_MSG_NOTICE([glibc version could not be auto detected. Check manually using 'ldd --version']) AC_MSG_NOTICE([glibc AVX-512 memcpy optimisation supported only from glibc version 2.23]) AC_ARG_WITH(LIBS, AS_HELP_STRING(), , LIBS+="-lrt") AC_SUBST(LIBS) fi ;; *) esac # Driver headers include path if test "x$cflags_qat_hw" != "x" then if test "x$cflags_qat_hw_intree" != "x" then AC_SUBST([includes_qat_hw], ["-I\${with_qat_hw_dir}/include/qat"]) else AC_SUBST([with_ICP_API_DIR], ["\$(with_qat_hw_dir)/quickassist/include"]) AC_SUBST([with_ICP_SAL_API_DIR], ["\$(with_qat_hw_dir)/quickassist/lookaside/access_layer/include"]) AC_SUBST([with_ICP_LAC_API_DIR], ["\$(with_ICP_API_DIR)/lac"]) AC_SUBST([with_ICP_DC_DIR], ["\$(with_qat_hw_dir)/quickassist/include/dc"]) AC_SUBST([with_USDM_DIR], ["\$(with_qat_hw_dir)/quickassist/utilities/libusdm_drv"]) AC_SUBST([includes_qat_hw], ["-I\$(with_ICP_API_DIR) -I\$(with_ICP_LAC_API_DIR) -I\$(with_ICP_SAL_API_DIR) -I\$(with_ICP_DC_DIR) -I\$(with_USDM_DIR)"]) fi fi # qatlib Intree uses different library name if test "x$cflags_qat_hw_intree" != "x" then case "$host_os" in freebsd*) AC_SUBST([DRIVER], ["qat_s"]) AC_SUBST([USDM], ["usdm_drv_s"]) ;; *) AC_SUBST([DRIVER], ["qat"]) AC_SUBST([USDM], ["usdm"]) ;; esac else AC_SUBST([DRIVER], ["qat_s"]) AC_SUBST([USDM], ["usdm_drv_s"]) fi if test "x$cflags_qat_hw" != "x" then if test "x$cflags_qat_hw_intree" != "x" then AC_SUBST([QAT_HW_DRIVER_LIB], ["-L\$(with_qat_hw_dir)/lib -l\$(DRIVER) -l\$(USDM)"]) else if test "x$with_qat_hw_install_dir" = "x" then with_qat_hw_install_dir="\$(with_qat_hw_dir)/build" fi AC_SUBST([QAT_HW_DRIVER_LIB], ["-Wl,-rpath,\$(with_qat_hw_install_dir) -L\$(with_qat_hw_install_dir) -l\$(DRIVER) -l\$(USDM)"]) fi fi echo "===============================================================================" echo "Enabled Algorithms and Additional Flags" echo "===============================================================================" echo "QAT_HW ALGORITHMS :" [$cflags_qat_hw] echo "QAT_SW ALGORITHMS :" [$cflags_qat_sw] echo "ADDITIONAL FLAGS :" [$cflags_common $cflags_openssl_3 $cflags_boringssl] if test "x$cflags_qat_hw" != "x" then if test "x$cflags_qat_hw_intree" = "x" then AC_CHECK_FILE(${with_qat_hw_dir}/build/libqat_s.so, [], [echo "QAT_HW Driver library not found in $with_qat_hw_dir/build. Install it & try again or proceed with 'make depend' target to install dependencies"]) fi fi if test "x$cflags_qat_sw" != "x" then if test "x$with_qat_sw_crypto_mb_install_dir" = "x" then AC_CHECK_LIB(crypto_mb, mbx_getversion) AC_CHECK_FILE(/usr/local/lib/libcrypto_mb.so) if test "x$ac_cv_file__usr_local_lib_libcrypto_mb_so" != "xyes" -a "x$ac_cv_lib_crypto_mb_mbx_getversion" != "xyes" then echo "libcrypto_mb.so not found in /usr/local/lib or in system default. Install it & try again or proceed with 'make depend' target to install dependencies" # Setting it for make depend target AC_SUBST([QAT_SW_CRYPTO_MB_LIB], ["-Wl,-rpath,/usr/local/lib -L/usr/local/lib -lcrypto_mb"]) fi fi if test "x$with_qat_sw_ipsec_mb_install_dir" = "x" then AC_CHECK_LIB(IPSec_MB, imb_get_version, [], [echo "libIPsec_MB.so not found in default path. Install it & try again or proceed with 'make depend' target to install dependencies"]) fi fi echo "===============================================================================" # Output files from the configure AC_CONFIG_FILES([Makefile]) AC_OUTPUT qatengine-1.9.0/debian/000077500000000000000000000000001500416242000147105ustar00rootroot00000000000000qatengine-1.9.0/debian/changelog000066400000000000000000000005141500416242000165620ustar00rootroot00000000000000qatengine (1.9.0-1) unstable; urgency=medium * Sync with upstream release 1.9.0 -- Colin Ian King Tue, 29 Apr 2025 15:31:22 +0100 qatengine (1.8.1-1) unstable; urgency=medium * Initial release v1.8.1 (Closes: #1078744) -- Colin Ian King Mon, 27 Jan 2025 09:55:27 +0000 qatengine-1.9.0/debian/control000066400000000000000000000016441500416242000163200ustar00rootroot00000000000000Source: qatengine Section: utils Priority: optional Maintainer: Colin Ian King Rules-Requires-Root: no Build-Depends: debhelper-compat (= 13), pkgconf, libssl-dev, libqat-dev, libusdm-dev, libipsec-mb-dev, libcrypto-mb-dev, Standards-Version: 4.7.2 Homepage: https://github.com/intel/QAT_Engine Vcs-Browser: https://salsa.debian.org/ColinKing/qatengine Vcs-Git: https://salsa.debian.org/ColinKing/qatengine.git Package: qatengine Architecture: amd64 Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends}, Recommends: qatlib-service, Description: IntelĀ® QuickAssist Technology OpenSSL* Engine The QAT_Engine offers two separate internal entities by which acceleration can be performed. It supports the ability to accelerate from the stand OpenSSL* to basic Intel instruction set, to either Hardware acceleration path (via the qat_hw path) or via the optimized SW path (qat_sw lib). qatengine-1.9.0/debian/copyright000066400000000000000000000235131500416242000166470ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Source: https://github.com/intel/QAT_Engine/tree/master Upstream-Name: QAT_Engine Upstream-Contact: Yogaraj Alamenda Files: * Copyright: 2023 Intel License: BSD-3-clause Files: qat_hw_config/* Copyright: 2023 Intel License: GPL-2 Files: debian/* Copyright: 2024, Hector Cao 2025-2025, Colin Ian King License: GPL-2 Files: qat.txt qat_err.h qat_err.c qat_bssl_err.h qat_bssl_err.c Copyright: 1995-2024 The OpenSSL Project License: Apache-2.0 Files: qat_constant_time.h qat_hw_ciphers.c Copyright: 2016-2024 Intel Corporation 2014-2016 The OpenSSL Project Authors License: BSD-3-clause or OpenSSL BSD LICENSE . Copyright(c) 2016-2024 Intel Corporation. All rights reserved. . Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. . Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. . Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at https://www.openssl.org/source/license.html Files: qat_hw_config/200xx/multi_process/200xx_dev0.conf qat_hw_config/200xx/multi_thread/200xx_dev0.conf qat_hw_config/4xxx/multi_process/4xxx_dev0.conf qat_hw_config/4xxx/multi_thread/4xxx_dev0.conf qat_hw_config/c3xxx/multi_process/c3xxx_dev0.conf qat_hw_config/c3xxx/multi_thread/c3xxx_dev0.conf qat_hw_config/c4xxx/multi_process/c4xxx_dev0.conf qat_hw_config/c4xxx/multi_thread/c4xxx_dev0.conf qat_hw_config/c6xx/multi_process/c6xx_dev0.conf qat_hw_config/c6xx/multi_thread/c6xx_dev0.conf qat_hw_config/dh895xcc/multi_process/dh895xcc_dev0.conf qat_hw_config/dh895xcc/multi_thread/dh895xcc_dev0.conf Copyright: 2007-2024 Intel Corporation License: BSD-3-clause or GPL-2 GPL LICENSE SUMMARY . Copyright(c) 2007-2024 Intel Corporation. All rights reserved. . This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . The full GNU General Public License is included in this distribution in the file called LICENSE.GPL. . Contact Information: Intel Corporation . BSD LICENSE . Copyright(c) 2007-2024 Intel Corporation. All rights reserved. . Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Files: LICENSE.PLOCK atomic-ops.h plock.c plock.h Copyright: 2012-2025 Willy Tarreau License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Files: qatengine.spec Copyright: 2023 Intel License: MIT License: GPL-2 On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL-2' License: Apache-2.0 On Debian systems, the complete text of the Apache-2.0 License can be found in `/usr/share/common-licenses/Apache-2.0'. License: BSD-3-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. . * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: MIT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, distribute with modifications, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. . Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization. qatengine-1.9.0/debian/lrc.config000066400000000000000000000017351500416242000166650ustar00rootroot00000000000000# # lrc complains that the spec file is BSD-3-clause and/or # Expat qatengine.spec however this is a false positive on # the spec file RPM License: line # qatengine.spec # # lintian complains about using and/or verbs in debian/copyright for the # following files and lrc complains about using just the and verb. Silence # the and/or warning for these. # qat_constant_time.h qat_hw_ciphers.c qat_hw_config/200xx/multi_process/200xx_dev0.conf qat_hw_config/200xx/multi_thread/200xx_dev0.conf qat_hw_config/4xxx/multi_process/4xxx_dev0.conf qat_hw_config/4xxx/multi_thread/4xxx_dev0.conf qat_hw_config/c3xxx/multi_process/c3xxx_dev0.conf qat_hw_config/c3xxx/multi_thread/c3xxx_dev0.conf qat_hw_config/c4xxx/multi_process/c4xxx_dev0.conf qat_hw_config/c4xxx/multi_thread/c4xxx_dev0.conf qat_hw_config/c6xx/multi_process/c6xx_dev0.conf qat_hw_config/c6xx/multi_thread/c6xx_dev0.conf qat_hw_config/dh895xcc/multi_process/dh895xcc_dev0.conf qat_hw_config/dh895xcc/multi_thread/dh895xcc_dev0.conf qatengine-1.9.0/debian/patches/000077500000000000000000000000001500416242000163375ustar00rootroot00000000000000qatengine-1.9.0/debian/patches/0001-remove-qatengine-spec.patch000066400000000000000000000165461500416242000241500ustar00rootroot00000000000000From: Colin Ian King Date: Tue, 19 Nov 2024 17:08:11 +0000 Subject: [PATCH] Remove RPM spec files Spec files are not needed for debian packaging, remove them. ----- Index: qatengine/qatengine-oot.spec =================================================================== --- qatengine.orig/qatengine-oot.spec +++ /dev/null @@ -1,183 +0,0 @@ -%undefine __cmake_in_source_build -%undefine _disable_source_fetch -%global _lto_cflags %{nil} -%global debug_package %{nil} -# Dependent Library Versions -%global major 2 -%global minor 0 -%global rev 0 -%global ipsec intel-ipsec-mb -%global ipsecver %{major}.%{minor} -%global ipsecfull %{ipsec}-%{ipsecver} -%global fullversion %{major}.%{minor}.%{rev} - -%global ippcp_major 12 -%global ippcp_minor 1 -%global ippcp cryptography-primitives -%global ippcpver 1.1.0 -%global ippcpfull %{ippcp}-%{ippcpver} -%global ippcpfullversion %{ippcp_major}.%{ippcp_minor} - -%global openssl openssl-3.0.16 -%global qatdriver QAT20.L.1.2.30-00078 - -%global openssl_source %{_builddir}/%{openssl} -%global openssl_install %{buildroot}/%{_prefix}/local/ssl - -Name: QAT_Engine -Version: 1.9.0 -Release: 1%{?dist} -Summary: Intel QuickAssist Technology(QAT) OpenSSL Engine -License: BSD-3-Clause AND OpenSSL - -Source0: https://github.com/intel/QAT_Engine/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Source1: https://github.com/openssl/openssl/releases/download/%{openssl}/%{openssl}.tar.gz#/%{openssl}.tar.gz -Source2: https://downloadmirror.intel.com/843052/%{qatdriver}.tar.gz#/%{qatdriver}.tar.gz -%if !0%{?suse_version} -Source3: https://github.com/intel/ipp-crypto/archive/refs/tags/v%{ippcpver}.tar.gz#/%{ippcp}-%{ippcpver}.tar.gz -Source4: https://github.com/intel/intel-ipsec-mb/archive/refs/tags/v%{ipsecver}.tar.gz#/%{ipsecfull}.tar.gz -%endif - -%description -This package provides the Intel QuickAssist Technology OpenSSL Engine -(an OpenSSL Plug-In Engine) which provides cryptographic acceleration -for both hardware and optimized software using Intel QuickAssist Technology -enabled Intel platforms. - -%prep -%setup -b 0 -%setup -b 1 -%if !0%{?suse_version} -%setup -b 3 -%setup -b 4 -%endif -# Setup Source2 driver package manually -mkdir -p %{_builddir}/%{qatdriver} -tar -zxvf %{_sourcedir}/%{qatdriver}.tar.gz -C %{_builddir}/%{qatdriver} -cp -rf %{_builddir}/%{name}-%{version}/fips/driver_install.sh %{_builddir} - -%build -cd %{_builddir}/%{openssl} -./config --prefix=%{_builddir}/openssl_install -%make_build -make install -mkdir -p %{buildroot}/%{_prefix}/local/ssl/lib64 -mkdir -p %{buildroot}/%{_prefix}/local/ssl/bin -mkdir -p %{buildroot}/%{_prefix}/local/ssl/include -mkdir -p %{buildroot}/%{_prefix}/local/lib -mkdir -p %{buildroot}/%{_prefix}/lib -cp -rf %{_builddir}/openssl_install/lib64/libcrypto.so.3 %{buildroot}/%{_prefix}/local/ssl/lib64 -cp -rf %{_builddir}/openssl_install/lib64/libssl.so.3 %{buildroot}/%{_prefix}/local/ssl/lib64 -cp -rf %{_builddir}/openssl_install/bin %{buildroot}/%{_prefix}/local/ssl/ -cp -rf %{_builddir}/openssl_install/include %{buildroot}/%{_prefix}/local/ssl/ -cd %{buildroot}/%{_prefix}/local/ssl/lib64 -ln -sf libcrypto.so.3 libcrypto.so -ln -sf libssl.so.3 libssl.so - -cd %{_builddir}/%{qatdriver} -unset ICP_ROOT -unset ICP_BUILD_OUTPUT -./configure -%make_build - -%if !0%{?suse_version} -cd %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb -cmake . -B"build" -DOPENSSL_INCLUDE_DIR=%{openssl_install}/include -DOPENSSL_LIBRARIES=%{openssl_install} -DOPENSSL_ROOT_DIR=%{openssl_source} -cd build -%make_build - -install -d %{buildroot}/%{_includedir}/crypto_mb -cp -rf %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb/include/crypto_mb/*.h /%{buildroot}/%{_includedir}/crypto_mb/ -install -d %{buildroot}/%{_libdir} -cp %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb/build/bin/libcrypto_mb.so.%{ippcpfullversion} %{buildroot}/%{_libdir} -cd %{buildroot}/%{_libdir} - -ln -sf libcrypto_mb.so.%{ippcpfullversion} libcrypto_mb.so.%{ippcp_major} -ln -sf libcrypto_mb.so.%{ippcpfullversion} libcrypto_mb.so - -cp -rf %{buildroot}/%{_libdir}/libcrypto_mb.so.%{ippcpfullversion} %{buildroot}/%{_prefix}/local/lib -cp -rf %{buildroot}/%{_libdir}/libcrypto_mb.so.%{ippcp_major} %{buildroot}/%{_prefix}/local/lib -cp -rf %{buildroot}/%{_libdir} libcrypto_mb.so %{buildroot}/%{_prefix}/local/lib - -cd %{_builddir}/%{ipsecfull} -cd lib -%make_build - -install -d %{buildroot}/%{_includedir} -install -m 0644 %{_builddir}/%{ipsecfull}/lib/intel-ipsec-mb.h %{buildroot}/%{_includedir} -cp %{buildroot}/%{_includedir}/intel-ipsec-mb.h /usr/include/ -install -s -m 0755 %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{fullversion} %{buildroot}/%{_libdir} -cp -rf %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{fullversion} %{buildroot}/%{_prefix}/lib -cp -rf %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so %{buildroot}/%{_prefix}/lib -cp -rf %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{major} %{buildroot}/%{_prefix}/lib - -cd %{buildroot}/%{_libdir} -ln -sf libIPSec_MB.so.%{fullversion} libIPSec_MB.so.%{major} -ln -sf libIPSec_MB.so.%{fullversion} libIPSec_MB.so -%endif - -cd %{_builddir}/%{name}-%{version} -autoreconf -ivf - -%if !0%{?suse_version} -# Enable QAT_HW & QAT_SW Co-existence acceleration -./configure --with-openssl_install_dir=%{openssl_install} --with-qat_hw_dir=%{_builddir}/%{qatdriver} --enable-qat_sw --with-qat_sw_crypto_mb_install_dir=%{buildroot}/%{_prefix}/local --with-qat_sw_ipsec_mb_install_dir=%{buildroot}/%{_prefix} -%else -# Enable QAT_HW acceleration for SUSE -./configure --with-openssl_install_dir=%{openssl_install} --with-qat_hw_dir=%{_builddir}/%{qatdriver} -%endif -%make_build - -install -d %{buildroot}/%{_prefix}/local/ssl/lib64/engines-3 -cp -rf %{_builddir}/%{name}-%{version}/.libs/qatengine.so %{buildroot}/%{_prefix}/local/ssl/lib64/engines-3 - -install -d %{buildroot}/%{_libdir}/build -cp -rf %{_builddir}/%{name}-%{version}/qat_hw_config/4xxx/multi_process/4xxx_dev0.conf %{buildroot}/%{_libdir}/build -cp -rf %{_builddir}/%{qatdriver}/build/libusdm_drv_s.so %{buildroot}/%{_libdir} -cp -rf %{_builddir}/%{qatdriver}/build/libqat_s.so %{buildroot}/%{_libdir} -cp -rf %{_builddir}/%{qatdriver}/build %{buildroot}/%{_libdir} -cp %{_builddir}/%{name}-%{version}/fips/driver_install.sh %{buildroot}/%{_libdir} - -%post - echo "RPM is getting installed" -if (lspci | grep Co- >/dev/null ) -then - ./%{_libdir}/driver_install.sh -fi - -%clean -rm -rf %{buildroot} - -%files -%exclude %{_prefix}/local/lib/lib64 -%{_prefix}/local/ssl/lib64/engines-3/qatengine.so -%{_prefix}/local/ssl/lib64 -%{_prefix}/local/ssl/bin -%{_prefix}/local/ssl/include -%{_libdir}/libqat_s.so -%{_libdir}/libusdm_drv_s.so -%{_libdir}/build -%{_libdir}/driver_install.sh -%license LICENSE* -%doc README.md docs* - -%if !0%{?suse_version} -%{_libdir}/libcrypto_mb.so.%{ippcpfullversion} -%{_libdir}/libcrypto_mb.so.%{ippcp_major} -%{_libdir}/libcrypto_mb.so - -%{_libdir}/libIPSec_MB.so.%{fullversion} -%{_libdir}/libIPSec_MB.so.%{major} -%{_libdir}/libIPSec_MB.so - -%{_prefix}/lib/libIPSec_MB.so.%{fullversion} -%{_prefix}/lib/libIPSec_MB.so.%{major} -%{_prefix}/lib/libIPSec_MB.so - -%{_prefix}/local/lib/libcrypto_mb.so.%{ippcpfullversion} -%{_prefix}/local/lib/libcrypto_mb.so.%{ippcp_major} -%{_prefix}/local/lib/libcrypto_mb.so - -%{_includedir}/crypto_mb -%{_includedir}/intel-ipsec-mb.h -%endif qatengine-1.9.0/debian/patches/series000066400000000000000000000000411500416242000175470ustar00rootroot000000000000000001-remove-qatengine-spec.patch qatengine-1.9.0/debian/rules000077500000000000000000000011421500416242000157660ustar00rootroot00000000000000#!/usr/bin/make -f export DPKG_EXPORT_BUILDFLAGS = 1 export DEB_BUILD_MAINT_OPTIONS=hardening=+all %: dh $@ # enable QAT SW # will need 2 extra dependencies: libipsec-mb-dev, ipp-crypto-dev override_dh_auto_configure: dh_auto_configure -- --enable-qat_sw override_dh_auto_install: dh_auto_install rm -f debian/qatengine/usr/lib/*/engines-3/qatengine.la # does not compress testapp override_dh_compress: dh_compress -Xtestapp # does not remove executable bit on testapp and testapp.sh # those files are installed in usr/share/doc/qatengine (see install) override_dh_fixperms: dh_fixperms -Xtestapp qatengine-1.9.0/debian/source/000077500000000000000000000000001500416242000162105ustar00rootroot00000000000000qatengine-1.9.0/debian/source/format000066400000000000000000000000141500416242000174160ustar00rootroot000000000000003.0 (quilt) qatengine-1.9.0/debian/tests/000077500000000000000000000000001500416242000160525ustar00rootroot00000000000000qatengine-1.9.0/debian/tests/control000066400000000000000000000001071500416242000174530ustar00rootroot00000000000000Tests: openssl-engine Restrictions: allow-stderr Depends: openssl, @ qatengine-1.9.0/debian/tests/openssl-engine000066400000000000000000000011121500416242000207160ustar00rootroot00000000000000#!/bin/sh # autopkgtest check: Check if the QAT engine is available for openssl # (C) 2024 Canonical Ltd. # Author: Hector Cao set -e # run openssl benchmark with qatengine and verify that the engine QAT is enabled # NB: in absence of QAT hardware, QAT engine will use software acceleration # NB : output the stderr & stdout to file and check for QAT engine usage openssl speed -seconds 1 -elapsed -engine qatengine -elapsed rsa2048 > $AUTOPKGTEST_ARTIFACTS/openssl_output.txt 2>&1 grep "Engine \"qatengine\" set" $AUTOPKGTEST_ARTIFACTS/openssl_output.txt qatengine-1.9.0/debian/upstream/000077500000000000000000000000001500416242000165505ustar00rootroot00000000000000qatengine-1.9.0/debian/upstream/metadata000066400000000000000000000006271500416242000202600ustar00rootroot00000000000000# https://wiki.debian.org/UpstreamMetadata Bug-Database: https://github.com/intel/QAT_Engine/issues Changelog: https://github.com/intel/QAT_Engine/releases Documentation: https://github.com/intel/QAT_Engine/blob/master/README.md Repository: https://github.com/intel/QAT_Engine/ Repository-Browse: https://github.com/intel/QAT_Engine/commits/master/ Security-Contact: Colin Ian King qatengine-1.9.0/debian/watch000066400000000000000000000003211500416242000157350ustar00rootroot00000000000000version=4 opts="filenamemangle=s%(?:.*?)v(\d[\d.][\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \ https://github.com/intel/QAT_engine/tags \ (?:.*?/)?v(\d[\d.][\d.]*)\.tar\.gz debian uupdate qatengine-1.9.0/dockerfiles/000077500000000000000000000000001500416242000157605ustar00rootroot00000000000000qatengine-1.9.0/dockerfiles/README.md000066400000000000000000000076031500416242000172450ustar00rootroot00000000000000# IntelĀ® QuickAssist Technology(QAT) OpenSSL\* Engine Container support Supports below Dockerfiles which can be built into docker images on the platforms with [IntelĀ® QuickAssist 4xxx Series](https://www.intel.com/content/www/us/en/products/details/processors/xeon/scalable.html) QAT device. * [QAT crypto base](#qat-crypto-base) * [HAproxy with QAT crypto base](#haproxy-with-qat-crypto-base) ## QAT crypto base This Dockerfile(qat_crypto_base/Dockerfile) with qatengine is built on top of latest OpenSSL, QAT_HW(qatlib intree driver) and QAT_SW with software versions mentioned in [software_requirements](../docs/software_requirements.md) section. This contains QAT_HW and QAT_SW co-existence build and works as defined in [co-existence section](../docs/qat_coex.md#qat_hw-and-qat_sw-co-existence) ## Haproxy with QAT crypto base This Dockerfile(haproxy/Dockerfile) is built with Haproxy release version v2.8.0 along with QAT crypto base mentioned above. Sample Haproxy configuration file is located at `haproxy/haproxy.cfg` which can be modified as per the required use case and to be mounted from the host to the container using `-v /usr/local/etc/haproxy/haproxy.cfg`. ## Docker setup and testing Refer [here](https://intel.github.io/quickassist/AppNotes/Containers/setup.html) for setting up the host for QAT_HW (qatlib intree) if the platform has QAT 4xxx Hardware device. Stop QAT service if any running on the host. ### QAT_HW settings Follow the below steps to enable required service. The service can be asym only, sym only or both in step 2 depending on the particular use case. Configure the required service only to get best performance. 1. Bring down the QAT devices ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo down > /sys/bus/pci/devices/$i/qat/state;done ``` 2. Set up the required crypto service(s) ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo ā€œsym;asymā€œ > /sys/bus/pci/devices/$i/qat/cfg_services;done ``` 3. Bring up the QAT devices ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo up> /sys/bus/pci/devices/$i/qat/state;done ``` 4. Check the status of the QAT devices ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do cat /sys/bus/pci/devices/$i/qat/state;done ``` 5. Enable VF for the PF in the host ``` for i in `lspci -D -d :4940| awk '{print $1}'`; do echo 16|sudo tee /sys/bus/pci/devices/$i/sriov_numvfs; done ``` 6. Add QAT group and Permission to the VF devices in the host ``` chown root:qat /dev/vfio/* chmod 660 /dev/vfio/* ``` ### Image creation Docker images can be built using the below command with appropriate image name. ``` docker build --build-arg GID=$(getent group qat | cut -d ':' -f 3) -t --no-cache ``` Note: GID is the group id of qat group in the host. ### Testing QAT Crypto base using OpenSSL\* speed utility ``` docker run -it --cap-add=IPC_LOCK --security-opt seccomp=unconfined --security-opt apparmor=unconfined $(for i in `ls /dev/vfio/*`; do echo --device $i; done) --cpuset-cpus <2-n+1> --env QAT_POLICY=1 --ulimit memlock=524288000:524288000 < docker_image_name> openssl speed -engine qatengine -elapsed -async_jobs 72 -multi ``` ### Testing Haproxy ``` Server command: docker run --rm -it --cpuset-cpus <2-n+1> --cap-add=IPC_LOCK --security-opt seccomp=unconfined --security-opt apparmor=unconfined $(for i in `ls /dev/vfio/*`; do echo --device $i; done) --env QAT_POLICY=1 --ulimit memlock=524288000:524288000 -v /usr/local/etc/haproxy/:/usr/local/etc/haproxy/ -d -p 8080:8080 < docker_image_name> haproxy -f /usr/local/etc/haproxy/haproxy.cfg Client command: openssl s_time -connect :8080 -cipher AES128-SHA256 -www /20b-file.html -time 5 ``` Note: n is number of process or thread. 8080 port to be used for starting the haproxy service. HAproxy config file mounted from the host to the container using -v /usr/local/etc/haproxy/haproxy.cfg. qatengine-1.9.0/dockerfiles/haproxy/000077500000000000000000000000001500416242000174525ustar00rootroot00000000000000qatengine-1.9.0/dockerfiles/haproxy/Dockerfile000066400000000000000000000157521500416242000214560ustar00rootroot00000000000000#========================================================================== # \ # \ # BSD LICENSE \ # \ # Copyright(c) 2024-2025 Intel Corporation. \ # All rights reserved. \ # \ # Redistribution and use in source and binary forms, with or without \ # modification, are permitted provided that the following conditions \ # are met: \ # \ # * Redistributions of source code must retain the above copyright \ # notice, this list of conditions and the following disclaimer. \ # * Redistributions in binary form must reproduce the above copyright \ # notice, this list of conditions and the following disclaimer in \ # the documentation and/or other materials provided with the \ # distribution. \ # * Neither the name of Intel Corporation nor the names of its \ # contributors may be used to endorse or promote products derived \ # from this software without specific prior written permission. \ # \ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR \ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY \ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ # \ # \ #========================================================================== ARG UBUNTU_BASE=ubuntu:22.04 FROM ${UBUNTU_BASE} AS builder ARG OPENSSL_VERSION="openssl-3.0.16" ARG QATLIB_VERSION="24.02.0" ARG QAT_ENGINE_VERSION="v1.9.0" ARG IPSEC_MB_VERSION="v2.0" ARG IPP_CRYPTO_VERSION="v1.1.0" ARG HAPROXY_VERSION="v2.8.0" ARG GID ENV DEBIAN_FRONTEND=noninteractive # Install required packages including curl, telnet, and git RUN apt-get update && \ apt-get install -y apt-utils \ software-properties-common && \ add-apt-repository ppa:ubuntu-toolchain-r/test -y && \ apt-get update # Upgrade all other packages RUN apt-get upgrade -y && \ apt-get install -y \ libudev-dev \ make \ gcc-13 \ g++-13 \ nasm \ pkg-config \ libssl-dev \ libpcre3-dev \ zlib1g-dev \ libreadline-dev \ lua5.4 \ liblua5.4-dev \ git \ nasm \ autoconf \ automake \ cmake \ ca-certificates \ libtool \ texinfo \ bison \ python3 \ wget && \ git clone --depth 1 -b $OPENSSL_VERSION https://github.com/openssl/openssl.git && \ git clone --depth 1 -b $QAT_ENGINE_VERSION https://github.com/intel/QAT_Engine && \ git clone --depth 1 -b $IPP_CRYPTO_VERSION https://github.com/intel/cryptography-primitives && \ git clone --depth 1 -b $IPSEC_MB_VERSION https://github.com/intel/intel-ipsec-mb && \ git clone --depth 1 -b $QATLIB_VERSION https://github.com/intel/qatlib && \ git clone --depth 1 -b $HAPROXY_VERSION https://github.com/haproxy/haproxy # Add the GCC 13 alternative to the update-alternatives filesystem RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 10 --slave /usr/bin/g++ g++ /usr/bin/g++-13 # Install binutils 2.40 RUN wget https://sourceware.org/pub/binutils/releases/binutils-2.40.tar.gz && \ tar -zxvf binutils-2.40.tar.gz WORKDIR /binutils-2.40 RUN ./configure && \ make -j && \ make install -j # Create a non-root user and group RUN groupadd -r appuser && useradd -r -g appuser -s /bin/bash appuser # Building OpenSSL WORKDIR /openssl RUN ./config && \ make -j && \ make install -j # Building QATLIB WORKDIR /qatlib RUN ./autogen.sh && \ ./configure --enable-systemd=no && \ make -j && \ make install samples-install && \ groupadd qat -g ${GID} && \ usermod -a -G qat appuser # Building Crypto_MB WORKDIR /cryptography-primitives/sources/ippcp/crypto_mb RUN cmake . -B"../build" \ -DOPENSSL_INCLUDE_DIR=/usr/local/include \ -DOPENSSL_LIBRARIES=/usr/local/lib64 \ -DOPENSSL_ROOT_DIR=/openssl WORKDIR /cryptography-primitives/sources/ippcp/build RUN make crypto_mb -j && make install -j # Building Ipsec_MB WORKDIR /intel-ipsec-mb RUN make -j && make install LIB_INSTALL_DIR=/usr/local/lib # Building QAT Engine WORKDIR /QAT_Engine RUN ./autogen.sh && \ ./configure \ --with-openssl_install_dir=/usr/local/ \ --with-qat-hw-dir=/usr/local/ \ --enable-qat_sw && \ make && make install # Install HAProxy with Lua support WORKDIR /haproxy RUN make -j SSL_INC=/usr/local/include/ SSL_LIB=/usr/local/lib64/ USE_OPENSSL=1 USE_ENGINE=1 TARGET=linux-glibc USE_PTHREAD_EMULATION=1 && \ make install # Copy the HAProxy configuration file RUN mkdir -p /usr/local/etc/haproxy COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg #Added to remove libc library for vulnerability issue RUN apt-get purge -y linux-libc-dev FROM ${UBUNTU_BASE} RUN apt-get update && \ apt-get upgrade -y COPY --from=builder /usr/local/lib/libqat.so.4.2.0 /usr/lib/ COPY --from=builder /usr/local/lib/libusdm.so.0.1.0 /usr/lib/ COPY --from=builder /usr/local/lib/libIPSec_MB.so.2.0.0 /usr/lib/x86_64-linux-gnu/ COPY --from=builder /usr/local/lib64/libcrypto.so.3 /usr/lib/x86_64-linux-gnu/ COPY --from=builder /usr/local/lib/intel64/libcrypto_mb.so.12.1 /usr/lib/x86_64-linux-gnu/ COPY --from=builder /usr/local/bin/openssl /usr/bin/ COPY --from=builder /usr/local/lib64/engines-3/qatengine.so /usr/lib/x86_64-linux-gnu/engines-3/qatengine.so COPY --from=builder /etc/group /etc/group COPY --from=builder /etc/passwd /etc/passwd COPY --from=builder /usr/local/sbin/haproxy /usr/local/sbin/haproxy COPY --from=builder /usr/local/etc/haproxy/ /usr/local/etc/haproxy/ RUN ldconfig #Expose the 8080 port EXPOSE 8080 # Switch to non-root user USER appuser ENV OPENSSL_ENGINES="/usr/lib/x86_64-linux-gnu/engines-3/" ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/" ENV QAT_POLICY=1 qatengine-1.9.0/dockerfiles/haproxy/haproxy.cfg000066400000000000000000000013561500416242000216320ustar00rootroot00000000000000global insecure-fork-wanted nbthread 16 cpu-map 1/all 1-16 tune.bufsize 32768 ssl-engine qatengine algo ALL ssl-mode-async tune.ssl.cachesize 0 stats socket /tmp/sock1 mode 666 level admin #thread 1/1 ssl-default-bind-ciphers ALL #ssl-default-bind-curves tune.ssl.default-dh-param 2048 defaults timeout client 10s timeout server 10s timeout connect 1s backlog 10000 mode http listen test mode http option httpclose #tcp-request session reject bind :8080 ssl force-tlsv12 crt /opt/atf/environments/server/install/haproxy-qat/haproxy_install/conf/haproxy.certs/server-rsa2k.cert.pem # monitor-uri / qatengine-1.9.0/dockerfiles/qat_crypto_base/000077500000000000000000000000001500416242000211375ustar00rootroot00000000000000qatengine-1.9.0/dockerfiles/qat_crypto_base/Dockerfile000066400000000000000000000145201500416242000231330ustar00rootroot00000000000000#========================================================================== # \ # \ # BSD LICENSE \ # \ # Copyright(c) 2024-2025 Intel Corporation. \ # All rights reserved. \ # \ # Redistribution and use in source and binary forms, with or without \ # modification, are permitted provided that the following conditions \ # are met: \ # \ # * Redistributions of source code must retain the above copyright \ # notice, this list of conditions and the following disclaimer. \ # * Redistributions in binary form must reproduce the above copyright \ # notice, this list of conditions and the following disclaimer in \ # the documentation and/or other materials provided with the \ # distribution. \ # * Neither the name of Intel Corporation nor the names of its \ # contributors may be used to endorse or promote products derived \ # from this software without specific prior written permission. \ # \ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR \ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, \ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY \ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ # \ # \ #========================================================================== ARG UBUNTU_BASE=ubuntu:22.04 FROM ${UBUNTU_BASE} AS builder ARG OPENSSL_VERSION="openssl-3.0.16" ARG QATLIB_VERSION="24.02.0" ARG QAT_ENGINE_VERSION="v1.9.0" ARG IPSEC_MB_VERSION="v2.0" ARG IPP_CRYPTO_VERSION="v1.1.0" ARG GID ENV DEBIAN_FRONTEND=noninteractive # Install required packages including curl, telnet, and git RUN apt-get update && \ apt-get install -y apt-utils \ software-properties-common && \ add-apt-repository ppa:ubuntu-toolchain-r/test -y && \ apt-get update # Upgrade all other packages RUN apt-get upgrade -y && \ apt-get install -y \ libudev-dev \ make \ gcc-13 \ g++-13 \ nasm \ pkg-config \ libssl-dev \ zlib1g-dev \ git \ nasm \ autoconf \ automake \ cmake \ ca-certificates \ libtool \ texinfo \ bison \ python3 \ wget && \ git clone --depth 1 -b $OPENSSL_VERSION https://github.com/openssl/openssl.git && \ git clone --depth 1 -b $QAT_ENGINE_VERSION https://github.com/intel/QAT_Engine && \ git clone --depth 1 -b $IPP_CRYPTO_VERSION https://github.com/intel/cryptography-primitives && \ git clone --depth 1 -b $IPSEC_MB_VERSION https://github.com/intel/intel-ipsec-mb && \ git clone --depth 1 -b $QATLIB_VERSION https://github.com/intel/qatlib # Add the GCC 13 alternative to the update-alternatives filesystem RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 10 --slave /usr/bin/g++ g++ /usr/bin/g++-13 # Install binutils 2.40 RUN wget https://sourceware.org/pub/binutils/releases/binutils-2.40.tar.gz && \ tar -zxvf binutils-2.40.tar.gz WORKDIR /binutils-2.40 RUN ./configure && \ make -j && \ make install -j # Create a non-root user and group RUN groupadd -r appuser && useradd -r -g appuser -s /bin/bash appuser # Building OpenSSL WORKDIR /openssl RUN ./config && \ make -j && \ make install -j # Building QATLIB WORKDIR /qatlib RUN ./autogen.sh && \ ./configure --enable-systemd=no && \ make -j && \ make install samples-install && \ groupadd qat -g ${GID} && \ usermod -a -G qat appuser # Building Crypto_MB WORKDIR /cryptography-primitives/sources/ippcp/crypto_mb RUN cmake . -B"../build" \ -DOPENSSL_INCLUDE_DIR=/usr/local/include \ -DOPENSSL_LIBRARIES=/usr/local/lib64 \ -DOPENSSL_ROOT_DIR=/openssl WORKDIR /cryptography-primitives/sources/ippcp/build RUN make crypto_mb -j && make install -j # Building Ipsec_MB WORKDIR /intel-ipsec-mb RUN make -j && make install LIB_INSTALL_DIR=/usr/local/lib # Building QAT Engine WORKDIR /QAT_Engine RUN ./autogen.sh && \ ./configure \ --with-openssl_install_dir=/usr/local/ \ --with-qat-hw-dir=/usr/local/ \ --enable-qat_sw && \ make -j && make install -j #Added to remove libc library for vulnerability issue RUN apt-get purge -y linux-libc-dev FROM ${UBUNTU_BASE} RUN apt-get update && \ apt-get upgrade -y COPY --from=builder /usr/local/lib/libqat.so.4.2.0 /usr/lib/ COPY --from=builder /usr/local/lib/libusdm.so.0.1.0 /usr/lib/ COPY --from=builder /usr/local/lib/libIPSec_MB.so.2.0.0 /usr/lib/x86_64-linux-gnu/ COPY --from=builder /usr/local/lib64/libcrypto.so.3 /usr/lib/x86_64-linux-gnu/ COPY --from=builder /usr/local/lib/intel64/libcrypto_mb.so.12.1 /usr/lib/x86_64-linux-gnu/ COPY --from=builder /usr/local/bin/openssl /usr/bin/ COPY --from=builder /usr/local/lib64/engines-3/qatengine.so /usr/lib/x86_64-linux-gnu/engines-3/ COPY --from=builder /etc/group /etc/group COPY --from=builder /etc/passwd /etc/passwd RUN ldconfig #Expose the 8080 port EXPOSE 8080 # Switch to non-root user USER appuser ENV OPENSSL_ENGINES="/usr/lib/x86_64-linux-gnu/engines-3/" ENV LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/" ENV QAT_POLICY=1 qatengine-1.9.0/docs/000077500000000000000000000000001500416242000144165ustar00rootroot00000000000000qatengine-1.9.0/docs/apps.md000066400000000000000000000045211500416242000157050ustar00rootroot00000000000000## Application Integration ### Asynchronous Mode Nginx\* with QAT NGINX\* with asynchronous mode for Intel® OpenSSL QAT Engine provides significant performance improvement with QAT acceleration. The asynchronous fork of NGINX\* can be found at the following Github\* repository: * [Intel® QuickAssist Technology (QAT) Async Mode NGINX\*](https://github.com/intel/asynch_mode_nginx) Follow the below link on how to enable Async mode Nginx\* with QAT Hardware and software Aceeleration using best known configuration. [Async mode for Nginx\*](https://intel.github.io/quickassist/qatlib/asynch_nginx.html) ### NGINX\* QUIC with QAT Experimental QUIC support for NGINX\* with Intel® QAT Engine for BoringSSL\* Library can be found [here](https://www.intel.com/content/www/us/en/content-details/737522/experimental-quic-support-for-nginx.html) ### HAProxy\* with QAT HAProxy\* is a free, very fast and reliable reverse-proxy offering high availability, load balancing, and proxying for TCP and HTTP-based applications. Follow the instructions from HAProxy [Install](https://github.com/haproxy/haproxy/blob/master/INSTALL) to build and install Haproxy. Use `USE_PTHREAD_EMULATION=1` option in the make command which improves performance utilizing HAProxy's much lighter locks replacing OpensSL\* Pthread locks. Add the following options along with other standard settings in the HAProxy\* [Configuration File](https://www.haproxy.com/documentation/haproxy-configuration-manual/latest) to utilize QAT Acceleration. ```bash ssl-engine qatengine algo ALL ssl-mode-async ``` ## Case Studies * [Intel® QuickAssist Technology and OpenSSL-1.1.0:Performance](https://www.intel.com/content/www/us/en/content-details/709581/intel-quickassist-technology-and-openssl-1-1-0-performance.html) * [IntelĀ® QuickAssist Technology - NGINX\* Performance White Paper](https://networkbuilders.intel.com/solutionslibrary/intel-quickassist-technology-nginx-performance-white-paper) * [Accelerate HAProxy\* with Intel QAT](https://www.intel.com/content/www/us/en/content-details/814574/accelerating-haproxy-with-intel-quickassist-technology.html) Other Application Integration and more case studies can be found at QAT link below * [IntelĀ® QuickAssist Technology (IntelĀ® QAT)](https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html) qatengine-1.9.0/docs/async_job.md000066400000000000000000000025741500416242000167170ustar00rootroot00000000000000# Using the OpenSSL\* asynchronous mode 'ASYNC_JOB' infrastructure Asynchronous operation utilizes the OpenSSL\* asynchronous mode (`ASYNC_JOB` infrastructure) introduced in OpenSSL\* version 1.1.0. In the OpenSSL\* master branch this infrastructure was augmented to provide an additional `callback` method by which the OpenSSL\* Engine can be notified of crypto operation request completions by the hardware accelerator. This additional method can be used if you think that using the alternative `file descriptor` method descriptor is too costly in terms of CPU cycles or in some context where a file descriptor is not appropriate. The QAT OpenSSL\* Engine build system will automatically detect whether the OpenSSL\* version being built against supports this additional `callback` method. If so, the QAT OpenSSL\* Engine code will use the `callback` mechanism for job completion rather than the `file descriptor` mechanism if a `callback` function has been set. If a `callback` has not been set then the `file descriptor` method will be used.

drawing

For further details on using the OpenSSL\* asynchronous mode infrastructure please see the OpenSSL\* online documentation located at: - - . qatengine-1.9.0/docs/bssl_support.md000066400000000000000000000120111500416242000174720ustar00rootroot00000000000000# IntelĀ® QuickAssist Technology(QAT) BoringSSL\* Library IntelĀ® QuickAssist Technology BoringSSL\* Library is a prototype accelerating asymmetric cryptographic algorithms for BoringSSL\*, the Google\*'s OpenSSL\* fork which doesn't support engine mechanism. It checks the type of user input SSL library during configuration time and builds out a traditional engine library if OpenSSL\* is detected or a library fitting in with BoringSSL\* private key method if BoringSSL\* is applied. This document details the capabilities, interfaces and limitations of the BoringSSL\* based library. Both the hardware and software requirements are explained followed by detailed instructions on how to install and use the library. ## Features - Asynchronous and Synchronous PKE QAT_HW Acceleration - RSA Support for Key Sizes 1024/2048/3072/4096. - ECDSA Support for NIST Prime Curves: P-256/P-384/P-521.(Disabled by default) - Asynchronous PKE QAT_SW Acceleration - RSA Support for Key Sizes 2048/3072/4096. - ECDSA Support for NIST Prime Curves: P-256/P-384.(Disabled by default) ## Limitations Some limitations specific for the current BoringSSL\* Library: * NIST Binary Curves and NIST Koblitz Curves are not supported by BoringSSL\. * QAT_HW and QAT_SW Co-existence is not supported. * `RSA_padding_add_PKCS1_OAEP` function is exported by BoringSSL\* `libdecrepit.so`, so it needs to be linked in the BoringSSL\* Library. It may cause linking error while building with the system lack of that library. ## Requirements - [Hardware Requirements](hardware_requirements.md) - [Software Requirements](software_requirements.md) ## Installation ### Build BoringSSL ``` git clone https://github.com/google/boringssl.git cd boringssl mkdir -p build cd build/ ``` Note: BoringSSL\* builds static library by default. To align with the QAT_Engine use case within NGINX\*, an explicit option is added to build it as a dynamic library. ``` cmake .. -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release make ``` BoringSSL\* doesn't support "make install" to consolidate build output to an appropriate location. Here is a solution to integrate all output libraries into one customized path 'lib' by symbol links. ``` cd .. mkdir -p lib ln -sf $(pwd)/build/libboringssl_gtest.so lib/ ln -sf $(pwd)/build/crypto/libcrypto.so lib/ ln -sf $(pwd)/build/ssl/libssl.so lib/ ln -sf $(pwd)/build/decrepit/libdecrepit.so lib/ ``` Note: RSA Padding schemes are handled by BoringSSL\* rather than accelerated, so the engine supports the same padding schemes as BoringSSL\* does natively. ### Build the IntelĀ® QuickAssist Technology BoringSSL\* Library The prerequisite to run autogen.sh is to have autotools (autoconf, automake, libtool and pkg-config) installed in the system. ``` cd ./autogen.sh ``` To build and install the IntelĀ® QAT_HW BoringSSL\* Library: ``` ./configure --with-openssl_install_dir= --with-qat_hw_dir= make install ``` To build and install the IntelĀ® QAT_SW BoringSSL\* Library: ``` ./configure --enable-qat_sw --with-openssl_install_dir= make make install ``` In the above example, `--disable-qat_hw` needs to be provided if the system has qatlib installed. Note : `--enable-qat_sw` checks crypto_mb and IPSec_MB libraries in its respective default path (/usr/local/lib and /usr/lib) or in the path provided in the config flag `--with-qat_sw_crypto_mb_install_dir` (for crypto_mb) and `--with-qat_sw_ipsec_mb_install_dir` (for ipsec_mb). If any of the libraries is not installed then their corresponding algorithm support is disabled. By here, the QAT BoringSSL\* Library `libqatengine.so` is installed to system path `/usr/local/lib`. Set the `--prefix` if specific install path is expected. ### Test the IntelĀ® QuickAssist Technology BoringSSL\* Library The test code is under `test_bssl/` directory and will be compiled along with this library. - Get usage help by running `qatengine_test` with `-h` option ``` # ./qatengine_test -h Usage: ./qatengine_test [-h/-d/-a] <-k> -a : Enable async mode -d : Test on rsa private decrypt -h : Print all available options -k : Set private key file path for test purpose e.g. /opt/rsa_key.pmem Test command lines for reference: ./qatengine_test -k /opt/rsa_private_2k.key ./qatengine_test -k /opt/rsa_private_2k.key -a ./qatengine_test -k /opt/rsa_private_2k.key -d ./qatengine_test -k /opt/rsa_private_4k.key ./qatengine_test -k /opt/ec-secp384r1-priv-key.pem ./qatengine_test -k /opt/ec-secp384r1-priv-key.pem -a ``` `Note:` All private keys mentioned here are just for example, pls instead by your locally generated or existing one. `Note:` Async mode can't be applied to the BoringSSL default method when QAT_HW and QAT_SW are disabled. - Tip: to get more debug information, enable QATEngine option: --enable-qat_debug when configuring QATEngine before compiling. All example codes provided here are __exclusively__ used for functional tests on QATEngine APIs with BoringSSL enabled. qatengine-1.9.0/docs/config_options.md000066400000000000000000000425001500416242000177610ustar00rootroot00000000000000# Intel® QuickAssist Technology OpenSSL\* Engine Build Options The following is a list of the options that can be used with the `./configure` command when building the Intel® QAT OpenSSL\* Engine: ### qat_hw options: ``` --with-qat_hw_dir=/path/to/qat_driver Specify the path to the source code directory of the Intel(R) QAT Driver. This path is needed for compilation in order to locate the Intel(R) QAT header files. For example if using Intel(R) QAT Driver package that was unpacked to `/QAT` you would use the following setting: --with-qat_hw_dir=/QAT This option is not required when building against the in-tree driver installed via qatlib RPM. This option is not required when building for qat_sw. ``` ### Building against OpenSSL from source ``` --with-openssl_install_dir=/path/to/openssl_install Specify the path to the top level directory where the OpenSSL* was installed to. When this path is specified the qatengine.so engine library is copied into the folder containing the other dynamic engines during the 'make install'. For example if you installed OpenSSL* to its default location of `/usr/local/ssl` then you would use the following setting: --with-openssl_install_dir=/usr/local/ssl If your system already includes OpenSSL 1.1.1 library and devel package this option is not required. In this case qatengine.so is installed in the system enginesdir (eg: /usr/lib64/engine-1.1). ``` ### qat_sw options ``` --enable-qat_sw/--disable-qat_sw Enable/Disable qat_sw acceleration. This flag needs to be enabled to utilize qat_sw acceleration. This flag when enabled uses Intel(R) Crypto Multi-buffer and Intel(R) Multi-buffer crypto for IPsec library and headers from the default path (/usr/local and /usr/ respectively). If the crypto_mb and IPSec_MB libraries are installed in the path other than default then use `--with-qat_sw_crypto_mb_install_dir` and `--with-qat_sw_ipsec_mb_install_dir` to set the crypto_mb and ipsec_mb libraries install dir respectively. (disabled by default). --disable-qat_hw Disable Intel(R) QAT Hardware acceleration. This flag needs to be enabled if the system has both QAT Hardware and QAT Software Multi-buffer capabilities and the in-tree driver is installed in the system via `qatlib` RPM where use of QAT SW acceleration over QAT HW is preferred. In case of the in-tree driver even though QAT SW acceleration is enabled via use of the '--enable-qat_sw' option, if both capabilities are available (both QAT HW or QAT SW) then QAT HW acceleration will be used by default. However, use of this `--disable-qat_hw` option will force the use of QAT SW acceleration. ``` ### Optional ``` --with-openssl_dir=/path/to/openssl Specify the path to the top level of the OpenSSL* source code. This path is only needed to regenerate engine specific error source files using the mkerr.pl script from the OpenSSL source. This option needs to be used if there is any new error message added in the QAT Engine source files and the error files will get updated using the mkerr.pl script. The default if not provided will build QAT Engine from the existing error files qat_err.c, qat_err.h & qat.txt in the QAT Engine dir which is generated from OpenSSL release mentioned in the github release page. For example if you cloned the OpenSSL* Github* repository from within `/` then you would use the following setting: --with-openssl_dir=/openssl --with-qat_hw_install_dir=/path/to/qat_driver/build Specify the path to the location of the built Intel(R) QAT Hardware Driver library files. This path is needed in order to link to the userspace libraries of the Intel(R) QAT Hardware Driver. The default if not specified is to use the path specified by --with-qat_hw_dir with '/build' appended. You only need to specify this parameter if the driver library files have been built somewhere other than the default. --with-qat_sw_crypto_mb_install_dir=/path/to/crypto_mb install location Specify the path of the built Intel(R) Crypto Multi-buffer library (crypto_mb). This path is needed in order to link to the crypto_mb library. The default if not specified is to use the standard installation path which is '/usr/local'. You only need to specify this parameter if the Intel(R) crypto_mb library files have been built somewhere other than the default. --with-qat_sw_ipsec_mb_install_dir=/path/to/ipsec_mb install location Specify the path of the built Intel(R) Multi-buffer crypto for IPsec library (IPSec_mb). This path is needed in order to link to the IPsec_MB library. The default if not specified is to use the standard installation path which is '/usr'. You only need to specify this parameter if the Intel(R) IPSec_MB library files have been built somewhere other than the default. --with-qat_hw_usdm_dir=/path/to/usdm/directory Specify the path to the location of the USDM component. The default if not specified is to use the path specified by '--with-qat_hw_dir' with '/quickassist/utilities/libusdm_drv' appended. You only need to specify this parameter if using the USDM component, and if the path to it is different from the default. --enable-qat_provider Enables Provider support instead of engine for OpenSSL. Valid only when built against OpenSSL 3.0, default if not specified will use engine interface. Currently RSA, ECDSA, ECDH, ECX and AES-GCM algorithms are only supported (disabled by default). --enable-qat_fips Enables FIPS support when provider is enabled. Valid only when built against OpenSSL 3.0 along with the flag `--enable-qat_provider`, (disabled by default). --disable-qat_hw_rsa/--enable-qat_hw_rsa Disable/Enable Intel(R) QAT Hardware RSA acceleration (enabled by default). --disable-qat_hw_dsa/--enable-qat_hw_dsa Disable/Enable Intel(R) QAT Hardware DSA acceleration (enabled by default). --disable-qat_hw_dh/--enable-qat_hw_dh Disable/Enable Intel(R) QAT Hardware DH acceleration (enabled by default). --disable-qat_hw_ecdh/--enable-qat_hw_ecdh Disable/Enable Intel(R) QAT Hardware ECDH acceleration (enabled by default). --disable-qat_hw_ecdsa/--enable-qat_hw_ecdsa Disable/Enable Intel(R) QAT Hardware ECDSA acceleration (enabled by default). --disable-qat_hw_ciphers/--enable-qat_hw_ciphers Disable/Enable Intel(R) QAT Hardware Chained Cipher acceleration (enabled by default). --disable-qat_hw_prf/--enable-qat_hw_prf Disable/Enable Intel(R) QAT Hardware PRF acceleration (enabled by default). --disable-qat_hw_ecx/--enable-qat_hw_ecx Disable/Enable Intel(R) QAT Hardware X25519/X448 acceleration (enabled by default). --disable-qat_hw_hkdf/--enable-qat_hw_hkdf Disable/Enable Intel(R) QAT Hardware HKDF acceleration (disabled by default). --disable-qat_hw_gcm/--enable-qat_hw_gcm Disable/Enable Intel(R) QAT Hardware AES-GCM acceleration (disabled by default). --disable-qat_hw_ccm/--enable-qat_hw_ccm Disable/Enable Intel(R) QAT Hardware AES-CCM acceleration (enabled by default). --disable-qat_hw_sm4_cbc/--enable-qat_hw_sm4_cbc Disable/Enable Intel(R) QAT Hardware SM4-CBC acceleration.(disabled by default) This flag is valid only on 4xxx(QAT gen 4 devices) as the support is not available for earlier generations of QAT devices (e.g. c62x, dh895xxcc, etc.) and QAT Engine is built with Tongsuo only --disable-qat_hw_sha3/--enable-qat_hw_sha3 Disable/Enable Intel(R) QAT Hardware SHA-3 acceleration (disabled by default). This flag is valid only on 4xxx(QAT gen 4 devices) as the support is not available for earlier generations of QAT devices (e.g. c62x, dh895xxcc, etc.) --disable-qat_hw_sm3/--enable-qat_hw_sm3 Disable/Enable Intel(R) QAT Hardware SM3 acceleration (disabled by default). This flag is valid only on 4xxx(QAT gen 4 devices) as the support is not available for earlier generations of QAT devices (e.g. c62x, dh895xxcc, etc.) --disable-qat_hw_sm2/--enable-qat_hw_sm2 Disable/Enable Intel(R) QAT Hardware SM2 acceleration (disabled by default). This flag is valid only on 4xxx(QAT gen 4 devices) as the support is not available for earlier generations of QAT devices (e.g. c62x, dh895xxcc, etc.) --disable-qat_hw_chachapoly/--enable-qat_hw_chachapoly Disable/Enable Intel(R) QAT Hardware CHACHA20-POLY1305 acceleration (disabled by default). This flag is valid only on 4xxx(QAT gen 4 devices) as the support is not available for earlier generations of QAT devices (e.g. c62x, dh895xxcc, etc.) --disable-qat_sw_gcm/--enable-qat_sw_gcm Disable/Enable Intel(R) QAT Software vectorized AES-GCM acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag flag '--enable-qat_sw' and IPSec_mb library is installed in the system (enabled by default if qat_sw is enabled). --disable-qat_sw_rsa/--enable-qat_sw_rsa Disable/Enable Intel(R) QAT Software RSA acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' (enabled by default if qat_sw is enabled). --disable-qat_sw_ecx/--enable-qat_sw_ecx Disable/Enable Intel(R) QAT Software X25519 acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' (enabled by default if qat_sw is enabled). --disable-qat_sw_ecdsa/--enable-qat_sw_ecdsa Disable/Enable Intel(R) QAT Software ECDSA P-256/P-384 acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' (enabled by default if qat_sw is enabled). --disable-qat_sw_ecdh/--enable-qat_sw_ecdh Disable/Enable Intel(R) QAT Software ECDH P-256/P-384/SM2 acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' (enabled by default if qat_sw is enabled). --disable-qat_sw_sm2/--enable-qat_sw_sm2 Disable/Enable Intel(R) QAT Software ECDSA SM2 acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' (enabled by default if qat_sw is enabled). --disable-qat_sw_sm3/--enable-qat_sw_sm3 Disable/Enable Intel(R) QAT Software SM3 acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' (disabled by default). --disable-qat_sw_sm4_cbc/--enable-qat_sw_sm4_cbc Disable/Enable Intel(R) QAT Software SM4-CBC acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' and QAT Engine is built with Tongsuo only (disabled by default if qat_sw is enabled). --disable-qat_sw_sm4_gcm/--enable-qat_sw_sm4_gcm Disable/Enable Intel(R) QAT Software SM4-GCM acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' and QAT Engine is built with Tongsuo only (disabled by default if qat_sw is enabled). --disable-qat_sw_sm4_ccm/--enable-qat_sw_sm4_ccm Disable/Enable Intel(R) QAT Software SM4-CCM acceleration. This flag is valid only when QAT SW acceleration is enabled using the flag '--enable-qat_sw' and QAT Engine is built with Tongsuo only (disabled by default if qat_sw is enabled). --enable-qat_small_pkt_offload Enable the acceleration of small packet cipher operations to Intel(R) QAT Hardware. When disabled, these operations are performed using the CPU (disabled by default). --enable-qat_warnings Enable warnings to aid debugging. Warning: This option should never be left on in a production environment as it may introduce side channel timing attack vulnerabilities (disabled by default). --enable-qat_debug Enable debug output to aid debugging. This will also enable the warning messages above. Warning: This option should never be enabled in a production environment as it may output private key information to the console/logs and may also introduce side channel timing attack vulnerabilities (disabled by default). --enable-qat_mem_warnings Enable warnings from the userspace memory management code to aid debugging. Warning: This option should never be left on in a production environment as it may introduce side channel timing attack vulnerabilities (disabled by default). --enable-qat_mem_debug Enable debug output from the userspace memory management code to aid debugging. This will also enable the warning messages above. This option produces quite verbose output hence why it is separate to the standard debug. Warning: This option should never be enabled in a production environment as it may output private key information to the console/logs and may also introduce side channel timing attack vulnerabilities (disabled by default). --with-qat_debug_file=/file/and/path/to/log/qat/debug/to This option turns on logging to a file instead of to stderr. It works with any combination of the following flags: --enable-qat_warnings --enable-qat_debug --enable-qat_mem_warnings --enable-qat_mem_debug The option should specify the full absolute path and filename that you would like to log to. The directory needs to be writable by the user the process is running as, and the log file can get very big, very quickly. The existing log file will be replaced rather than appended to on each run of the application. If the file cannot be opened for writing then the logging will default to output to stderr. As with the other logging options this option should never be enabled in a production environment as private key information and plaintext data will be logged to the file (logging to file is disabled by default). --with-qat_engine_id="" This option needs to be specified if you want to use an engine id other than the default which is now "qatengine" (previously it was "qat"). This option can be used to set engine id as "qat" for application that still uses older engine id within the application(disabled by default). --enable-qat_plock Enables Plock optimization within QAT Engine which is an alternative to pthread's rwlock for multithread application. This flag when enabled uses plock using preload as mentioned in QAT Engine install instructions and improves performance for higher number of threads (disabled by default). --enable-qat_ntls Enable ntls in engine for handing NTLS requests which is needed for SMx with Tongsuo (disabled by default). --enable-qat_insecure_algorithms Enables insecure algorithms RSA < 2048, DH, DSA, ECDH curves with bitlen < 256, ECDSA Curves with bitlen < 256, AES128-CBC-HMAC-SHA1, AES256-CBC-HMAC-SHA1 & SHA3-224. These insecure algorithms are disabled by default. QAT HW driver version v1.7 needs to be built with the flag `./configure --enable-legacy-algorithms` to enable these algorithms (disabled by default). --disable-qat_hw_lenstra_protection Disable protection against Lenstra attack (CVE-2017-5681) (protection is enabled by default). The RSA-CRT implementation in the Intel(R) QAT OpenSSL* Engine, for OpenSSL* versions prior to v0.5.19, may allow remote attackers to obtain private RSA keys by conducting a Lenstra side-channel attack. From version v0.5.19 onward, protection against this form of attack is effected by performing a Verify/Encrypt operation after the Sign/Decrypt operation, and if a failure is detected then re-running the Sign/Decrypt operation using the CPU. However, future releases of Intel(R) QAT driver code or firmware may effect this protection instead, in which case the Intel(R) QAT OpenSSL* Engine code-based protection would no longer be required and this configuration option should then be selected. For further information, please refer to:- https://security-center.intel.com/advisory.aspx?intelid=INTEL-SA-00071&languageid=en-fr https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5681 --enable-qat_hw_lenstra_verify_hw Enable Lenstra Verify using QAT HW instead of OpenSSL Software method. (disabled by default). --disable-qat_auto_engine_init_on_fork Disable the engine from being initialized automatically following a fork operation. This is useful in a situation where you want to tightly control how many instances are being used for processes. For instance if an application forks to start a process that does not utilize QAT currently the default behaviour is for the engine to still automatically get started in the child using up an engine instance. After using this flag either the engine needs to be initialized manually using the engine message: INIT_ENGINE or will automatically get initialized on the first QAT crypto operation. The initialization on fork is enabled by default. --enable-qat_sw_heuristic_timeout Enable self tuning of the timeout in the polling thread in the Intel(R) QAT SW. This flag is valid only in case of QAT SW (disabled by default). --enable-qat_cycle_counts Enable cycle count measurement in the qat_sw acceleration. This support is only extended to qat_sw acceleration code path (disabled by default). --with-cc-opt="parameters" Sets additional parameters that will be added to the CFLAGS variable at compile time. --with-ld-opt="parameters" Sets additional parameters that will be used during linking. ``` qatengine-1.9.0/docs/engine_specific_messages.md000066400000000000000000000365421500416242000217530ustar00rootroot00000000000000# Intel® QuickAssist Technology OpenSSL\* Engine Specific Messages OpenSSL\* engines support a mechanism whereby custom messages can be defined for an application to communicate directly with the engine. These messages are typically used in two ways: 1. Firstly in order to set configuration options. These messages are typically sent before the engine is initialized. Sending these after initialization will typically have no effect. 2. Secondly in order to control the engine operation. These messages may be sent before initialization or after or both. The custom message mechanism passes a string to identify the message, and uses a number of parameters to pass information into or out of the engine. It is defined as follows: ENGINE_ctrl_cmd(, , , , NULL, 0\) Where: - `` is a pointer to the Intel® QAT enabled OpenSSL\* Engine. - `` is a string representing the message type. - `` is a long that can be used to pass a number, or a pointer can be cast to it. - `` is a void pointer used to pass data structures in. - The last two parameters are always `NULL` and 0 when used with the Intel® QAT OpenSSL\* Engine. ```text Message String: ENABLE_EXTERNAL_POLLING Param 3: 0 Param 4: NULL Description: This message is used to enable the external polling mode of operation where it becomes the applications responsibility to use the POLL message below to check for messages that have been returned from the hardware accelerator. It has no parameters or return value. If required this message must be sent after engine creation and before engine initialization. Message String: POLL Param 3: 0 Param 4: pointer to an int Description: This message is used when external polling is enabled to request poll of all instances. The status of the request is passed back in the variable passed in as Param 4. This message may be sent at any time after engine initialization. Message String: INIT_ENGINE Param 3: 0 Param 4: NULL Description: This message is not normally necessary as the engine will get initialized either via an ENGINE_init() call or automatically following a fork. This message would only be used for performance reasons with an engine compiled with --disable-qat_auto_engine_init_on_fork. In that case it may be desirable to send this engine message in the child rather than wait for the engine to be initialized automatically on the first accelerated crypto request. Message String: SET_INTERNAL_POLL_INTERVAL Param 3: unsigned long cast to a long Param 4: NULL Description: This message is used to set the interval in nano seconds between polling for messages coming back from the hardware accelerator. The value should be passed in as Param 3. The default is 10,000, the min value is 1, and the max value is 10,000,000. This message can be sent at any time after the engine has been created. Message String: SET_EPOLL_TIMEOUT Param 3: unsigned long cast to a int Param 4: NULL Description: This message is used to set the timeout in milli seconds used for epoll_wait() when event driven polling mode is enabled. The value should be passed in as Param 3. The default is 1,000, the min value is 1, and the max value is 10,000. This message can be sent at any time after the engine has been created. This message is not supported in the FreeBSD operating system or in the qatlib RPM. Message String: ENABLE_EVENT_DRIVEN_POLLING_MODE Param 3: 0 Param 4: NULL Description: This message changes the engines mode to use the Intel(R) QAT Drivers event driven polling feature. It must be sent if required after engine creation but before engine initialization. It should not be sent after engine initialization. This message is not supported in the FreeBSD operating system or in the qatlib RPM. Message String: DISABLE_EVENT_DRIVEN_POLLING_MODE Param 3: 0 Param 4: NULL Description: This message changes the engines mode to use the timer based polling feature. It must be sent if required after engine creation but before engine initialization. It should not be sent after engine initialization. This message is not supported in the FreeBSD operating system or in the qatlib RPM. Message String: GET_NUM_CRYPTO_INSTANCES Param 3: 0 Param 4: pointer to an int Description: This message is used to retrieve the total number of crypto instances available as specified in the Intel(R) QAT Driver config file. The number of instances is assigned to the dereferenced int that is passed in as Param 4. This message is used in conjunction with the GET_POLLING_FD message as in event driven polling mode with external polling there is an fd to listen to events on for each crypto instance. This message must be sent if required after the engine has been initialized. Message String: GET_EXTERNAL_POLLING_FD Param 3: int cast to a long Param 4: pointer to an int Description: This message is used to retrieve the file descriptor that can be used for event notification when the Intel(R) QAT Driver has had the event driven polling feature enabled. The value passed in as Param 3 is the instance to retrieve the fd for. The fd is returned by assigning to the dereferenced int passed as Param4. When retrieving fd's it is usual to first request how many instances there are with the GET_NUM_CRYPTO_INSTANCES message and then use a for loop to iterate through the instances starting from 0 and use this message to retrieve the fd for each instance. This message must be sent if required after the engine has been initialized. This message is not supported in the FreeBSD operating system or in the qatlib RPM. Message String: SET_INSTANCE_FOR_THREAD Param 3: long Param 4: NULL Description: This message is used to bind the thread to a specific instance number. Param 3 contains the instance number to bind to. If required, the message must be sent after the engine creation and will automatically trigger the engine initialization. Message String: GET_NUM_OP_RETRIES Param 3: 0 Param 4: pointer to an unsigned int Description: This message returns the number of retry operations. The number is set in the variable passed in as Param 4. This message may be sent at any time after engine initialization. Message String: SET_MAX_RETRY_COUNT Param 3: int cast to a long Param 4: NULL Description: This message is used for synchronous operations to determine how many times the engine should retry a message before flagging a failure. The value should be passed in as Param 3. Setting the value to -1 results in infinite retries. The default is 5 and the max value is 100,000. This message can be sent at any time after the engine is created. Message String: SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD Param 3: 0 Param 4: NULL terminated string of cipher algorithm name and threshold value. Maximum length is 1024 bytes including NULL terminator. Description: This message is used to set the threshold that determines the size crypto packets need to be before they are accelerated to the acceleration device. It is not efficient to accelerate very small packets to the accelerator as to do so would take longer to transfer the data to and from the accelerator than to encrypt/decrypt using the main CPU. The threshold value can be set independently for each EVP_CIPHER operation supported by the engine using the following names: AES-128-CBC-HMAC-SHA1 AES-256-CBC-HMAC-SHA1 AES-128-CBC-HMAC-SHA256 AES-256-CBC-HMAC-SHA256 The input format should be a string like this in one line: AES-128-CBC-HMAC-SHA1:4096,AES-256-CBC-HMAC-SHA1:8192 Using a separator ":" between cipher name and threshold value. Using a separator "," between different cipher configurations. The default threshold value is 2048 bytes, the minimum is 0 bytes and the maximum is 16,384. The threshold value includes all the bytes that make up the TLS record including Record Header (5 bytes), IV (16 bytes), Payload, HMAC (20/32 bytes), Padding (variable but could be max 255 bytes), and Padding Length (1 byte). The string should be NULL terminated and not more than 1024 bytes long including NULL terminator. This message is not supported when the engine is compiled with the flag --enable-qat_small_pkt_offload. Message String: ENABLE_INLINE_POLLING Param 3: 0 Param 4: NULL Description: This message is used to enable the inline polling mode of operation where a busy loop is used by the Intel(R) QAT OpenSSL* Engine to check for messages from the hardware accelerator after requests are sent to it. Currently this mode is only available in the synchronous RSA computation. It has no parameters or return value. If required this message must be sent after engine creation and before engine initialization. Message String: ENABLE_HEURISTIC_POLLING Param 3: 0 Param 4: NULL Description: This message is used to enable the heuristic polling mode of operation where the application can use the GET_NUM_REQUESTS_IN_FLIGHT message below to retrieve the number of different kinds of in-flight requests and intelligently determine the proper moment to perform the polling operation. This mode can be regarded as an improvement of the timer-based external polling. The external polling mode must be enabled first before enabling this mode. If required this message must be sent after engine creation and before engine initialization. Message String: GET_NUM_REQUESTS_IN_FLIGHT Param 3: int cast to a long Param 4: pointer to an int address Description: This message is used when heuristic polling is enabled to retrieve the number of different kinds of in-flight requests. The value passed in as param 3 is the indicator for a specific kind of request: #define GET_NUM_ASYM_REQUESTS_IN_FLIGHT 1 #define GET_NUM_KDF_REQUESTS_IN_FLIGHT 2 #define GET_NUM_CIPHER_PIPELINE_REQUESTS_IN_FLIGHT 3 The first (i.e, value 1) is used to retrieve the number of asymmetric-key in-flight requests. The second (i.e, value 2) is used to retrieve the number of KDF(PRF and HKDF) in-flight requests. The last (i.e, value 3) is used to retrieve the number of cipher in-flight requests (when the OpenSSL* pipelining feature is not used), or the number of in-flight pipelines (when the OpenSSL* pipelining feature is used). The address of the variable recording the specified info is returned by assigning to the dereferenced int address passed as Param 4. This means the application can directly use this int address to retrieve the specified info afterwards without sending this message again. This message may be sent at any time after engine initialization. Message String: SET_CONFIGURATION_SECTION_NAME Param 3: 0 Param 4: NULL terminated string of section name from Intel(R) QAT Driver config file. Maximum length is 64 bytes including NULL terminator. Description: This message is used to configure the Intel(R) QAT OpenSSL* Engine to use the string passed in as parameter 4 to be the name for the Intel(R) QAT Driver config section rather than the default `[SHIM]`. It must be sent after engine creation but before engine initialization. It should not be sent after engine initialization. Message String: ENABLE_SW_FALLBACK Param 3: 0 Param 4: NULL Description: This message is used to enable fallback to software (on-core) of the crypto operations normally accelerated to the acceleration devices by the Intel® QuickAssist Technology OpenSSL\* Engine. This command enables the software fallback feature - crypto operations will continue to be accelerated but, with this feature enabled, in the event the acceleration devices subsequently go offline the Intel® QuickAssist Technology OpenSSL\* Engine will automatically switch to performing crypto operations on-core. If required this message must be sent after engine creation and before engine initialization. This message is not supported in the FreeBSD operating system or in the qatlib RPM. Message String: HEARTBEAT_POLL Param 3: 0 Param 4: pointer to an int Description: This message is used to check the acceleration devices are still functioning. It is normally used in conjunction with the Software Fallback feature (see engine command ENABLE_SW_FALLBACK) when using External Polling Mode (see engine command ENABLE_EXTERNAL_POLLING). The result of this engine specific message (success/failure) is assigned to the dereferenced int that is passed in as Param 4. Polling using this message will result in the Intel® QuickAssist Technology OpenSSL\* Engine being notified when instances of an acceleration device go offline or come back online. By sending this message more frequently you can decrease the time taken for the engine to become aware of instances going offline/coming back online at the expense of additional cpu cycles. The suggested polling interval would be around 0.5 seconds to 1 second. This message may be sent at any time after engine initialization. This message is not supported in the FreeBSD operating system or in the qatlib RPM. Message String: DISABLE_QAT_OFFLOAD Param 3: 0 Param 4: NULL Description: This message is used to disable acceleration of crypto operations to the acceleration devices when QAT HW Acceleration is enabled, with the immediate effect that these operations are performed on-core instead. This message may be sent at any time after engine initialization. Message String: HW_ALGO_BITMAP Param 3: 0 Param 4: pointer to an unsigned long int Description: This message is used to set the global QAT_HW algorithm bitmap and will trigger the bind_qat() again to reload the QAT_HW algorithm method according to the input bitmap value. The input value should be a hex string, like 0x82EF, which is the combination of the bitmap for each algorithm. Currently, the Engine supports the first 16 bits of the input value, the higher bit value will be deprecated. The default QAT_HW algorithm bitmap is 0xFFFF which means all algorithms are supported at the runtime level. For more detailed usage, refer to: docs/qat_common.md Message String: SW_ALGO_BITMAP Param 3: 0 Param 4: pointer to an unsigned long int Description: This message is used to set the global QAT_SW algorithm bitmap and will trigger the bind_qat() again to reload the QAT_SW algorithm method according to the input bitmap value. The input value should be a hex string, like 0x82EF, which is the combination of the bitmap for each algorithm. Currently, the Engine supports the first 16 bits of the input value, the higher bits value will be deprecated. The default QAT_SW algorithm bitmap is 0xFFFF which means all algorithms are supported at the runtime level. For more detailed usage, refer to: docs/qat_common.md ``` qatengine-1.9.0/docs/features.md000066400000000000000000000051031500416242000165550ustar00rootroot00000000000000# Features ## qat_hw Features * Asymmetric PKE * RSA for Key Sizes 512/1024/2048/4096/8192. * DH for Key Sizes 768/1024/1536/2048/3072/4096/8192. * DSA for Key Sizes 160/1024, 224/2048, 256/2048, 256/3072. * ECDH for the following curves: * NIST Prime Curves: P-192/P-224/P-256/P-384/P-521. * NIST Binary Curves: B-163/B-233/B-283/B-409/B-571. * NIST Koblitz Curves: K-163/K-233/K-283/K-409/K-571. * Montgomery EC Curves: X25519/X448 (ECX). * ECDSA for the following curves: * NIST Prime Curves: P-192/P-224/P-256/P-384/P-521. * NIST Binary Curves: B-163/B-233/B-283/B-409/B-571. * NIST Koblitz Curves: K-163/K-233/K-283/K-409/K-571. * SM2 * Symmetric Ciphers * AES128-CBC-HMAC-SHA1/AES256-CBC-HMAC-SHA1. * AES128-CBC-HMAC-SHA256/AES256-CBC-HMAC-SHA256. * AES128-CCM, AES192-CCM, AES256-CCM. * AES128-GCM, AES256-GCM. * ChaCha20-Poly1305 * SM4-CBC * Key Derivation * PRF * HKDF * Hashing * SHA3-224/256/384/512 * SM3 * Synchronous and [Asynchronous](async_job.md) Operation * [Pipelined Operations](qat_hw.md#using-the-openssl-pipelining-capability) * [Intel® QAT OpenSSL\* Engine Software Fallback](qat_hw.md#intel-qat-openssl-engine-software-fallback-feature) * [Key Protection Technology (KPT) Support using QAT_HW driver v2.0](qat_hw_kpt.md) Please refer [here](qat_hw_algo.md) for applicable QAT Hardware versions and algorithms enabled by default. ## qat_sw Features * [Intel® QAT Software Acceleration](qat_sw.md) * Asymmetric PKE * RSA for Key size 2048, 3072, 4096 * ECDH for the following curves: * Montgomery EC Curve: X25519 * NIST Prime Curves: P-256/P-384 * SM2 * ECDSA for the following curves: * NIST Prime Curves: P-256/P-384 * SM2 * Symmetric Ciphers * AES128-GCM, AES192-GCM and AES256-GCM * SM4-CBC using 16 Multibuffer requests (Tongsuo only) * SM4-GCM using 16 Multibuffer requests (Tongsuo only) * SM4-CCM using 16 Multibuffer requests (Tongsuo only) * Hashing * SM3 Hash using 16 Multibuffer requests (Experimental) ## Common Features to qat_hw & qat_sw * [BoringSSL Support](bssl_support.md) * [OpenSSL 3.0 Provider Support](qat_common.md#openssl-30-provider-support) * [QAT_HW & QAT_SW Co-existence](qat_coex.md#qat-hw-and-qat-sw-co-existence) * [FIPS 140-3 Certification](qat_common.md#fips-140-3-certification) Note: RSA Padding schemes are handled by OpenSSL\* or BoringSSL\* rather than accelerated, so the engine supports the same padding schemes as OpenSSL\* or BoringSSL\* does natively. qatengine-1.9.0/docs/hardware_requirements.md000066400000000000000000000021561500416242000213440ustar00rootroot00000000000000# Hardware Requirements QAT_HW acceleration is supported on the platforms with the following QAT devices * [IntelĀ® QuickAssist 4xxx Series][1] * [IntelĀ® QuickAssist Adapter 8970][2] * [IntelĀ® QuickAssist Adapter 8960][3] * [IntelĀ® QuickAssist Adapter 8950][4] * [IntelĀ® Atom™ Processor C3000][5] QAT_SW acceleration is supported in the platforms starting with [3rd Generation Intel® Xeon® Scalable Processors family][6] and later. [1]:https://www.intel.com/content/www/us/en/products/details/processors/xeon.html [2]:https://www.intel.com/content/www/us/en/products/sku/125200/intel-quickassist-adapter-8970/downloads.html [3]:https://www.intel.com/content/www/us/en/products/sku/125199/intel-quickassist-adapter-8960/downloads.html [4]:https://www.intel.com/content/www/us/en/products/sku/80371/intel-communications-chipset-8950/specifications.html [5]:https://www.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/denverton/ns/atom-processor-c3000-series.html [6]:https://www.intel.com/content/www/us/en/products/docs/processors/xeon/3rd-gen-xeon-scalable-processors-brief.html qatengine-1.9.0/docs/images/000077500000000000000000000000001500416242000156635ustar00rootroot00000000000000qatengine-1.9.0/docs/images/async.png000066400000000000000000000535401500416242000175150ustar00rootroot00000000000000‰PNG  IHDR[{óæŒsRGB®ĪégAMA± üa pHYsĆĆĒoØdVõIDATx^ķ½ \Ū}ąoŅ$M“&Ķ&M²ŪޤÉv“’’MŗiÓ6Łn¶ŪŚt’ķæé¦Ż>ҤķMrso|}¹6,žB€āa1ĘŒĘ< ƒ™7Y€ę ÄC’IĆ Ś3𑐄‘ųĪ÷s>¶ęhFšįwę«33g~óš @  # ˆ}Ä>Čbd±c„ŁNŠ•K£;ōʤY{ĢåńĪlĄ<ę Šņ¾ģ¬Øålfķ]`ŒšZ­.čŹėµ:zåÆĄg+ģŪĮ Æ·o{mp4A ßF®µõ }#ü×.ż:(ųV§į…Fx¢9“ąx¬°o#W€¾ŻešŚąh‚.@­öł6Bp¬­×!#@2ä #Ą2ä #@2Ā 0ė4ZŒyMaŃ»OŸ,Čx„ćt£į…WmŪŅč-ĢÄ±šŠŒ€OT$ė–Š·¬įŌn‹s…qižÅ4±ŪŠ[•łģˆpVdT;­jŌ@Ø Ō™-«³€ #øć/ŃҰ2·b ™©#ń²F°(»n%] ø•Z1¬q“ r]”Ī­#l„ŗ-'źźÕ«a””aąETVė 3×>X’bĮ˜ėŸ+Š]ė$€›“:“ĖŹ˜^k°Šp‹~]·/wĻ9_ž“2‚c…é6h&0c… ü_šE[TH ĆŹŖžZzęK®lĶ  °Ł…żžż¤[ĒĮhx¬œ“ÆØDn '³a°ŁcĆØ¦—ĢgsĄ²ļÅUČ Qī„7’éĶ÷Xią‹g„_‰MāD„Ę•H“‡näKĮŌ}ķ-žHĻLQ;=ėżŪ źÕly æMŁ‘zI8ĢģŌ^`ž©ć†„D&$°Y/#Pū½#ąOót„•Ļrnm<÷‘zg®)5,4†såj®xpY`Źż}2FęæZ:d‹Ėo½ŸŲ]wzČ ųjb¦,<©Ekaŗ{ēÄjćY9·ų17$ž66Š3‚Ė _¼9F…Ė4tżbāć-’XŖČˆ¾ō^([PÖ5g]‚°õÜŽ;ĄĒ /„u™Ōuq”…ąąĘž©_»’?b¶įSwY¼'[ RŅwņ/¦‹ßI|sLF Ćq Z÷•£f;Շö¶a‘töH}’=Aõƒ„+k¢C‹'[”—1±R}±p|’#-ā“7ӞRįŪ¬ ±4õ B2ŗé…¼Ōµń. z©µ³>/¹ü.e„żķ¤’4˜¾3-4_ ¶všŚŚĶ6Žåü`Lr³)‘U1oŽ_Ąƒ“2ĀÅŌ.źŪˆÅJ»AC+.'ßkn©Ź`%Ō-ōjӑuŸü‚ _ė‡qŌƑ’œ‚Ą’öų`O +›q¬&a\źĶ½ ”8žŹū°Į2ß*ä§ ²¼+?å¶Iƒ¢ń:;ģ‹_6ØI^xvŸn“•Õk<!ąō°øŗ—‹ąøąēĻŻWŽšßÉüõn˜G$FpŻF\vć"Æ ģK^y©>‚”÷VF³gO®7²‘'µ™%Ā·ĪKKKK‰ųŁ¹mvÆy11}×¹v@&!7ķFpl'ó§±aCĀšģ~żŲ-jkĮ…¾y-‹"ćZ~›a’ćʉZ)°ņt+ŚÕµóY7ŗ¤Ć’±EmĒę$1E;±øœž!^w˜ŽŽŪø4ĻŽn\VųŠ»ÓŌrŽKi×ćŚåUŠ 0ˆÓŽNķ2xV˜ 3Ų†÷3ŗAƒ4 ę¼Œ`³ZĄ^`³.T‚¶G½’¼4’›ĶgČ@`FhėqŅ…LūļēĖ˜<Āq Ś ÷•Ū_{ū”džyD’¾yĻž‡!uķ¼÷rŒą=b„.īR‘½’ķ—2¹)ā_LlRŃjR܍x/_Š»W²:ę• āÜvćh1Žś›-‰…Ć”¤\śŽķt¾ÄÅ,Žõk‘Ō֒ZŖ Ż÷šūʕÓ1i+ŗ|!’Ÿ‘‘‘vMųpLļrŌą:gż¼¤0’Ū¤"ČMqF(·eÅļčø@®w¤æRč\QšČūWc£S8”!ń5Ļ1b½ļfthX—Ļg‡†rk§LžuŌńć·.…Ūaåw3Ÿ}NÄą›ņ>›—“˜}%퉬…ĪIįE†°JĒØˆ„Ö/Ń{ˁX‚ߌ©ŚÄ÷cSų qy~=fpˆ†ēŹ9ŚƒĒ†żāŻpvŒĖ²¤nąĘ•_„š©#õz^h‡Ļ‹ŗĢ*čß8t#_īĢ¢Ų*f_ eóӒ#ń»JaÜÕ¶„„ļŸPÄw.±Ŗ”„7#…Že½ŹIIŠåĆ^bśĢvŗ 4»ŗTJŸ'Ą¦r/ƒ/ä'Fó̹.ąĮ‰įÖĮÜp»˜Į O•†qæģ/Ģ 9n#x‡0­/«õŌ+n\_YŁr9/} āå8”ó6Ņ¢SÆnaĪ(ą†5Õņ†‰Y]bł!›]«ņµņ„Q£R­;šƒĄŒą•Ń8tå\7ŒŽ'0Ļe]ĄĮǬj]ĻĶä%`‡0mŖę'śź x±ń¹O˜Ś#Bb[Tók?²’]4FßA;#ėO…±ģģāņņāė܄<ńK…¾Ó1Ā©qRF8Ņ ­ä…‡åöéNFŚ'`„£į¹a‡’JśC FŲ‡4ét‡~Ā)s:F  LŖÅ„5ƒwȁBŌKš—ųń?"ÆĢ7Œ$ˆ€­wųĘŌ`WgÆBcO×FšT²§¢.ɂžpmX’uwöČ5`ļ&¶Ō«ņ‘XŖ2‘Ųr~Xl銓ć¦|«ōFtĢJ¬“ Ӌļg‡óEXF-}ŅŌ&•w_O»-]Æd§»ßōŽä Či÷LŅ"VdV•HŖ»ļÉƍ@źGź+š:;¤ÅH-fyil\~cWgKēÄĘųžėõŃāøÄāĒu¶pЈ‰xo†\«x"ŖĶˆHlœ”7ņ/^Ōvρ@,UŤ“1»;±ü ĪnlģŃŻ‡ā©­Å†Ś~‹Ķ:$dÉéYhPƒƒ yē,EOciFttĮ Õ;p4ŽG s=õ„E¼ĖœG«£…Qy:µ+>ęśśę„°k·‹‹og\*›ĘDüčūJ`b¹&Žß¦W?d§uŠ:ą·Y9L~Ų}#ĢöµÖß*ŗ!ŗW&ŃXwXŁżō,4ØĮA P€œŗp+½Ćć²Vžī>i:Ōøō»pDkŽlę&6Ŗ%‘Oé||ŅåõT;»GŽ?p*ż.0Bhńsšiųó’HAļŽ¦žĆ9wCĢ•G¦u1‚p¼4cĒÉš­¬RfĀjpƒ §}AÕ*`'fós’c¹÷'Lī“˜U"|÷b,Ÿ"½fĢ5æ;±P›É»žĘ‹ŽÉé^[jĖ`Ť …9eż.Æ7—;²cŲéB”@Ų¼@`¢”·/'¦åę&Gr*G;œsOĀ)`=‚č2ūc܌ą©iHą6o2SvPƒƒ yG 6Ó®o9žå`ņPĄ|[†żŁØÅ“LZ~×פհ¹iŸ„²ėVLŚ ½Åk¾~c_vü½™Ćæ˜Xkä„“P­Ż58ČA Wa„£ĖkŅķ½@źõf¦Ö,Ҋā_Ļ+$V%b¹–™p§|d½zh¼«gĪća@ØĮA P€Ąk„WĖŗ’µØĻŠkV.i÷µ€ä ČÉafķvyß½³„S,čJŌ£Å×B{Ałą•ŽļßR4+“$¹‡ä ČÉ!££šŽ©ĪFłR’$®įĒØĮĮ 2B€œ¬źd÷žæüč,nz³|:čŹßÜR¼ī¢ƒ’ž;^>²Ž;łEŌą`!@Šy„CłSį8Į'£BĢMؙĢöØĮA P€ #x§F¶łū²[żk;VĒp%;ØĮA P€ #xgEļ:>jŌą (@ü58ČA d’@ rP€Į?Pƒƒ AFšŌą (@ü58ČA d’@ rP€Į?Pƒƒ AFšąnp˜Ī‘E‚r`Ē­ĮK ¼ˆ‚{J7÷<ó›Ņ’“r9•“‰Ō źväe1‰ÕÓŌ°'b®6«œZ›kĶćrø|>—›ß”¦j¼ā™TžŽfĄŠ„"÷d/ ’J!£vr`ǵĮįÓ÷xi×āSŪ“¤gŚy ‹ŗÄÄZ%aQ”r²»u¤U"¼ōNUcĆ'KŁł`iE ‹S§“$×Ī vvöŽ-›LūIåŻņÓS©ēW—dO‡'=³ĪŪ!¶ęgØ õ¤Q5ŚÓÕ3Ŗ2‚U£ŒP-w¤«§fCF€dŲqipÖ±"޽©Õ¦dnćį™gŽf.`§W•§š›VA…U’ϾŻV™ÄoQ[ķF *XÉ­zū¬žŹźxöķvqkm»\­`’ŹĻ¬¹ę§{7ļ'”‚ŖNŁ”c&ė< ŻŲ™ø_ŲÜŃR”Ą.ĒØtõļ;ŅÕ?Z«…Œ9Ȱ³ßą°Įė,AÓ°¤« "ŗšŹļ™vžŌ÷ ~~„ŒNäH”tŅ4YĘÉl(¦Œ0SĮowf†vƒŌöęÅrr+žŒīįH*~ƒÄDüØŹEźk3øb7Ā’ģK8Lõ(pYATlŪ=]½z`ĒŁą bA¬ ŗPW]6Mx¤ÆˆÅŹØ“N:#mÜf’ŻŠ‹Ļū¬$/0ĻnOz¤œ Į?‚·Įß’’q9}ĄTy RkłNΐ‚°{•© *Į?‚“Įé°ŻÉ5ę‘®x u—ĢėQļķå2B€ #ųjpƒ ČžqŽ8Äż f"@Fd’8W īŁ²é‘—jē™é`!@üć\58Ė.ł1V’—“$Ģt0€Œ ČžqŽÜnO¾Ś;¾źż¶mAFd’8o .ÆG ŒP4°ĘLC2B€ #ųĒykp£+¦„ĒKR•=—d0€Œ Čžä 2‚@ÓąHķŒ|‘J§z8G˜r`ēH ĪŖQōuŠ%ó[ŪĖ3K†ż]ҬžYŠ6‹ZŽŻŃ=”^W*·R«\TÆ*ś»‡ę锭„nnØ«³ŹøŒk§:ÅĆs`j’^\XU>K”FS•ű »g¶¾ń|›L…Łlųśģģ:•5m}fjĮ9 õ©‡€Œ9Ȱs„g•²3źŗ:5ŒÖ$f÷Yˆ…:æq ד¤g¶Æ+›x1‚ZQŪ]~Č„|©eåAōNqc{cīUv­W·gÄ^«jļ|Ü:<֚ĘĪ~ŲŃV–uSŠ+µŃļ°ļ4‰jųį9ż+c÷bC8·‡UŹ–Ģä›M­A‡_māg“Ī ń 糬0ėå ߬Äļ^{v=Ønp@Fd’8BƒĆgj’āU}J“ĶüTŚ¢ź»sĻ/šŖ¼V,7MŻĖ飮åŪų‰Ų@.»|ŽJv6W—Ż£øĒĪź±ŸÅƧĖā²{©-}Łqó;¹1„SøX­MŹźŁŃµņłmz0ׯ+"Sų|~l»FEŲ0鍊‹©MJÜF2³ųÄw€nö­½ŚĖjtĶ ;Č‚ŒąGkp„q±]•?‚)J3r„yµ3ƅ‚lan³š°^.”2°b’¼č›2³²*ŠK=µŌ¶§rję$łŃ·ĘģÉŠp鍘¢qź`¶œ!Ö/U'd÷™AdP˜xŃń Mž¹ø”‡÷Ń÷M Č‚Œą/lp¤aؔŸ!¦Ä¦5«šĶ&Ī;‚=±\s1_~ńImON+M˜—Ėy?±yĖŌ“y9"95W˜Ē)‘źIlü›•œ+Ģ-ėU—ĒG§s’bÆ5/ąęŽģ„š%ĀFŠf ękĀŲeƒI^‘ĶĖĶĖĪ}(×H‹Sņŗ×-Ó剹½zÜ1‹ÆS‹>ō/eÓ ƒÜ¦b¦ƒd„AFšĆœvg·w~›™ LŚMƒõŠ=7éōo71WĮš1ŻŗsĢNZ [Z:”3iÖ­o¹?ŗÕ ¤Eæ±É| æųŠs öNÕ,lɔĮ?<ÜŽŽŽŅš“Š™±ś%K~ćĮå5„āuŸ×O–ƒ Ž|j4Č‚ŒąĪg²…żkæ—.]kP~V9CĻ\8“aÄėĒ·ž’BÅ?•N1ļ'Č‚Œą ĮU |ū½sŸˆd2ƒ^Æ9ž¶²¬³|•7ā,}ūl\tÖ-ķSūJ”ōƒ¢fē¶ü‘`t—ān2B€ #ųhp7ŗ¾÷%Ļ?Fe(„˧cµ;LZ„Öņ©čgÉģŚšn͜³žsqCLķ+]„PTCݟēĖ£-ö-ø>).(AFd’p68Š)HnS}1QBKįņĆ`J+āä čl€Œ; Ž ÷MlżÕMŇĆūŽR›B2ä #ĄĪa nqĖÜ6„c&‚dČAF€Ōą (@ü58ČA d’@ rP€Į?Pƒƒ AFšŌą (@ü58ČA d’@ rP€Į?Pƒƒ AFš—jpø¼ŒÅį%sS DJ«Šōqć¹üT~Jęƒ {†"b©Q0ąū~jl H(ŅēĶÓ(@ƒŒ;/Õą¬’|¶=Į6z3\Š‹)«¢¹uŌžMāø=Õ >}—v->µM{`ǵ3ƒ½cĖ&’ŲšŸŃX@ÕÖō@§H< ‘NŖM[ źy·č阼å'(@ƒŒ;/k„Ų¢Q½acŗ‘]<›¤E¬Č¬*‘TI'd·YNJx÷¦V›’¹kī)“eu<ūv»øµ¶]a¢Tvz{PČvŒµe‡Å?˜ßń~š]ŻŽVŹaÉżĶ¤„9Ȱó’F†„&„D¼u1K¼BēQ°h=„ŃŃƒ:¼Ī4 Kŗ "¢«•nJ µ½y±œÜŠ'c«Ķn„mĒ5NåœÉ4u#č6a"~LÕa#7%ņŪüĶā„9Ȱó²}źØA?œ›Ń©{Ęź’*oDеā|X(@ü58HؑmvLė™  ē-i‡fŒcqxFayY”ͽ=¢g²`z|¦É-æ¾Éf‚jf5ŻAF€dČ9<@ųÄmVĪ€•2‚kB{ķŲ-–p˜ŗ¾ˆĖ ¢ dŪīéī=†ŖķF°ø/#yę>Fń+.‚ßB:`Œąś™Ūz·üśŌŃĢVv?½øČ°ƒŒ9>śså‘i]˜s7eŅWė¦Ė¢3ÄŌa<֗S2iOļ|—2‚ėŠĀĶ6>§Qcq_f|ÜcŒbe_u ·RaŚ7‚ėgnoøå×-½Įŗ!„÷v ĒG€°AtŁ4īa#”īĢć„;·Ósp!ŒėZˆ+ŹbXecĖx£øŁw=6C4OOxaĖ-æ>IjŲė»„—ŌŅȰƒŒ9¾dģĖŽæ7ćmŲ!i5h ÖCÆ &ķś”…Ėx£čüś;k¼”ĘÕŻ?¹>Ū¬\ŅŅ˜`r|ˆX•ˆåÆfĄ¢ łõ±™ž¾y G[ƅö~šJļ÷o)šZ’¤ŗ ȰƒŒ9ļV¾÷/%¬« ĮX¾”$”3G‚^óŪUņå;ČPƒŒ9g,YöwržŌ Ę-@żoŪŗPŁžb>ŹČžŒ9Å=rSügŻsŪAWDÓŗ’?L‹ą“Qļ=˜“«w¼čž§m·=ųĀĖ”Ŗ_·Ż}ͦéa>ŹČžŒ9Į ”vpĮļgČ ū×Lę„w#ōżŒyķ/Ŗd„cr‚4@:l÷RķüŅs,32ģ #@ĪŁ2T #@2‚/ŽdČAFš2±ƒŒ9Ⱦ@F8v ĮČĒ2ä #ųįŲAF€d_ #;ȐƒŒą d„cē|XjąE Ųsš¾"n<—ŸŹOÉ|0±)-I+—SILIż@” naG^“X=M%"ęj³Ź©E°¹Ö<.‡Ėēs¹łjŖęäAFš2±s®Œ€Oßć„]‹OmӒöžrėØ;‰Iǁ,źk•„EQŹÉī֑V‰šŅ;!T Ÿ,eēS¹ĀJXœ:„=ŁAx$°ē"uyh»ė³ŲńŁ™u|iyf ĢėņČvPéöPöƒ #ųįŲ9OF°ŽńīM­6%s×›IZĊ̪I•zzļ.`§W•§š›VA…U’ϾŻV™ÄoQ[ķF *XÉ­zū¬”šŗ<+]ėņ,vL’89©i‹¤ĢĀ)*r>²]ane÷2‚/Žsdlš:KŠ4,é*ˆˆ®¦rŚ,EOciFttĮ ÕY õ½‚Ÿ_)£“QF(4M–q2ŪŠ)#Ģ”EšŪ=ŸuģĄ#”©ŽåYģ­›\ŁŽ¹>”ł(w|Œpģœ#ĂXAu ® .ŗlšĄ­t>2\VĄŹ”^‹•Qit÷6n3ÉnÅE„‡ē^’ž!>$c‘{BSń€ė3ŪõOxœz iĆrĀoŲēfŁ^61įśPvū[ž #ųįŲ9/F 7[SSš˜§™r£ EMvb†0?'9–{Āž`$oF Ī4ę¾ó–T‘[CÅ ŃIŁły™ÉYM‹öŁø?+ŻčöĢvŖ)…•˜››Ę G ĪG¶‹4øŪCٽŒą d„cēüōtŖ?Øģ¢[&ŗ«pD“ÖńøuWģŁ‰]Ÿ•īž,vŅ¢ßŅ›½—G¶ÜŹī 2‚/Žó`Ė.ywxżļīLĢW—פóRÆ7+$'ōŠvd_ #;g»ĮĶn˜Ćė>;ųZhļA ]\ #ųįŲ9“ ne«ØvtóĻóåt’?P¾”$¹ÕÆ.X ŗ[’ćäęæg6/ųAF€³g„ŗįĻ|ćZ»Óg |6¶žŁ¼ąvĪday«čĮčęŸåķ÷>p„—Õ°p«-čJLżæ$7’³yĮ2ģœķĆŌéu,¬~įcWūb<® č<‚/Ž³ßąl63N^ļ^ż»;“FGŽš ĮČĒĪy0‚“ć‚d_ #;ēŹ& QõlćéÜ63 #ųįŲ9WF[1½Śū··'™é`ĮČĒι2ąKI’³ś-»'0ŗšd@Fš2±sތš~ķ<č&<žŌ2ÓŠƒŒą d„cē¼”dHŒp£÷”r¢2‚/Žófƒ™XÜ2cÖ ¹ ‰Œą d„cē¼!č@Fš2±ƒŒ9Ⱦ@F8vĪ›FTƽ½`§„Œą d„cē\avĆü+½’Püœ™|Œpģœ+#\؞}-ŲR§ #ųįŲ9?FĻź_ķżķä‘ ž@Fš2±s~ŒšÓŠpČŠT75|ŒpģxmpF QЧ. ¾Ä„>“··×3d: #ųįŲńhp櫦wkę~5²’×cuŲ.Sœw–ö)](YwÖG4ģ?¤ģ.BØFZŗ<Ļ5Xp Fņ 2‚/Ž×§ŌZb›•Ÿg)|;k4w§³ 32ģlp8AVĖ6¾›'æ'YgŖ‚dČAF€ ĪĻG¤B2ä #ĄĪŁopAĪ97©“7f$słŁÅ'õ›"#;Ȑs¾`‘äÅd‹f4ZĶL—0.§×sl 2±ƒŒ9ēŪXwnv'­«ōff£Ę£—€Œpģ #@Īł6±ŚœŹĪÆØ©ŗĆ ćß­}Xß;ofŽ #;ȐsĪ°©č¹Ń)UķgEF8~ ē|8A;ŃVqėFaY“tķąµ/d„crĪya”&™{·K61Ö[ĶēĖ™j'ČĒ2äœo#˜Ś3²ŗ-ö—øģVĘCū+ŽdČA}ni§t\ÖSŏG}„SrĪ·ØóŠöū·o•·Č4č<Ā)€Œ9ēŻ¾Ē¤v¬µ¶¾±ypay”“,÷÷ĶøXŒP=­®¬ohģRLŠkī×?lčYÄTŻŽW²–ŚŗŗŚfé:—l„fąéø‰4ĢŽĶčIĖó¾Į5ÓÄ£Z‰ž)®/ÄŅ@ßśX[CEIIUc÷Œ‰^Ģf33³9Vn@.m„ŖOÜķXp|ž†“©¦®”ih ,ƒŒ9Ⱦ€Ē–ĮŅ‚NµŁfs¾°įŠū•ƒ.—JqEe™xÓ`4[5UĆÓÓ»•ćcĢ«{u%wś 6›i ųī€Ģńö$ć«“¢B²Õ]Ź.źÜ”×ÖH7ūܽSŽŗF€ĢąßķZ«®³YśŹ+. 28fs®©ŖØģxRQ7!Ū_Š:Rv§×™ŠrĪ»‚ęź#iZ’“ÕUön˜¹§Źsļ<é蟣”—g]ņ…‹‚y„ģ*¹7¶^QŅ>āxŪłtRlš~EeCKCuuĶƁ•6aź²“k5JŹ-=ŅŚņ’;@n9g#œ+·E؛2„½ÜeAL\R¾æ2äœo#ĻÕGĖģÓŗ¦Öŗ¢²öa1żB¼*æ'ČŲšh`‘Ö>aŸnģ’UW ›ę7>§ŗŌ«†g½•…•MM•…ėr¦²q–9l?÷āė‰53ęéźDaēģćū­jß•=˜“÷1 Ʊ7ĮLnF Ōū³M>Ūžē»S ļ»RGżä¬F-…Īärq4^jɗ’:;Ȑs¾œ$W·Ķ»¹OW'õŖō3±ƒó›Ų¦ 7Óæ¼vŒŌŠÅ5Iī9ėAyµ‹“}fĪ·š©śŠ­½éš„÷«Fķ•.Ą`„ŗįĻüØ“éc¬~Ś…ß¾ŸVüĒeSĪś_ŽŲO+>»į–VüÕ.ņįšNd˜9ĒFĄ'¤E^xė2‡ąF_fWĻ1ļ8¤Š4~ļßīMƒŻĻ¹_½‘0üׅ PŒn2³Śl™]+t%(’ūĪžŹÕŪVg=(Æv‘’77fĪsĮbŠ Ü-hšŃ¬ollé1/'Ę :ŗč+_į#|ąJÆÄń€ƒąG€œs~!ųņ,īķķµO顏óŸ\gŖ‚ dČ9ßFę<‹«ŪÖmsš=:rĪ·PžÅSrĪ·PžÅSrĪ·š„į'OØxNPžÅrĪya±%‹ŸVŌ8¤4xƒ‹Œpģ #@Īł6‚ėʤøZČa±³+:'7Ż."#;ȐsŽ€ėfūź Ó8œ“Āz±ø>›-m0oŽdČ9ßFĄUײīµĖ5ĢŁDR;Ö-CF8I ē|4Œ¾nįCFxypŻŅ”Rė8;ƒuū_rĪ·LY‚.gŚĄƒ@dbµėF‡ĒOåóK“øŪi)ĪjZö‘Ÿą ¤I)Ÿ”oņ:H}wv$ļn÷"sZ†˜«ąŽ”RȐs¾@,?ā†%VÖ>4 P™AŻ€ĒÄly\v/FÕį8ī>e³Yz³Ų• ތ`Y›čuō IĒ•ģØ qך‚4©Ä¹,Ž™Ņmč¶eMŃף%ļƒ ėśd_§xhfC«šQŁk,k³‹Ź%õ¢D,QšØ:Bæ(ķīźSh\śZ¤i©3›•ņ`d^Kā›ÓƒānŁ@)2BppĪąśÜĒĪ15Sķ#†Į<» ”w’:ēį>uØĄ/uNŅ>łP;ź–L·-)d§U¶µŽį^kz.Ą½ß$uɄDj‡ėļ?īj+ā¤=Öą³nyGGcÓŠÜÓl^­Š°ÄŁéͳßb4Šź3Y™Om˜¬(6©¤µ«ķ‰DķśAcÕI—b ꇦ„‘Üņ¶¶JžÅ‹łČĮĄ¹5”yRX>īL4HØź®—O2N :@š–e¢š‚ÄØō¶Ā}ź0#l¶¦§5­bė¢ ~݊Yš•}»øų',g€XØäŽa:õ ¤~Ŗ³ö^qnltń„EәĖ-Øķ™7˜äæzqS”•ݱ„}œĢmё6됐[Ėnʗ82:»BĢ”s e8.-`S©ńɒųd„`ąÜĮ: Ģx Z¶\V˜QǼv‘HūįŲ×VjŁ×ŗLnSŲ!F Ōm×ÓņJKŹ%j« Ÿ(N(”aŌAAÄb7_āvZģä‰÷ž°ńŪ‰ÅTāf®ė¾+č6įņāŌ‚¢ aƑŌ?ꄉĄńŠu([…ĖoĒŻqju‡äE±7¤ą}ĖH> !(8·FĄ%ÉÅrgc&×[ųmĢ„ˆĪ#(›2ŲÉYBa:;¾p`cĮuJKZz3ß¹ÄįŅJū¶œš#ÖZų,Ž¢¢Āā‡Ņ W6§Å$fēåfŻ—™@‡’NL¤ ÅÅ#ÄLUBLŚuA;’[7;[/HÉf°+§pšÖ½°_‡1Šp5‚ _lā³āy¹7[Ż„ÄĮ†Ļj7‚³|…7Āi®m~ö«ČŠr֌p«÷žœŠ/'u‚Ęw6Ź8Õæ!rN^mX`6Õf+čS;ėAæÉĢ6Ūļ¤>sÖæĀE>=ąj„oeętU‹Ę>ŒŒ-čØv‚·Įͬc§äœÕ’NÕģ³ejų; ä #ĄNš6øæ.T|=ķY~ÆŚąņ„K Č9kFŠ™ŚyĶßљDĢt{{ «ų÷zŒ×ē½p iƒÓa»} Ō…\ 笺©Ģ«ĄŲŚ}­VŹ7ķC^gæĮ9Ⱦv# ü˰iĪ1ꈭĄī*­zÜs˜Ķi‚Œ9Ⱦj#dĶXčNwr’Ū+r|ńŹ°cQü]a(ų—™~³F"uŠŁ’wČæī3¶¬į{{n‚]rÆjŁŗŒł’|r #@2‚/^¹üjp!²×ķ‚žM_O»µ@õb'¼ Ū>y ĮšaÓBvo0ū’õ9ĖvJ”V įėLqwļ ŗĻ5é­īŪ9 Į0ÜŪ{S²óĖuŗĻ7éqū¾ķqtąƒü9KķŠ•8ņüĒ2ä #ųB#˜‰½uĒŻĢßė1~łńvŚ”óŁ)€ dČAFšÅ+7NlżvRń.”ÆĮĀÕqģӏō’&aŅG5€žżś%ŠZIõ~ā‚Sr|ńŹx-“—ŽķĮüŃ:ŻækŌĒĒIA©n|ŚŪŅfś“@F€d_¼Z#¤O›_»§ĒütMĻę.8j _ŪP©¶ \&ööŽhѬ^wŹ– ĮÆÖUĖVjˆQĶÖµé—bDX͚ĀŲšXNä»ļ&ŌĶx~ŠĶ›’ÕÓ=p@F€d_œ²,Ä^©Ņś§Oōļö.¹—0Ö[>üÅuż=z†#Aā85j™Ō‰ųļü4Ŗxˆ€Ō>ĶøĄnšķt@F€d_œ²ĄQ=č¼^«s&ų׹H­“œw5,üJH(ÆF®7ōg½Ķn\·wpYžE^ū!·8õ0ÆNdČAFšÅIaooļńžčøļ`H»{e ›1ś¼żŽāńšZ¦KĄsCł¢u0eš,‹x/_ŗ=q;”U9c3韦‡śœ‘ÜĘ÷¾×cüAæg_3ȐƒŒą‹“6Āķ2€NĮjuŹļó¶Ē:Vx‰Ó¤±;Ą£K°«©g‡•ĶŠoéZ¹—Šä„²śźß KąD‡Eå“/ŁśāÉ×Ū·?xų ;ȐƒŒą‹“0‚T·ŪµĪŒ;ę(Ģ?6õ~ĀĮŒ)Ä̽šˆņ9°ßčąS„”@TG€X­cGV.ŚČĶ'Éļ_ļ×{uMĮ¼åsMś6YŽdČAFšÅńaÓB~ŪŽ)ųZū6Su<ļ†&Ōģ÷ dfņ@—ČŹ¢CĀy™ü˜0ö]©ż±Ļ¦ģ¾ČĒcį­ä(FœŌłx ĖńŒ9Ⱦ8#€ł†cÜńļ“mƒćöśUĻ;”}šzH•dr’ÉmŌ9ńµ‹×Äz‹g—Ąž.aŅĢĻ,i÷Ū„/ō‹Ę]—÷@ļ]Å>Ł ‹WœĘݐȐƒŒą‹0i ž¦ßŽŅc£ wvż>«’śÅ“ˆĖi·ó öŃh–Żx?¾Q{t ˜w¹·Gß:ąØį×éÆM™}D Į/gƒcąŒ‘x½V÷_D† •÷G&ś‚ĶŌėė;c{õŸńo?Š«™3ī’Ī ÷Y97ŸLYt ^ 8xIynžb‹^čHĮ:Ŗ'NķĪhdČAFš…æFooKw>VÆŅ2' A żĀ«YŻs#&<źźÅ·ćbėF_›}|1$]l?-ą_ļī{¾ń2§»7ج­Ó%½ŠlkȐƒŒą 9c;Ū-ś†Õ—>uO5|ū'qå3V¹U›ōÆ1ÕZ[K-øü—‹ŒŲ+Z°üA‡aŃq‰LjOå<āA Į~”k÷;b[v@æ{ąä¦¤,™ŹŹh™ßźĻś93ÖPŁ}éē‘_RlŻZnJ¼p1"RŠśZˆ–cō؇;‹ÆņI 4ȐƒŒą æŒšŌŽ’ۿƒ™Wdć*ĀŌ—}%£k µāk8MŖ±¢Ė±µĖ`ß_ŪLēæ÷'·Ē Įq‚^­ö5®ĄroÆq‘1w:Ļ›ˆ«ćŲ‚#Gū«r|įļQĆ׌·æŲ¢÷ć†eb®<"µsGż06LP^˜ĮKĶ«z:£Ć eUä•Ņ)܆’Wt¦Ņ°ÉĢ4ž¢ĒÜŹ3Æ¬ÆdČAFš…æFæĆG¹kČ:S”P!7’6b©*šßn§J/ż<]¼IżŠ›fžŠ§ [źĘģēų¼†!ķnŻ Ó…(˜·¼)ŁvœŻ„ dČq ЦÄfR1ƃ“Wl_ø*ŠĻ7rCėf1u]<ÆÕ`mĪMćE‡ÅŽčv=YšB#`ÄŽtPC!’½#+Ģ #@Ž[€žēR;@å'l-ß²õżŌ6‘n[i±™”Ģ»ĮĄ«7Ā6¾'˜17©=ų=N¬ŲL]Rxźƒb·Eg?ķO˜4‹óĖNf„yį¼všēŻĘæģ5‚/=śPČW2äøˆÄmu’‰ŚN½=ā媟Hv>Z§«w |‚äRāK€Œ9^¤év³<æĪĢpҰ$ėīģ‘k,¤Q5„“Ÿ#'õŹée“Ė[6bkaA½"ļ=S[lŲr~Xl銓óĪ|°ģhOWĻØŠĮļ>3ƒI՛w%öīŠ¤#t³ƒ“mŁń°įp9Up{{{ōöä?oŽßz¼]½| Ē{€:’ĘĶtiūsę]O°±āøÄāĒu¶pŠŲ—Ķ.›ĘmÄ|E’ppÓõ-LÄūihvu{[)‡U4¶”hä_¼"Øķž£,wćā ›;ZŠŲ„ć˜ŪĢrz"µņ:ŽÅ°ģŚĪŃŽB»Ø„£©0ę­«paĘHVČ̌‰3b!4Ā6¾õæņdūåNž’ó t >ÕØļŻÜ=āx„`r P’Ūn: Ė•Ć|ŖŒŻ£ĒAõ÷g+øĀ²<~å<įž&Jeׁćgr«) ģ䤦žĆ9ĘüāÓeŃbjĻĒś²cJ&·Żg¦gra²˜•ńT’ŚÖäh8ūō^żähŁŹtV2sĘģw,Õķ-Xč§9"#ĄĢ92¦¶•ĢM t’y× bµ#;†. „Ķ ŌōJ]ܛģzźÜ™Ū[F°į“ģpĪ= }”ŽPwęĘqB‡Ū©&ōŁÉŽEńw…”ą_fŚĪčŠéU³’-gŒ žaN ĒK€Ęø¶ĮwmSłŌ€ÅŹOø”Õvf6(ŃKŸ/˜ˆ_Du ¾!:ä™*\·ĒŒ“%Cšog‚^(āY’ŅØA2äx nĀVöKnp-C!ĢlPāŻ¢æ“©E/S€Į&b„ļˆ `ē·ąČ`ļ‰w>żŪ]†K£;S†tūéķé›-½R7’é˜AŚ üV’ä'3 4MP’§)ģ_£+Ayūž,Sk³­qg=(Æv‘’U˜ąlpP­ŲĖ-ālpg`[čJ`„Öђ쬅Zģö®p-¾–‚vó½Įcü-įņ(•­ä­‘Æ<Ł/Ų~ę;žS_ŖžĢ_äß’„0Ę%„}’Ö“—M9ė?ŽĒŌŚl³fg=(Æv‘…u9ÕнÜ"Īw¶…®FØž¦³j‹Ö׎“õ ŚĶ÷b„µ.Ūź“€ŠÕW÷üF˜6_oßęO™?R§ūē!“3’āYŁŹŪ³²u}Eoå<^ś Ī0½ĶŸcIUĘɵ×3)«ŪVPC—);zp‚tփņj©ś§ Z±—[ÄŁąĪĄ¶Š•Ą}“æå¬…YäłuO8Ėh“›ļÅ'ĢQĻ,¾ÜóQ<¶‡ ÷Žm~/_žzho\s0Ż”źG€œCD¶†ßńt]š~™>ą5ĀĖqŲö€ī»E©Ē`̉ādČń Õv7T||„±ßõtLœ#/Čó‚¹ŽąŠš’Ųööl†YŪRĶ0ĆĢȰƒŒ9/Ų’ļ}Ä!…×m–-¦V`r^ Ö~7a©ž©„dŲAF€œ7ŲŖ?ĻAĪTĀ 2ģ #@Ī‘4{›1Bó15°‚Œ;Ȑs¤ķķŁš¾I”ģC¶]ę†]8AF€dČ9j€Ö{™n‚ZÄŌ@ 2ĀéAšVēW·©{ƒX“ĶØēé${ Ēu’2Ā(‡™„’3nBÓWčēņSł)™&ĢžÓø¼<½jjdēńā‘(W”pņ%¦õį A27)WŠ©²*™Ø­¹¹oĮbšéii©Ź«x^‘x½ßÅȐćG€L*[łÆŲھĖLBÉŁ6”¬Šę>¶?ļ…ÄqüĄ“U’ukĢ«š©Į®Ī^…Ęžŗ•4©dOE]’=įžz?M.śvUŽ#KU&ņ@¢\«ōFtĢj³l¬mS_6«ČfŖØ7ŌŌ >®|“b-/Ā+Łé.OÆ@F€’4š@ [$į;{¶`3I‹X‘YU"©ģ¾§5©©Æhźģ|S µ˜å„±qł]-ćūÆ×G]3čb"Ž›!×*žˆj3"-m¹'Ź%–ŖbRŚ;:i»—Öf³?¬ŸÅdj„ŅEUĶe™%CV됐U$gfDF€’“‹QwCo 2“šqʍ°h=„ŃŃƒöĪė“łŠ>i˜ė©Æ(-ā]ę0Ū–Kś[j)-óØ8××ūirķɰWLŚ ż|°vŒ}Łń÷fż^Ė®})b­‘—ҢْdČA S7ĀŃĄå5éöĪ õz3SėiEqĻįO­;ūŖD,ßOtēĮ­žµŻź™œčé›w>„€ä ¤FxåäŽ×Ņž½Ś žvÆĢĢ™Ōą (@N֝Ļļ^ØųQ죇©¢å +oߟ„³B‚ņqV?˜|¶lB rP€ädŃQķÜ©Ī@łčÕ~ÖĆ7Qƒƒd„9Y#H‹SšæSÜæn|+謕ŗ§ ¾Źt­hwvQƒƒ Aē¼³c%~“3ü”°¾æ/~Ž1½Ÿß58ČA dļöÆqŸØŌŪ.£"ģ 9(@‚ŒąØĮA P€ #ųjpƒ Čžä 2‚ 9(@‚ŒąØĮA P€ #ųjpƒ Čžä 2‚wƒĆtŽŪĘP€ vÜ±ŌĄ‹(°ēprĻ+½)-I+—S9ÜHż@” naG^“X=M x"ęj³Ź©E°¹Ö<.‡Ėēs¹łjŖĘ+I¤āml H(rÉė`Ēž3Bķ:'D"µ3ņE£Ū׏0!@üƵĮįÓ÷xi×āSŪ“äĮ<ÓKu‰‰µJĀ¢(ådwėH«DxéŖĘ†O–²óĮҊ§NiI;4®ģģģ[6™ö“H»%¤¦rMÆ.ɞOzd™¦!¶ęgØ”Ō¤Q5ŚÓÕ3Ŗ¢ö$ŹÕrg~jĄŃdÕ(ś:ŒynZžY2ģļ“fõĢ‚–°ØåŻŻźu„r‹ µŹEõŖ¢æ{hžNÆKč憺:ūģkk§:ÅĆsZźR»ø°Ŗ}*–($¦+‹cvĻl¹6žƒÆ“©0¾>;»6 _Ÿ™ZXtĢįń·r!@üĆ„ĮYNJx÷¦V›’¹kā<Ó6ąvzUy æiTX%łģŪm•IüµÕnb”‚•ÜŗƄ+„²:ž}»]ÜZŪ.W;’HϬ¹&¤{7ļ'”‚ŖNŁ”{–iŗ;°3q7.¾°¹£„(]:ŽQł©ßwę§^«u”Ye…ģŒŗ®ĪGĶCź„ŚÄģ> ±PĒć7.įš–ōĢ'ć¼A­Øķ.?äR¾Ō²ņ ś§ø±½1÷*»V‰«Ū3bÆUµw>nQ/µ¦±³v“•%EŻ”bÄJmō;ģ;M¢~xN’ŹŲ½ŲĪķĘa•Ŗ%3łfSgkGŠA¬6ń3Zē†Šų…ƒó2fŽd„“Į?ö6x%h–tDDWSIŸ=óL“ś^ĮĻÆ”Ń™Ū(#”Nš&Ė8™ķŔfŹ"ųķŽL°īŚŽ¼XNnœ1šĆźL"횐zƒÄDüØŹEźkݳL3Ų°$»ÅS= \VU ŪöČO}“į35Iq‚Ŗ>%XYóSAj‹ŖļĪu>æ`hŖņZ±L~7.§Ś c?±qČe—ĻQ_1W—Ż£øĒĪźa2ćN—Åe÷RsZś²ć*ęwrcJ§@ojµ6)«gG׏ē·éĮ\wÆ\ˆLįół±!ģ°Ņ”S›”ødęxČ‚ŒąĪg bÕ €ŗ‚øč²iĀ3Ļ4Ų)+£Ņ:éœl“p›Iv+."<<“uI^x†ųмo„A%­āʕMY˜$Ņn ©)#8Ī øg™f°æ­z^!¦vH¬/;¦dĮ-?õ‘DŪQ`«pEiFŽ0ÆvføP-ĢmV/F—€ķ¢6'ś¦Ģ¬¬ŠāR=RŪžŹ©™“äG;²kƒõ)§¾|¶œ!Ö/U'd÷U° ļ/šĒŠ©æµ•% 3“Q_åņāćRźUą`‹™ć #2‚0 ŽÜlMMibĪܙr£ EMny„©zoF Ī4ę¾ó–T‘[CÅ ŃIŁły™ÉYM‹öŁhˆ…ĘLn¦071:S¤!˜$ŅC® ©7LN#xd™¦”…«;sć8”€ĆĪķT _q!Œė’Ÿś" C„ü ”0%6­YE›Mœw=zŠÉˆ¹˜/1=æ''Œ•&ĢĖ弟ؼeźÉ¼‘œš+L‹ć”Hõ$6~ĶJĪę–õn˜äåńŃ)œ¤ŲkĶ ø¹7;”f‰°“ˆłŚ„0v™Ä`’W$Dóró²sk‡‹Sņŗ×-Ó剹½zÜ1Ēa„AFd’šŁąŽ˜Wڤլģ§Ż 0ŻĮz„Ō¾0‰ųœz»±H«Ak°īļFąםł© °Č¦ėGx€›ōFz­ˆ¹ ŽpЌéÖu˜cvšż[ZęBšuądטH‹~c“łDæAFd’8©ē‘|zöE{ĶÜ> «ąn’ĖCuuŲīæŻ›nVhIr©²sĢ+Q*^?T§2B€ #ųGš6øœ§«Æ…ö~)IĀoW­;~Q€ vrDy­õƒ¢<Ż|#a˜Nłįš¾–N=Ū¦Ō0ZīœM4­c6ÕfŪ0āĪzP–uūO®č™ßvÖCµČMńw3Ū¾?¤40Ļą r`ē³± ōNu6Ź73Śź†?óG‚6gĶWx#̦Śl`'tփR>²Ī¼a³}'gĢYÕ"’%ķ]ł”°¾?ĖŪØw‚Œ;¬‡o¾w’]';K‡ νč÷Ņe…żksš" üī*ē< ’ŁT›M©µ8ėAQ¬ķ0oŲl`'tÖCµHRÓ?¼[łŽ/Ŗfæ™!ūž-S“ #ĄNš¦Ž¶DšŃ«ż?©˜jŗņüH¶l‰ą;Ž@F€ 5f%žāĘD–xE‡ķ2UvĪI€†—Œcõƒ.CŠIv‚ŌÖCN³“ķX‰’q}t‘.?œgŖ‚dŲ R#Ęł ÉBüvņČ딽āŁŽČ°ƒŒ9>Ō3æżÉ؁Jé3 #Ą2äųжŁķ4 ü #Ą2ä 2‚ 9(@‚ŒąØĮAĪ $ģ^å>Q1ЃŒ;ȐóĀ}-ķŁĒYżĢō #Ą2ä¼0@_į|:f™€dŲAF€ß¬ÄGĀū~÷Ś3fz`r|hpŃš”°¾Šą¹ˆŒ;ȐóĀ-„3aĢŃĮˆ½¢ĖßzOž}r #Ą2äx vg×`ö;Q+śŌųZ­õD™Óv ē`€ę7ĶßH—ķ{~ŻųHīķ5®āw™ģL•*ė…g;÷–¬V÷D•' 2ģ #@ŽG€ ŸśVÖ(«qń{łņė‘z fbļ·[·AąÓōāTą2ģ #@Žk€jG7?zµ’µŠŽofŹĄæ’‘+QoL„æĻąÖ®b›QĘ?š~"Ł‘h=ļƒ0īī Ø<9`rœŹģZłĄ&…(æĮ‡ō<yn ž Ć:’äóÜ!8”x£E’¹&ż©; #Ą2ä€ L}!äĮœÓtIö6ryŽDŠū¶ßūdƒī/{×^pāš}ŁGł’ƾĘ1‚Œ;Ȑō~Õ/¾–öģ„įOD¼ī"…Ėē°Õkü€Ė¾­;ü”U®€Ž8 źNéĄį¬a}»ģ?Ū÷™éąG6’‡²ł?b&‚Ÿ³ghwv¶ĢĻ–M3z„ćÉõ«8ų©’f‡”åE‚W‹}śĶÓ܃NÖČ1™GU|“yŒ™>»€_õŸHv>ÕØß“?ó’Ü ōį6ž*ÆAœČˆsĮĻFØć’ßz¼=°u ž Ļv>ѠӟE) # Ī& &‚5ށc~z’7®ā k@OŗCźM7øQģņń£Cp'ĶĄ/Y3ūO—;3 # Ī {öĖ„`§żwś-Ƨ ]%€õg‡pB˜÷^̚™ü|“>sęŠĖ™Į 2⌠µ’`½ēøvP“`¹µ`Įqč&|ņnŲ{ģ̬k)É|a½Üp¤‹„÷īFЃŒ€8 €}ūWź©;‘¾Ž¾ĶT€Ü””%³ĀĆCY-ÓcnŠÖfŸO-ØTƅW86üø’į́Œ€V¬ä^Ł’ÕŁŁ’_ż&ŽsóŗżR‚;8fĄp›©/ūJF×:AjÅ×.pšVŻ%`RŹzŏļńâ˟uōQĆ*žåĪ™2"(y¢Į?ūˆ:S>†1U^ µŅ ^Dx\JÕ莶al˜ ¼0ƒ—šWõtF‡Ū0 ˜µņÖŹŹŗŽŃUŸęÉĶy Xh¹‹Ą2"hŲŪŪ{ŗĮ\;æĢŸ~¤æ<ŠM=O’8ĪTaC×/q[Ōōõ|ŖōŅĻÓśŌ{¦™§āÉ嗐€;»{æÖØ’Ž˜yŠöŁTج_}BŻ”ģ”~ąv#Š%(ē] æŹ«‘ėw5ģ+„SŽ Š¤^VĪMKb]޾ѭ¶nMJ&·č.æß×fŒš”5ŸCČØ”‡ņę,~Øūē!ӄć†eHĢ å‹ÖĮۦɲˆ÷ņ„†©ŅŠK…cö! ¦y™bÓF˜43­‚ų& a#ę+".§ŻĪ/hY0ł}ż‘A¢Żżń°é›† /ē/‚d¤TŖ¬ÜepŽz ŗčļ{aÅVÄĀčäŗ‘:vXٌ}Æ&u­ÜKEr‹NRxå­÷9üä谘‚^ =’̽šˆņ9ĖŌ}ö…7’5®fĪH¾ŌõGŠ˜ t[¾üx[!# 'č„Ó/ž¢‡JmųŻn£ŹŪĪF`*Ֆ…Ś÷Eü·[6m”Ī„ P§ˆÕ:vdå"e\«œšVé]u#ūż™™$ Ż!éb=ų|Ņt“ė³FāŹę°Cu ŽłiTń„¼Ö>ĶøĄnXÅäE”±Wh{&ĶüĢ’Öżƒ0LT%Nća3Ėn¼o7±Ü”xįbD¤ąńó1Ɨ6-dź”Yą°\抗(­ęWš|ńDAF@¼zˆ½½ü9Ė×Ū·×|ŗo³×ķ{<.ĖæČk7ŹŖØ°ż‹ v\®X4MœK…cŌmIŌŁÄˆņ9`‚…ū¬‹œ›O¦ĄĮ†^­v=ØpAk%iO½Ń¢?K‡>@F@@Į׌·?X«[:JWŸøŹŖ¤ī;$õOÓC}˜ÜxP7ęz”ąvć©ń/föPĒž„ŗ.öā ųÅĒ×Ę»ūžoPųżæ³hyęȒtįŁĪµi³÷Ū„Ī"Č(øa’—1}”» eõÕ¾–Ą‰‹Źi_rīÓ>n\Š C8MąpŌ=įżų§iö³‰^čŁÜż“}(䏆NūńM€Œ€€Óī^לQs™›O’ßæŽļŚÕ'Iß7.¬-6°ße ņ3¢co?UL©]ĢCīķµ¬įōx'=¾÷Å}ų6ē’Ų„³2"1 d‡šEZšCļP?·ģėĘ+8XšP»Ÿ8¬Y¶~ł15ņ¾Š¹ĄpNĪ2"–vČü¹#%&ĀśEć[¤Ėh„ƒ7.ųø{ÉyĀ¢vÅś‘:Żæ›Ęōē“Są2"¾g•$ógē܍°ć/:,öF·šžĮƒ •õ; ­Óiķ' ‰½½33łX@F@@ÄĆ+0ĀĻ„Ģ „#au@ GXœ_>x1љņčMÉĪėµŗ’Łcœ=pÓ$€Œ€€°ß²،ūŖ·ŃöööÆįŻg  kLrAĻĮŃNprļóMŌÕÄßļ0–sį 2F$ŚŻ—>ē/ÕķžldēÖs†ņĮ²µ’8žŃpN@F@@}‹qėK=ķ™n, Ź÷‡ æ@F@@Gļ&µWæļØ»“r‡Œ’cĪ›/<Ū©_ŝ§~Œ€€‘’=`Ź™=ŅĄ„;‹–Ś; gĮT!|čń½āEfˆį‚‰ų=‘įę¼egu Žd¼ģ’{ 0ø“fśeppĮT!Žd¤<ŃąæŃ¬æ«¤ś8¹7īHø Ž&ŽhŃ/x{X "P2c$^ÆÕżQ§!nū\“žóMzśöD+¹‡ĪžČxłŸ=Ę?}jüV§į ŗŁŽG"8qšb±2œ7&tÖš“@F@ ū # ˆ}Ä>ČbdįĄfū?d>¼²q{ģIEND®B`‚qatengine-1.9.0/docs/images/qat_coex.png000066400000000000000000001032331500416242000201760ustar00rootroot00000000000000’Ų’ąJFIF’ŪC     ’ŪC   ’ĄžÅ"’Ä ’ĵ}!1AQa"q2‘”#B±ĮRŃš$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤„¦§Ø©Ŗ²³“µ¶·ø¹ŗĀĆÄÅĘĒČÉŹŅÓŌÕÖ×ŲŁŚįāćäåęēčéźńņóōõö÷ųłś’Ä ’ĵw!1AQaq"2B‘”±Į #3RšbrŃ $4į%ń&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤„¦§Ø©Ŗ²³“µ¶·ø¹ŗĀĆÄÅĘĒČÉŹŅÓŌÕÖ×ŲŁŚāćäåęēčéźņóōõö÷ųłś’Ś ?żS¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠJóOŽæ4?~[ķDŻRėrŲi‘0;É'ųPde°zš ā¾ń÷ķUń/āä/‰.“K2ŁKF“¦õ>c÷˜×?ńĆāeĒÅÆ‰Śßˆe˜Éi$Ķ ‚dķŽÕ  ć#ę8źĢǽpuśvY”QĆŅS«Ķ÷éä|Ž/:³qƒ“Q±?ŒüCu3K7ˆ5idn®÷ņ’ńźgü%šļż5Oü —’ŠŖ–śUķՅÕō6wYZ”[‹˜āfŽä„Ąawqžø8¦_XÜé·rŚŽ[Ėium’Š£”ō*y½’gKeyÜÓŽåļųK5ßśjŸų/’Gü%šļż5Oü —’ЬŖŁ> ńųtx€čZŠIŚ5O²IöRwmĒ›æ{åė׊N£ŗ@„7³dš–kæōÕ?š6_ž*ųK5ßśjŸų/’YTU{*ʾįs˹«’ f»’AĶS’e’āŖÅ—ÜņRæ»żżĆŪ½~‚|5ų•”|XšÆˆ|?rg²›(ńČĖƒ£‘rv°Čö ‚ ł_B~Äæ.<ń†×C’mŗGˆĮ“š78UUšķn?ķ§°Æ—Ī2šS£*ōciG]:Æó=Œ6qš§QŻ3ōŠŠ(ÆĪØ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ «Ŗ[Éu¦]Į łsI ¢?÷X©žujŠ{ų²ŖČ6²”eą« #Ø#֊÷æŪąēĆˆ×ŗŻ­³ ė×so2Œ¬3·Ķ,-żÓ»s(čTągiĒ‚Wģų\D14cV3ą«S•øK”čæ üq¦ų_Ʀ֛©–šĖV½³†öĶU‰–Š%Ą•”ō Œń:äżåSȽ2o|7kĻßgLÕ/.5+¹¢mVŌØ¼„Ę¢/u…ĆÆĢć̃’79_›Ø¬źąé՛ØŪMöł—õ„Ŗ„£mæą’Ÿįź{7ÄĄÉö©<É7–\fىIź[+3T“ļxt|?“ŠęHķµŃd¶“RfiXż¾I£)&=®…X:Ø*Ųń<šŠk ·g}üŸį«vż4ZMŽß×]:mÓ]O¤üAāΚ žÓoĀ8Óoõ 0ŻEo’#åOéh¬ŽZ°Wo“0;¾~CÖwÅH|§ųƒ]Ė„XÉgi>ž4{}:T§ūau•‹ŹÉ!C7 mĘ+ēŚ+(ącœfōžæĻęļ½ļrÄ9+8®Ÿ‡õ÷i±ōå׌>¾­ XĖį‹[ &EžęČÉ<0³!Eņ’±ŒeĘß½'œŲ.£;’übń5—ŠÆ“[« KO¾†=: vŽÓIK axćDa(HÕ[%r”Yƒ€@Æ=¢®Ž )¦Ū]õż,D„-ąWwšĘćPųŻą­•šE×,ę;FNĕ]’ ŖÕĀWŲæ°‡Ąū¹5“ń#V·1YĮi !¤‘I&ģ…,ƒŌ³v³Ģ±Ćag)uV^¬¬-)U­øh¢Šü€ūp¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(/ÄŽҼe”]茯Œ:–™v›&·˜eXzś‚ Œ@ ƒ_!x’ž ā&»–ēĮ~&Kx²ŗ~³`™<ādäŲ'ŽXõÆ“h®ģ.;ƒw£+~G=l=*’ÄW?<įß?č+į?üŗ’äj?įß?č+į?üŗ’äjż¢½_ķüwó/øćžĶĆöyłć’łų›’A_ ’ąu×’#W;ńö/ų…šßĄŚēŠ/ļ¼3sg¤Ś½Ü°Ūß\yŽŖ2BęÜ żM~˜W•~Õ_ņn?ģ q’ ŅžßĒ2ūƒū7Ūń>F’‡|üM’ Æ„’š:ė’‘Ø’‡|üM’ Æ„’š:ė’‘«ō:ŠŪųļę_pfįū?¼üń’‡|üM’ Æ„’š:ė’‘©Ń’Į>>%—õ *ē–[Ū’Gįöaüėō2Š?·ńß̾ąžĶĆöüO“>~Ąz'‡Æ Ō|g«’ĀE,e]tŪXĢ6”‡gbKH=¾Aź }]km •¼Vöń$š Ž8¢PŖŠ€80*Z+ĒÄāėāåĶZW;iQ§EZš°QEČnQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEå_µWü›Ä_ū\č5źµó'ü+憗šWöwÖF±£kZ…·ˆ£—G†ļK†)"µć,ž~łŖ°VĮPÜ®22ōŻĀüų¹ańŪįŽ‰ć­'HÕ“]+X¦“·ÖāŽ+–ˆ1U¬r8 ŲÜæ7*Aļ]ÕQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQU5MZĖCÓn5 Fīt2Mqpį#GRĢxžś -×ȟ·7ĘOkŸM6›¤œ¤śÖ w¦"cOöĪxū¼ēäæÖ¾Ļ-Č\ķW¬æ—ü’ČšqY’¹G~’ä~ ~Ī?¼ń?Ć66… ~Ō4ĖXąfĆ (UņOćPČä`d Œū5~1iŗ•Žo}au5•ķ»‰!ø·r’FĆ£+AÆøægŸŪr×^ū?‡ž!ĶŸØšk˜ ē¦&ˆŪż”ņžūqĪ–G<=źįµn«üĶ0™„j{•t}Ļ®č¤V ””‚¤dŠŅ×ÉŠQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQExĒŚ¢ĖĄššÆƒl›ÅŽ:˜˜–ŹŃhķŸ‡ Ėæż3^x9+Ęz(aźbgģé+³*•aF<ÓvG£|XųÉįƒzö—ˆo|¹$ -¬aĆ\]0ź3Ó¦XįFFO"æ9¾8žŃž'ųć©bśOģŻŻm£[¹1/£HxóÄF8'9Ž.šĻÅ/kZ†½āų›TæWŁsu6™>!#˜ ¶07 (Ąé\—м#­x#Y›I×“Ė'Q‹–·ŗŒ©#$™NdĘæDĖ2¼>©JJU?/Oó>c‹«Zé&£żndQ[—^ń%Ž›oØ\ų{U·°ø„ÜĆu-”«± ‘\® į—ę0õŖ7Ś„„łælÓī­<—X¤óįdŲ컕NGØČØę¾‘N/fy\ƱFŠÕµš®·}å}›Gæøó‘$Źµvެå† ø*źAh ėqŚ[Ż>~¶·½Ä35«„’$Ęł±‚«‘– ŒŃĻįŹūŪū=ž×ZēĀ6ƒFÖüķ{ĀC °ĶŘõ…‰åq’,ÉĒē?” ń¶‡ń @·Ö¼=ØĆ©éÓ–XO*qʲžU†FT€E~ChžÕ¼Mröś>—yŖÜ"+w™ÕGV!A sÖ½įž»ń?ąŸŠ“Ė­ HÖ-.µ` :eĶ„Ę-Q8ą0 œ€Üšł\Ļ'£ˆntZŒūtä{Lté.ZŠńüÕ*+Ģ~üvҾ'ļÓn¬ī|3āėd wįķQ W;ŗŗg¾ĄČϧWēµ)Ī”œ&¬Ļ§Œ”×4BŠ(¬Ź (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ÆØ[iv7··0ŁŁŪĘŅĶqpį#e™˜š’jÅy7ÄØ#ńgʇ~Ōc[ K WÄw6rØh®e²’ĘEž%WæóBž7D‡ŖŠü57ĀĘę/[ŻGü3ZŪOŠĶ’’_üj½ZŠņŸųjO†ō3ä…×’£ž“į‡ż ßł!u’ƫը )’†¤ųa’C7žH]ńŖ?į©>ŠĶ’’_üj½ZŠņŸųjO†ō3ä…×’£ž“į‡ż ßł!u’ƫը )’†¤ųa’C7žH]ńŖ?į©>ŠĶ’’_üj½ZŠņŸųjO†ō3ä…×’£ž“į‡ż ßł!u’ƫը )’†¤ųa’C7žH]ńŖ?į©>ŠĶ’’_üj½ZŠņŸųjO†ō3ä…×’£ž“į‡ż ßł!u’ƫը )’†¤ųa’C7žH]ńŖö¦ų`ŖIń7ž”÷_üj½ZŠų7ö…ż¶ļ槑ņXčb!QN£ŗčśµ­|ršÅ¶Ņ<6nå};ļ§–Żę„5’Ū˜ŽI- „džł”xU²xÅqZāč?5ŻG_žŻÓ|%ŌĘIl5i/.¤?3ȍ£(BI±Ü0y#¼śŠö”„§MóBé÷æłčpʼä”e²čz«ü[Ņ4żCC0h Ø’g,֗·w7q™5+g‹ÉhĆ„“M“©%LĀG_0Agˆ¼iĘ [XõmcJšµĶ£<×:‡Śå:„Æ… I·ĖŠ8“ éNN<ĪĪ?:īü©'Žź¾T'ł?ux<žƒƒō5ÜxÆįž™”ųƒF³‹S{·Ź‰s§^“Mw§np ŹŠ³®W$ž\™VŻ feBŒg’ÖĻóüū[ē`UgĖ'Ń-}?­7½“Ų¼ßtżIŅü5öUÖōĶņ;čol/ē€\N™Ų‰Yc!‚…Ų¬…K˱kzĒĘh¼_§jUޚšy×Z7ŌÆžöS\/–±Ģ‘¬lc‰Dyh€}Łć# ŅŪųĀ qs%ļ„ōM×OÖ®4™„ÖÆuĆfFvņęŽn@nB±˜,cĆuO±’j^głæ`óŸģž~<Ļ/qŪ»gϽaF4+ĖįwŽļĪĻ£·go%ŲŚ~Ņ’Żvū®ŗöÕ|üĪÖ«‡Ś>±‡ˆtÉ«ŪĒhŃéėy€$ńO½„öń†RbŪ€Łł³Śŗ{ö²×µ5ü9-½×Ū>ßio5”a¹ˆĘķ‘Y#+ żéLĀĻ$ųÅÕ,-9ėSWÆā­Ņ݌#ZQų4;æˆ^3µ¼ńf«x^źņĄXé–0A ¾Ńm$PŖóB¦YJćrØ8Æ®æf_ŪüuØXxCĘq0×ē"+=RŚ,„ŪcīȊ>Gļø §œķĒ?!|'ų7āŒŚ÷ög‡¬·¤x77Óemķ”ō.ŲźyŒ±ĮĄą×čĒĄßŁĻĆōŠÖ1’ikóFėXø@%UAĻ–™žÉĄÉl łŒź¦ a5Ķ5·uź’ÆŌõšÄN|ńŅ:|ķ”źŌQE~~}(QEQEQEQEQEQEQEQEQEQEQEQEW•xžN›įēż‰ž&’Ņķ½V¼«Äņtß?ģLń7ž—h4ź“QEQEQEQEQEQEQEQEQEÅüSųC៌^:WˆģDŪC{Ȱ·¬GŽńĒAr§ ×iE\'*rSƒ³DŹ*K–Jčü²ųéū7ų›ąv”ę]”Õ<=+m·Ömć"2sĀJ¼łoģI±88ņjżŌ“ŪMgOø±æµ†öŹį s[Ü xäR0U”šA÷Ɔ’hoŲŽļĆ’hńĆøeæÓ2O”会wĢ$ó"ćųN\cŁćļņÜö5mK¤»ō~½æ#ę±ys‡æGUŲłŠR ’Įi+ģ ŻŌ×ēŃ|C¦Ķ„źPņŠĢ8eÉ•‡ § ¤ƒŠżŠÆ)ż„¾Eńsį^µ§Śép_x–+YGŹĒ$7q¶CŠAłNAĄÆ„ĖsŖ˜;S«ļCń^Ÿäy8¬kūŠŅ_™łĶš§ąļ‰ž2ė’Łž²ó<›é²¶ÖŖz|u<įFXąąpqś1š7öqšĒĄķ;uŒŚ^ š0—ZĶĀ+ś¬cŸ-3ü äąn-]ļƒü¢x@¶Ń|?§C„é¶ć #©īĢO,DZ$žę¶«Ē7«Ž|‘÷aŪæ©¦ ?¼õ—õ°QEąQEQEQEQEQEQEQEQEQEQEQEQEQEQEW•xžN›įēż‰ž&’Ņķ½V¼«Äņtß?ģLń7ž—h4ź“QEQEQEQEQEQEQEQEQL–A o#}Տį@¢¼FļöÅųicu5“ś…ņM “næbs†d{Š‹žCį‡żÆæšOš®õ—ćŗ£/ü’‘ĶõŖóń}č÷:+Ć?į“>ŠJū’d’ ?į“>ŠJū’d’ Łųßłó/ü’¾µ‡’Ÿ‹ļGEūJx>ļĒæ ®t;=JkĶSJV·Ō“ÓØŚĘ£lĪÓŪO6%PĢė¹FŠr@ę¼sĮ7_| ńćBš5Õ·ģŻ­®ģō;@HĶ“ĖęŚFšc$Hg(0uIypcē č?šŚ ?č%}’€2…r’kŸėŸõ«Oų¾oxĮ”ݦźzIž”0;dFFX¤ć#vGJŸģÜeœ}Œ¬ļö_T—nŸØŽ+ćoh¼µZOį_|eš?€tB“ńĖŁxcJ·ūšü֖ś6Ųķc¹ Ė£JóLŠde0ĖvK3i¶2GÖ³¾·ā|,ÓÆ<_,Óė-4źfŗµžŚwˆJĀ3*McdŪöą-£S€@ äńš_ķšŽĻL³·»×µ Bź(R9®ßMdiÜ( !UT±ÉĄā­Ćh|0’ •÷žÉž³ĄćdŪt%Æ÷_łĮīßE,U K™TK濯ėcÜčÆ ’†Šųa’A+ļü“ü(’†Šųa’A+ļü“ü+?ģüoüł—ž’Č>µ‡’Ÿ‹ļG¹Ń^’ ”šĆž‚Wßų'ųV·„’jx×ÄV“{y>£{'• mhč Į<“ĄąųTĖ‹„\„JI/īæņ)bhIŁM_Õ»EW ŠQEQEQEQEQEQEQEQEQEQEQEQEå^#’“¦ųy’bg‰æō»AÆUÆ*ńü7ĆĻūiśEż·Šæ¶¤š Ht”"Ü[Ś%ĢŠæŚķŌ2#: ÅsøpĒÆCźæŁ~±[ héÖ·šW‡-­^ķ&²Ž/bŗ“€DŅF¬Aq!•žóžų­*ā•)rņ¶’į­÷¶‘躊÷ž“>z¢»oŠ~‡Įz„—†–8MŽ› }®ę5¦y¤RO|DŃ v渚é„QU‚œvÕžfU éĖ•…zwģĖ’%ßĮßõöō[טק~Ģæņ]ü’_g’E½rf?īUæĆ/ɚįŽ)śÆĢż5¢Š+šóō@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Æ*ńü7ĆĻūˆ_ģż6ŚČ’xC>ē5“_{’Ć xž~µ/ūūGü0ׁ?ēėR’æ“G‰0\±‹KŃ˜ŽS‰“»kļ>¢¾÷’†š'üżj_÷öųaÆĻÖ„’jæÖli}ßšIžČÄw_üąŠōļŁ—žKæƒæėģ’č·ÆŖᆼ ’?Z—żż­æžČžšŠ“ŻN¹¾7¶2ł±‰$IĮō&¹q|Cƒ­‡©J*W”ZŪŗõ7£•×§V3v²ižćEWę§ÖQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@yWˆ’äé¾Ų™āoż.ŠkÕkεĻź7“G‚uø­$}&ĻĀŚõ•ÅŲ$sMw£¼H}Łmę#ž¹šōZ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ņÆŚ«žMĒā/ż®?ōõZņÆŚ«žMĒā/ż®?ōõZ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<;ć÷‚ķµ’|,y5é˩믄^C¢ų£RÓ"žŻtėū€­µÄk»ĶŠ6ߍä(RŪx¬­?ćę±į½?F×üc«xgFšu’Šu īī’KUÓķ­¾Ūo5Ü×Ie¶‡Ŗęþ†®3UńµÕ‡Ę? ųA …¬umVÕ„³ę$–—lH«Ī6°¾œŒåē.öVC—¼Óņ·ēžk’Gʟķāhü]šļN·³Š­ķµū:öO·Kgl5“ĪČéh÷Z¼ŠcUĮtK:© HŻõõRZFŽośł ­żŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¾d’‚…|pŅž žĪśČÖ4mkP¶ńr蚯épÅ$V³¼e“Ļß"V Ų*•ĮĘF~šf ¤“€9$×˶ÅO†ž-ųoÆü9Öāo R1ŠXHŪ²°tI‚ՕXp{pFEtPĆÕÄĻŁŃŁ•J°£jŽČöæ‚?,>;|1Ń[ ÉģĆØ5æ_–>»ń—…e:’†gšÓÉó™Ž9¢¼ ”?0T #”ĒŁ_ iٵ$µÓüu¦śM95DæRæg’Łˆ +sņOCź=kólĆ#©„nTeĻÅ|æČśĢ.aé)®WųZŸBQPŚŻĮ}n“ŪL“Āć+$lOЊš¾dõŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¼«Äņtß?ģLń7ž—h5źµå^#’“¦ųy’bg‰æō»A U¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¤''KExĘOŚėĆæ}7F Ækiņ”± MŸāo^¼jų«ā'ŏ|PŌÖ½ØÉ:g1Ś”Ū īÆāy<ó_}ü\ż›|)ń^'šŲišĪ>MBÕB±?ķŽŒ>¾¦¾"ų±ū=ų³į-ĆÉ}ho“¬šŖ–ž!ü'ėź9ÆŠ² ™lRIZÆ÷æöޟ©ņłœqnķė/ל±‡ń]4GŅžÉŚŪiW¶W>™k%Ē™1¹*c”ČŖ<äĪz6Ļ:Zō -ĖU°¼žŌڵ¦ŗ±¢1ŗHŠ%Ɨ¹æ€*g$tā¼–Šū`éM·m’ą’żRģxQÆ8ŪĖžłį‹?ŲZ½åķ¤w÷:¦­m}8–Ž9?v¾y£·Ķ¹•J:`‚#ægį_:/…<;§XŁRlē ėåJßičĖē[Չe)…ɁĻŽAćĆ“Ų`øŌ-bŗ’H­žUYd…ŗ” ŖHœF}E{?Š>č¶·ā–Ńn¤Ńmō¹nķķ-eŠK“my9–ł¦fČ ˜ćaŠķ\•^%47ڊ6ƒ”’ žuIJ.yŲ‡ńäžUöĻĆ?ƒ>ųS§ˆ4[$6ņQŗi:–ķŌńļ_ŸŌĖdß²W«Ž;|ūüµó>-Ž.+ßų<÷łšÖ??č²|?’¢ǒŽŃ’ cšCž‹'Ć’ü*,ųķz­ńŠžU’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@U’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@U’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@U’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@U’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@U’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@U’ cšCž‹'Ć’ü*,ųķšÖ??č²|?’¢ǒŽ×ŖŃ@]kūSü½øŽ ‹ŽžyŌŽ/Y31ōKĶzeµĢ7–ń\[Ź“Į* #–6 ®¤d0#‚ļEÕ¬7¶ņAq sĮ ŚńŹ”•‡”­y?ƒ,mžüoÕ|£B–^ÕtQ®Į¦Ā6Ćgt—UĮ‰G¤‚HX¢ü»ÕŪ»ė“QEQEQEQEå^#’“¦ųy’bg‰æō»AÆUÆ*ńü7ĆĻūŌź+ͦż£>[Ķ$Rų¦Ę9cb® H8 Zgü4—Ćoś4’ūś+§źµ’ēŪū™¶§üĖļ=2Šó?ųi/†ßō6i’÷ōQ’ %šŪž†Ķ?žžŠUÆ’>ßÜĆŪRže÷ÆŠü+¢ųŪĆ÷š/ˆt{ HŗP'Óõ;T¹·—k]Ńø*ŲeR28 Õņg„<ćo†æü„ü9Ņ®üxžŸYÕmt_ZG-ö·6‹W^u»žń÷M•ĀŹå>šŚk߿᤾ŠŁ§’ßŃ^yńūö·Ō¾ė‰š³ā¤xź4Y“Ł.ÄRĆ++Šø‘J€ėøć “ē¢8lD[j›×ÉōR_=ļņE}b•¬ä¾’ėŠĆųŸń‹āV«įżKRšN›ā‹=!õČ-RīoŽXß[Ś‹īńŪÉ„^NŹ×#af³`œqōĀ­CZÕ¾xjóÄe[]šĀ½e‚h7JTncŠĆ"Ō«EŸ‘z+Ć?“'ōßivšĒtżcV†Ś8īõ $_i˜( ET3dķŒā“’᤾ŠŁ§’ßŃBĀ×WżŪ×ɑķiéļ­<ĻL¢¼ĻžKį·ż šżżĆI|6’”³O’梏Ŗ×’ŸoīcöŌæ™}ē¦Q^g’ %šŪž†Ķ?žžŠ½”üvš'‰5k]3LńåżÓłpĮ īgo@KĆ׊»ƒ·£«M»)/¼ļØ¢Šē5 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ņ«ł:m?žÄ˟ż.‚½V¼ŖćžN›O’±2ē’K  U¢Š(¢Š(¢Š(¢Š(Æ*ńü7ĆĻūdÖ±Iæ»ŪæTŽčį%7£ÓśGĶōW¾x_ą.‘ÆxšźŹkj֎ɦ¶’éĶ֚ó,“¬V2gwnq €@''"µÆĀ­"×Ä^!Ń/4­SBµŽĢ {ķiњõ–öW¶s ,bQņ%”yœ¹\ęæ“hórė}?ĻåņПŖĻ—›§õ÷|öėfxegR¶k=JīŻ­ę³h„xͽĮ̱aˆŲü˜t<GAU«ÓNźē#\®Ģ+Óæf_ł.ž’Ƴ’¢Ž¼Ę½;öe’’ļąļśū?ś-ėƒ1’r­ž~LčĀ’¼Sõ_™śkEWįēčEPEPEPEPEPEPEP^Uq’'M§’Ų™s’„ŠWŖ×•\ÉÓi’ö&\’étź“QEQEQEQEå^#’“¦ųy’bg‰æō»AÆUÆ*ńü7ĆĻū!ĄF .OEٟ,ÆäŚKļ>)¢¾Ö’†Ń?čfŌ?ļ„’āh’†Ń?čfŌ?ļ„’ākOõ‹/žg÷2²±=—Ž|SE}­’ ¢ŠĶØß ’Ä×#ńwö=Ņ~ü1ń7Š`×/ofŅld»Ky*ČTdBō„ž±å’ĢžęŁXžĖļ>W¢¾Ö’†Ń?čfŌ?ļ„’āh’†Ń?čfŌ?ļ„’āi’¬Yó?¹‡öV'²ūϊhƵæįtOśµūį?ųš?įtOśµūį?ųš?Ö,æłŸÜĆū+Ł}ēÅ5éß³/ü—ף’Ńo_DĆčŸō3j÷Āń5Ń|=żō懾4Ņ|EmÆŽ\ϧĶę¬2¢mn ąÄ×3>ĄÖĆT§ ;Ź--;£zn"XNKD×_3čŗ(¢æ1>¼(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Ź®?äé“’ū.ōŗ õZņ«ł:m?žÄ˟ż.‚€=VŠ( Š( Š( Š( ¼«Äņtß?ģLń7ž—h5źµå^#’“¦ųy’bg‰æō»A U¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Æ*żŖæäÜ~"’Ųć’AÆUÆ"ż¬õ [?Ł×āw0Ąóh÷5’@„ĪŽ€½GJõŚ* ;ėmB5­ÄW1gd.sé‘SŠEPEPEPEPEPEPEPEPEPEP^Uq’'M§’Ų™s’„ŠWŖ×•\ÉÓi’ö&\’étź“QEQEQEQEå^#’“¦ųy’bg‰æō»AÆUÆ*ńü7ĆĻū~Ōų%jö@®³ā™1iPøVFCĢߥøĮļ6F2Ćó³āGÅ|XńšĻ‰5¼øÉĀæ,6Č‚$裧¹ĘI'šś·'«“ēīĆæWéžg™ŠĒCīĒY„æ³GĆæ ü)ųąļ xFņßSŃtūUŌ-H+w)%¦›Žļ!v#±8ķ^_”æhüÕ¼Ż&o¶iHļGøcäĶŲ²’qńüCŠd0ÆŃƃ’<1ń«C7ŗ ÖŪø@ū^›q…ø¶oö—ŗžĢ2Ō1Ģ2ŖŲͼ;’™x\d1 ŪK±čQEx‡ QEQEQEQEQEQEQEQEQEåWņtŚż‰—?ś]z­yUĒü6Ÿ’beĻž—A@«EPEPEPEP^Uā?ł:o‡Ÿö&x›’K“õZņÆ’ÉÓ|<’±3Äßś] ŠŖŃEq’<]wą_‡zÖ½b‘Éuc™A•8ē®u$”Ł2’Šr}ŠųOž»Ę?ō Óńź?Ỽc’@7’Æ”’W³ä_z<æķL/ó~ ū²ŠųOž»Ę?ō Óńź?Ỽc’@7’£ż^Ģ?‘}č?µ0æĶų3īŹ+į?ųnļ’Š'M’ĒØ’†īńżtßüzõ{0žE÷ žŌĀ’7ąĻ»(Ƅ’Ỽc’@7’£ž»Ę?ō Óńź?ÕģĆłރūS ü߃>좾’†īńżtßüzųnļ’Š'M’ĒØ’W³ä_zķL/ó~ ū²ŠųOž»Ę?ō ÓńźöŁ›ö„×>4kšĶ®«ikkŒ "}œ±f#œż?ZęÄdŲĢ-'Z¬mę½ ©cšõ¦©Įźü”h¢Šń@(¢Š(¢¹ĻüBš’Ć/M­xQ‹N±Œķ]ē/+愍G,Ē”=5QŒ¦Ōb®Ų›QWgA4ŃŪĀņŹėQ©gw *€2I' ÆæhŪ}-¾Õį߆ó¬ÓcøńŻČ½ˆ·†=¼ĆĒ] ä0ńŸŚö¬ńʉ¦Ņģ|Ķ ĀAž[ŽŻxiŲuõŲ>Pq÷ˆ ^_w–ä*6«‹WĖžä|ę/1r¼(ż’äMww=żŌ×WSÉss;“²Ķ3—yœ–f<’O$š†Š+ķR²²<­O ų£Všf¹k¬hz„śf§lŪ¢ø·l0õ±SŠ©Č#‚ eŃJQRN2WLqwGčģńūdi¾Ķ ų¬Į”ų”ˆŽ)³¶ÖłM¤żĒ=6‚q“œķJ×āĶ}Oū<~ښ‚~Ķ xźIõ}:§/uf½0żåA’}œnĄZųLĖ!q½\"ÓłĖü¢ĀfW÷+ż’ę}’EQŃ5Ķ?ĚU¶§„^ĮØi÷)¾›w޾ óÅ^Ɗi§f}įER¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Æ*ø’“¦Ó’ģL¹’Ņč+ÕkŹ®?äé“’ū.ōŗ õZ(¢€ (¢€ (¢€ (¢€ ņÆ’ÉÓ|<’±3Äßś] ×Ŗ×•xžN›įēż‰ž&’Ņķ€=V¼Ļö’’’#āĻśņå^™^gūIÉńgży?ņ®¬/ūÅ?Uł˜Öž½łĒįæźŽ,[—Óā€Ao“Ksyw ¤ĢHU2Lź›Ž9;N©Žh:†µ&=”éŖG?ٚĻa2y™Ū°(źsĒk{Ć:ʅ/†o4-z[ū$¼Žö+Ķ6Ö;—ÜØčcdy#ą‡Č`Ü~S»#Ś|1ū@ųcĮ^"¾Ō!¾Ö®ķī.šź;ka8O)”HćIķQD&]æ91L€Uŗcö:ųŠō„%svßĖ®Żžćą©Ó§8¦åg’ÓīūϚ™J±VpA¤®ēZš¾”ć Bū^µÖ­u+K‰E¹×u«+kéć÷Ér\0:äGQ]ÕÆĘżßDŅl.§ÖµglŠ#’/&Ž)a1=¹HZęTįāY/‘›(ģxÖX™(§ó>©=æĪĮģW;NV]ėęxeéŽ*Y>*Imy”’giöp†kˆµM^ŹÅŽņSę\H±Ė2…˜*>ź(źäų„¤ŲͤÄé;i¼~åįÕĻŁÄCĻeb6Œņ ę,`†Ė1õ‰YZ7–·WŪ·ßśś“ģ•÷Ó£·õż#ČØÆ\ńOެ~!i§AÓ'½³Ź%KŻbk[Ud #ż’IÕV·Ü`~EŹĘ]BūįĻ„5-KØ~Ó«]ŪŹēHÕm®c’Ś4™e†W‚VĄc"|§‚ō§Dœ}čŚWŚż;üµū‚T’~ėŗļoėŌóŹ+č}w枃«Ē4Vwŗę…$ˆāŪP°³‘®ōŠd‰¼˜šMA‡–U6‘’­qśēŽō]āĻ‹u°_°»øaCö) ö× ÓūŖæ\qYSÅV©£¤Ó³ėŚŽVėųz2ēFœUŌļ·ėó8o ųWń‰”ipŪæ–é77Ū‘ó²42ŗļvŚŲUÉ8ńņĒā?„ļ5 sÚV„EfŠõ'·¹‰wɄ.8‘ppUŌ«w1ćēU*Ė^3’å·ŽÆÆ_—ĢļĖćˆ¦āīī’'ż|żmö?ˆæh/ųkĆśŽ·.ŗŚ¦™”ܛMV}ŹćVū‹•„ėi­Tf`r7H®³Ā^+±ń®…o«éŃj0ŚNX"jšeĪ?‚LĒ"Ž8%FFČ9ƒ~žĄzģżš[恬|Z5é|[kyk„OpņŪŪijZˆ”Ļ.”Ćõ‘½‡ŻÆPųū<_x»Ę×¾0“²ŠoõŪ(4&ŠŪTwF†[+ÉgøO8C#[¬ČŃ”xՉŪó) ü©[ķw_%ÕłŲūY-Žśž–ō½ßÜ{õń’ÅOŁ_āÄŻH{Óįē¹[ŻVņļEQ„Ū[Éup²Å477z=Ł2Ę”:Į Ä«•>Ķmū9é‹kĶćˆ 0@æį3Ō[œ‰@>‚’ųnō}‰zI„¶ŗ’_×ęSų÷ūOxoą«ŁåuŸH¹‡J…Ąņņ2fžĘ8ūĒ##įķ;āž»ń+ātŗļ‰µø£Õ¾ÉtšD— ±ZX\“dC³wĖ ŒHHĆmfa‚Ćøż¤?d-{įżĘ”āĻyāo;5ÅĖ\;M}jIĖ“¤ó*÷2uīn?4WéYN õw:Rę“VoŖæKt>S^æµJjÉ;„ŃŪó>”_ĒāšķēŽotoŽG§\GsŖ]źq]¤²‹åĄn’žŽ7#bŲ{‚Dn )Ē/Ę»O ŪiśbxZĒ@ŽĘŽęīŁ®ģ/Œ—’m¹›ĖóĪłC„›NzĄ¼–ŗĻ‡0ųÆūRņćĀz¬š%Üłø¾MY4ÅX‹ØŚÓ<‘® łwrqĒź¬<©5QĻEwm–·óó8ż²’ååÕŪ]ßc©ųk xOQšüRė £É¬ż„¼›}GV{X¦· •¦*Ćc"—1€A|æŹåQ_E|7ą“jĀt٬’[DšćTd–ņo&F+t”‡” }īk,jk“•Ékńߌ¼FU{ĶsYo±Ą%¼ŌāFūBī·Q#9Č`r9ĄĻ8ØĒĮļÆ$[éå±¼7cW³6«DIøó| C•R„² ŠRQ“nU­?Ėoéæ+8Ž:(^Ž_×õn·½O†¶:V”āq®¶²ĒöiŽŽŽžēģÖÓÜŲŲļMˆ[;×ÓpĪkŃ5Ÿ ų=<7<“ŲxoMœI=ę›®››Ø/üņĮö™7óoϱų%¼ĢŒ Ÿin“˜X]ɇß]±ŠvxēÖ^r˜¾—ŠÄ—ĮŠĮA"ø±uåėĢ~#x'žG§ ®„[Esåźdŗ‡xĪÉ”Žž[÷Ęć•*{ąrÕ4°īpŒ£U½o×Ļó¾æ- •Ug”aųż«ü ų­©ĶįHtoųDī¦óĪ‹„ެ®#$ā@D’yĄ!vćĄÅ}Åšƒćw†>5hfūA»ÅŌ }ÆMøĀÜ[1žņ÷SنAś‚äÜ0Éq4pÅK,Œ#@K3€IƲ’gŲĆV‹Éń?Œ5=[ĆS¼dŪiŚ=ģ–wŠu–hČdćžY©Ļ8b9Sąē8%: s•¦¶ž÷ÆłžŽ^U9bÆĖśģ}±EyWü3®‘’CÄü,už;Gü3®‘’CÄü,už;_}!ź“W•Ć:éō7ü@’ĀĒQ’ć“Ć:éō7ü@’ĀĒQ’擟“W•Ć:éō7ü@’ĀĒQ’ćµ œš·Į’ų_D»×õų[Ä×2éÖ²k2,ךuźŪĖp‹ē€ ÉŽnup€3ĀzŻQ@Q@Q@Q@Q@yUĒü6Ÿ’beĻž—A^«^Uq’'M§’Ų™s’„ŠPŖŃEQEQEQEW•xžN›įēż‰ž&’Ņķ½V¼«Äņtß?ģLń7ž—h4źµę“—ü‘ד’*ōʊźÖŲZˆcž&ėŖOąkZSöu#;lÓ"qē‹sņŠżp’„gG’ Mž'ųQ’Ī’@›üO𯻒[?éĒžM’ڟ7ż‹’O?ų'ä}śį’Ī’@›üOš£žž6?ų ŸįGśŁ’N?ņožŌ?±éēį’ü¢æ\?įŃ’čc’€Éžåß42ˆ_’=:Ņ4›Ę7 "¬ Æü#śĆ`ńČŹ©ĮīķGśŁ’N?ņožŌ?±éēį’üࢿ\?įŃ’čc’€ÉžĀ3£’Š&Ē’“ü(’[?éĒžM’ڇö/ż<ü?ąŸ‘ōWė‡ü#:?żlš?ĀųFtśŲ’ą2…ėgż8’ÉæūPžÅ’§Ÿ‡üņ>¾«ż€’ähń_żzĆ’”=}‹’Ī’@›üOš©ģō{ >C%­µ“„m/ J‡™¼üż{ ,?²·5µę¾Ķ>ČźĆeWŖŖóŽŽ_šK”QE|yī…Q@|­ūD~Åz>×āĒ“ư2M„ń­ćw+Ś)żņN3·%«źš+Æ Š«„©ķ(»?ės“aZ<³Gć>·”źÕ®“½VŹ}?Qµ}“ZÜ!GCא}¹÷5µšūĒ×õ¦Õ,ģ-ļ.ölFžāź,ø6óDH#‚¬J‘ŚæKž6žĻ~ųᤘõ8~ƬÅĖMbŻp­’=9ł©ĮRs_œß¾ ųŸą®»ö zÓu¬¤ż“R€·¹ģ¶8aŻNśOčų ҆ce=$÷]ż•Äąźa_2Õw6“O'ˆ4{ĶOBÓ#Ho¬./Æ4čd[‹ˆķ~XŠ!—Ź\'D@p* 7ć%ŒvZ½„ׅ“ßģÉ4ćie£Bn¾Ź$kئy$sqēdˆūIÕTcÆ.¢½_ŖQ迯ėīčqūiõg£ėŸµ%Ä·Z^”5Im‚ꑤĀx­7īź¾o—°1BūxŻŽ±õωW~"µŌ¢¾Ó4é$½Õ„Ö‰–KydŪę,x“"Œ0b1Įšä(­#‡„œVß×õ’—RoF’«[ņÓÓŠ·«źO¬j·—ņ ŽK©žvUwp 1$nvg=z³{’y­ü>מ&ųŽ Ú|š…ōŸ3mHuy¢(õ=Č$^…šöcń'ĘėČļmĀČÄM«L™ó0pRž6ĪA?uprs…?¢Ÿ žxoį'‡cѼ7`¶ §š{—žüÆÕ›Æ°ĪŠšsā–{*>ō’ėžG£…ĄĻłē¤3ĶægߣG@ų3 „’—®x»oĶ~éū«bG+žž›ĻĢyū •Æv¢Šüęµz˜‰ŗ•]Ū>¦8Ņ,QE QEW•|p’‘‹įżŽq’éŗžŗo|TŠ>źšN›Ŗ^{żUe{[}#C¾ŌܤmČī-a“ĖPeŒn}£ęÕŠZ~„ŃųWY×õ “ė}_µ¹¶hø–źmöPĘĄ);YīĄČĘ BÖÖė§Ģ:Ųķ袊(¢Š(¢Š(¢Š(¢Š+Ź®?äé“’ū.ōŗ õZņ«ł:m?žÄ˟ż.‚€=VŠ( Š( Š( Š( ¼«Äņtß?ģLń7ž—h5źµå^#’“¦ųy’bg‰æō»A U¢Š(¢Š(¢Š(Æ*ųÉ’%ąOżŽw?śk5źµąŸ>'x;Ć’ž Łj¾,ŠōŪĶ?ų\^[ŽjPÅ%“M jʲH¬Ą¢–’5ąź;Š÷ŗ*+[Øo­a¹¶š;‹i‘dŠh˜2:‘ŹGr©h¢Š(¢Š(¢Š(¢Š(¢Š(¬ŸųSHń¶…u£kŗ|:ž™t»e·r”Ŗ°źAäkZŠiø»­ÄŅjĢüėż¢?c­_įŚõ’ ‰µĻ Ø2K7]XÆ}ą]ąd ī Ēꌿ¦Æ•’h/؟Nń“ÓėŽū>‰®9Ż>œ’%„ÉĻ,øŗ ŚN8–?q–ēŪRÅæū{ü’ĢłüV[öč}ßä| /q2E4’ČĮĢÄąRM}‹ū;žÄ2ß}“Äįx Ą’ēkæ”ø#•ü±ĻMÄ`©öŁ÷öPŠ> Ć«ØłZļ‹ö|×쟺µ$r°)éé¼üǟŗ Z÷zĆ2Ļ„Vō°ŗ.ż_§oĢÓ —(Śuµ}ˆlģķōŪ8-- ŽÖÖÅ(#P0Tp`TŌQ_{”EPEPEPxóį,^>ųįMvņņžŪOŃlÆ¢)„ė7štĻ4²Ś<{“‰ęG‹y7#±RJü§·Ļėū%ų½~-ė>&ųD“‹]CV†ä<Ū@÷ŖšĶš2$d2ł‚Iļ®n‰w?2‚Ķ_bו|p’‘‹įżŽq’éŗžœ$£%öoo›øŪŗ·§ą|żćOŲēĘŽ$Õ,’Æ'žUµ*•#Õ¤EIrĮÉt(ĆU|3’”Ž?ūᨒ†Ŗųg’C÷ĆWę½ś7ś­†’Ÿ’ü?ČłOķšßŹæō£ž«įŸż q’ß Gü5WĆ?ść’¾æ5č£żVĆĻÉ~äŪ5æ•~'éGü5WĆ?ść’¾¾Bż®žüż¦~6|/ń¤ž#“†×Kŗū/‰¢d`×ŗznš%r|Ąb=öϟ௢õ[ ’?%ųlÖžUųŸ¤ŃžŌß !cÄ¢( Ŗ±§ĆU|3’”Ž?ūį«ó^Š?Õl7üü—įžAż³[łWā~”ĆU|3’”Ž?ūᨒ†Ŗųg’C÷ĆWę½ŖŲołł/Ćüƒūf·ņÆÄż(’†Ŗųg’C÷ĆWOą_Œ>ų•yskįķIoå¶A$”T€ œėłWå…}Wū’ČŃāæśõ‡’Bzó3,‚† :š›m[{uiv:š™LEhŅ”UŸłlQEšĒхQ@Q@Q@Q@Q@Q@Q@Q@Q@yWĒł¾’Ųēž›ÆėÕkʾ8ČÅš‡žĒ8’ōŻ@«EPEPEPEPEP^Yq ŸšŌZ|»Ź’„:åw挿¶Œś×ńgĒž/šßĘK’ģū·†“OŚj³Ūéķ„E„y-čo·É<2Ž„qj>ʎć XŒćx?öšńŽ<[äCįI,Æ4ż'\y¼5‹øEõÕŗéR[÷¶6×1·²)żĘā@“ D}ļÅü•õü4+•ór’[\ś~Šł‡Gż²5M[ĚN‰oą)uŻÖć[HZ¹m0M;ĊAŅdŠ‘™.žŹB‘“øł«éźvv¹MŁQHaEPEP\oÄOÜų©“[Fæ‹IńN‡3ϦŽÜBf„‡M’Į4a”¼R/F*+²¢€,’Æ'žUՅ’x§źæ3ßƗ£?2(¢ŠżŲüą+Ņ~éšĒ†5[Ÿ čVž"ń"ŽA¶“MMFHmJ¹gX]]p\"—ŚJš2»łój+*°öåO·ęT%Ė%/ėoéŸB\|?šķžµā}"åt½3PÖoe°Ól.a„†TAlĖ…é–=ĪŹ ĘĄ ®ā6¹qsįE.Ÿ¤ŁĖye-ÅÓYč֖²“©wqĖǰ¢‚ €q’3Ķp7ŗ•ޤŃ5ŻŌ×M Kfi ”FO ZŠuūÆ^5Õ¤VRČČc+aäx$duŽøĻ^y5ĆO (ZR—3VßÉ5ņ¾ļŖ:„^2ŗŠ²wõÕßēŁlzGĮ}*MGGÖLZ7l²+¶©u¦ĆØ[@©±Šä?ĶouóŠ‚6†ž­¼į¹$–Ż,-Dbaćį?ŁYĮµŻž›yĘ5įZę¹sā ļµŻGg»Bm±²†Ņ<ö!E\ūć&³éO R¤ŻN~VūŸ]¼æhB ·žæą¾’‚D·Wjŗšo-"óŸĖvŖäēvŅ¢¢ŠōҲ²9mŻ…}Wū’ČŃāæśõ‡’BzłR¾«ż€’ähń_żzĆ’”=x9÷ü‹jüæō¤zYoūÜ>“>Ų¢Š+ńćī‚Š( Š( Š( Š( Š( Š( Š( Š( Š( ¼«ć‡üŒ_ģs’M×õźµå_?äbųC’cœśnæ U¢Š(¢Š(¢Š(¢Š(¢Š(7QšÖ‘¬GØ„ž•ezš•ÆŲoVāŻ$V’?īeČłćżäŸ+d|ķĒ&¼ŹĻĄß 4_/Ć[†~³Ónō+­BHķō›hķš'ž¦…”ą‰ Ä[³yIp1ėõåWņtŚż‰—?ś]»5濟žÅż‰³įæ„Sū ·i[t+QżžL†\ĮūæŻ0—ł1óõ껟(§v ¢Š)QEQEQEW;ńĮ°ü@š†„įū‹‰- ¾ŒÄóF ²©ėŒ÷®ŠŠØÉÅ©Gt&”•™ņßü0/†?čfÕæļˆæĀų`_ ŠĶ«ß…}IEzßŪ’łüĪ/Øįæ‘-’Ćųcž†m[žų‹ü(’†šĒż Ś·żńųWŌ”Qż±’ŸĢ>£†žD|·’ įśµoūā/š®?Ē_±ęį?|;Ņį×u)ćń6».“<’,`‰¦_^\Nė4^{9ļŠūR¼Óāʓ}©xóąÅÅ„•ÅÕ½‡‹n.o%†&u¶ˆčZ“BIE2Kn8¤QՀ£ūc’?˜}G üˆņoų`_ ŠĶ«ß…šĄ¾’”›V’¾"’ ś’Š?¶1’ół‡Ōpßȏ–’į|1’C6­’|EžĆųcž†m[žų‹ü+źJ(žŲĒ’ĻęQĆ">[’†šĒż Ś·żńųW£üżœōæ‚z¦£y¦ź×š‡Ū¢X.‘ݤA\zŸŅ½vŠĘ¶e‹ÄAÓ«Qø¾…ÓĀP§%8A&‚Š(Æ4ė (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ņƎņ1|!’±Ī?ż7_×Ŗ×Ģ’µGķ šėį·~é'ńeމ©XųŠZāŽģ²“vfĪö!7NSĢ`¹ų ¦(ŖšF­kÆi6Z•„ĀāĘņø‚`Øel‘Aę­ŠEPEPEPEP^Uq’'M§’Ų™s’„ŠWŖ×•\ÉÓi’ö&\’étź“QEQEQEQEQEQEQ×5Ņt]Bö(ZāKky&XPeœŖ’äćó–‡ń7Ş‡ĀŽ!ŌÕ!/ŅĶßMלÉū8ü.mbćV‡Ą±ŌīŚf½»ÓōųķdæYC £ŗ1ūLRo%ā—z1Ć%A­Ū] śyŻz[Mī«M/’·ł|ļ®Ē›|0ż„ß©[]FaŽŹEx"ŗÓ­äo’š|²Gb …ż;ćWÄ]oį—†-µmĆqųˆµŹÅuēĻuV•be²Ś]LFࣈJ€Å™‘Tš|?<„čöö„Śm…¢?– + ūJĖ·›mz?Ęo‹1üšż–µs§ FŹkƲH«tČŒŃ»#Ć »ob@7Č~Xڶµ/‡ZäwRZé–:V©4ļ{­gann­ļ @»C$n¦u‹•¾P‚æ-yĘ£”_ü?ń·€-5ßźß#ń6±q¢(ń=––£OOģ»ū§’ken²,L•*ķÅ.–_×[~jöŚŚ^ķ‹M_õēł7ē}•‹7’/¬|Sā ŸéĒWŠ4¹5{†“]Xķ^‚7 ²“@‡ß!V Ŗ#O.F J€ö?~$'ÄoŪŲ5Œęfµ‚is9Ž6eżņć÷2nV $¦0ŲlŖč·ĆŸ µ¢ZŸ čĘŁ!:|;™B± ·•UR{…µsš§Ā]FėÄ·šž—ńÄ~°¼ngŠō« ģr¾ÕY„°’f/·ę&Ryą€ Wi„»[ö×å¶ŗ »’‡_×ü>šłfµū[x‹I🃵ž6£«ų›M“\·ŅtĖKQhōš°•,֚dÅgc:®ĘUˆžæ‘]µūM]h~&‹ĻšŒįÖįkčgøŸW[±dnŪdV®ī_–C!<ł{~jōŸ| št}3Hń‚|;ÆiZX ac©é0\Įh…$t*ƒhå€PÖ>ų'XńʍćųG“ūéw :kvPGw2¬/ Ć,Ū “A_īn¢zb®ė›Ź’…’ĖMüļŠ]£ūķžzśi®ę·ƒ~"i^:–ņ=6Ó]¶kU‰ä:χļō°Ā@Jģ7PF$ ˜&JœĮ"ŗz(„č0¢Š)QEQEQEQEQEQEVG‹|MiąĻ źåž’±XÄf›Ė`£©½kמ~ŠæņD|i’`Ł•kJ*„HĮõh‰Ė–-®‡ ’ ­šćž~/æš’Āųmo‡óń}’€ÆžłńE~›ž¬`æš_z’#ä¶1—ćžgč?ü6·Ćłų¾’ĄW’ ?įµ¾ĻÅ÷žæųWēÅ«/ꗮæČ?¶1—ćžgč?ü6·Ćłų¾’ĄW’ ł×öعų%ūRx«į¶³¬Ż]BžÕ×ŖÖN~ß`F÷µ8Å"GÉč­.9jš*(’V0_Ķ/½lb;/ĒüĻŠeżµ>¢…YļU@ĄŃš?J_ųmo‡óń}’€ÆžłńEźĘ ł„÷ÆņķŒGeų’™ś’ ­šćž~/æš’Āųmo‡óń}’€ÆžłńEźĘ ł„÷ÆņķŒGeų’™ś’ ­šćž~/æš’Ā»†_“…¾,ź×~‚÷2Mo›!–€ ąuükó¾Ÿż‚’äz×’ėĶ?ō#^feįpxIצåumŚī—cÆ ™VÆZ4䕟õÜū’Š(ƀ>˜(¢Š+Ź®?äé“’ū.ōŗ õZņ«ł:m?žÄ˟ż.‚€=VŠ( Š( Š( Š( Š( ŖźZ„¦e%ŻõÄv¶±Œ¼²*żMZÆ3ż¤æäˆų³ž¼ŸłV“”ķ*FŚDN\±rģt?šµ¼’C.›’ Gü-oŠĖ¦’ąB×å=÷’ź¤?ēóūæąŸ3żµ/äüą«šµ¼’C.›’ Gü-oŠĖ¦’ąB×å=Ŗ’ŸĻī’‚ŪRžOĒžś±’ [Įßō2éæųµšßķĮū6č_“7ĒO…Ž)Š|akc§ĖvŗŠZßP˜ķ#W‘n>r‚X7s$]Æ ¢õRółżßšCūj_Éų’Ą?Tl~$xK±·³“×ōø-mćXb‰'P؊UĄ*ųZŽ’”—M’Ą…ÆŹz(’U!’?ŸŻ’?¶„üŸüõcž·ƒæčeÓš!h’…­ąļśtßüZü§¢õRółżßšCūj_Éų’Ą?V?įkx;ž†]7’““Oh~$žHt­V×P–5Üėo b£Ōāæ%kźæŲžF’׬?śם˜püp8iāKŚŚ[»K¹Õ…Ķ"“i8Zž~GŪQE|aļ…Q@Q@Q@Q@Q@rž?ńÜ>ÓģŠYM«ė•ȱŅō›VU–ņą«>ŠX€ŖØ#¹įQó€Q^UćŽ~Ń? bš4ŅõŁÕOA HźIэWŌ&ųįqcs"Śx Ä“lEŗ\ß\“|ž\{¾ÅśWĒ?³ĶÆķ]oū=ų³žÖĆĮ_Ųņż–?nmīüø*r=~љ:`bæHėĻ?h_ł">4’°læŹŗ0’ʇŖüĢŖ’^Œü梊+÷ƒósמė…—†tqįļXxzHuG—Z[J;FžGå—Ge7YG”»ĪK|æ8ĻGcą’]Ć„]ź–šf“įķR9.NØŚ“-ś7ŪäŽ4Ko;żYT1ą|ĒxÅ|ūS\^Ü]GsO,ŃŪ§— Čå„iø¶Õ ÜĢp;’{כSē.hO–ļ¦żzõ³Śś.Ģź§]EZJ’–żŗy÷ņ=ćZŃžhæfi:MÜóŽYŚĖö Ē “ŽlČ Ō. ,`—“ąķĮåŗN±ö? čŬčÉ—{Ó­gÖ"k;¶HŁšŪże¼Ć'7 ¢·žwŸ¢£ź-«Nmė}uūµž¾ā¾°®łcm-ż]qųµj¾ šuœ–Śżž§ygyqw{ ÷ˆ,ī®ā ol<ąĖö³ū²"±ćgU®_ą~§6›­j+ ķ½€ø!’ćūb=*ź4ó—‚y>N ŃœļR@×Īķ/'ÓµšKk˜]dŠh\£Ęąä2°ä@ Š×ń޼KāĖx ÖüCŖė0ÄŪćP½–uFĘ2±ĮĒzøįe ^ĮYÅ’_?½?6õ«)ÉMč×õżio+hzևā-ģ0ĶuŖŁÜĻuēxJgm7Ł$•Żo6øŖ¬ŠĒjņļˆ—°\xš[[I£¹²ÓbN‚hH)* ŠG;|’µ\Õ­,hĶĶ;’_š’y5+ŗŠÖ·õ’}Į_OžĮņ=k’õꟶƘ+é’Ų/žG­ž¼Ó’B5ēēŸņ.«ņüŃї½Cēł3īJ(¢æ>š(¢Š+Ź®?äé“’ū.ōŗ õZņ«ł:m?žÄ˟ż.‚€=VŠ( Š( Š( Š( Š( ¼Ļö’’’#āĻśņå^™^gūIÉńgży?ņ®¬/ūÅ?Uł˜Öž½ł‘^µšēĀ:½ąōŪm>MbśēP¶µ3Kt·nńŚÄš¬?x’7ŒƒĒ5䵯¦ųĆ^Ńō›­.Ć[Ō¬tĖ­ßh²¶»’8fÜ”[z²#1_¶ā)ά9iŹĢüśŒć ©I]§üŠ’į_źž$ŌuķJllmīĘ K9%å+·r-ćH’¬X‰0čVØéæ|)§Łų‚ kXŌ żŽ‘ģĻo¦«„³K%¹_$ż”|āVm§xE$gøŲ~&xĀŚŹ 8|W®Eio“ ŗj3ćM»vŖ†ĄxĄćU+ų‚ėGHŸ]ԦңO-,d»‘ TČ;Ddķ*§ź„r*8¶ß5MéŃ}ßÕüµŪŚQJ6Ž«?Ēśüŗßų+Nµų·s j­mØéöqß1’ėĪŽ[K$o ˆłrŖÅP“Į=÷µ†¾ń k«iŚßöm›Ep^.Āk‹}Ö°G-ĆDn%Ip|Ģ*øÉ!²UpkÉ’¶/Åō—¢öą^H¬Æq귘Į”«ŁÉISź .Ÿā WI’Ńģu+Ė7“‘¦·kyŽ3 ŒgL•ˆUŽN„i:„%8Ōi„o+ė­¶ģLjSWNWü;\ģõO†ŗN‹¤Ķ¬Żė·ŸŁ„¹°htŌk‰ZhäuĘg [ ‡|ä8Ö“«;=5õOŁé÷W “[4–eŌK ‘)» œ”RfXTnĪāĻ|M õżģ~"Ւ÷PO.ņįo„\Ø #nˌqƒš³ań;Ę:]µ„—‹5Ė;KQˆ ·Ō¦Hā# ”°¼ÓŌŌŹž.Žģ×įŪÓž²ŲjTzĒśū’Åōī¬~ éģóy:ÅõÄ)yö‹k‹(‚Ū‚g¤^`ˆŹĮLDŗįä4üÓˆŽoāye·µ»¼²æŗšĀ82[Ę”/p£·tź3ÄŽ|Ińv”n ŗńNµs³øŽmBgPĪ\ą·VąžįŪŌŌŽų‘¬xW^:²LŚ…Ć4²0»øœfI(xäIB?\1A ē챉9{MlōÓ~?®·+Ÿ¢åŅ’×_OĘĘw‹“‹ ėŚ~›©lY۾Ž¢ v;©ä¬AĘAĮƤ’`?łU >gfv8Q–ff'’IƤ’`?ł÷ßų’ć^łEŚXßłż/ü ‡Õ0’óķ}Čš?ųbŸ‡óļ}’Ož5Ć|Jż–|į=_ĄÖV×>^·ā$Ņī¼Ė‡'É6—R¼šwBœżkėZņƎņ1|!’±Ī?ż7_ŅžŅĘ’ĻéąL>©‡’ŸkīG1’ Sšćž}ļæš)’ʏųbŸ‡óļ}’Ož5ļ”SžŅĘ’ĻéąL>©‡’ŸkīG’Ćü8’Ÿ{ļü ń£ž§įĒüūßąS’{åicēōæš&TÒϵ÷#Ą’įŠ~Ͻ÷ž?ų×cšĖöš·Ā]ZēPŠRę9®#ņ¤Ģ\œŽæz]Lv*¬\*U“O£løįčĮóF ?@¢Š+„č (¢€ ņ«ł:m?žÄ˟ż.‚½V¼ŖćžN›O’±2ē’K  U¢Š(¢Š(¢Š(¢Š(¢Š(®Sā—ƒgųą=cĆö÷ŚK „M(%S=š:×WETdį%(ī…$¤šgÅšļżcž†ūüž*ųwž±’C}žæ’_jQ^÷öže’?’‘ę’fį?“ńę|W’’Ö?čo±’Ą7’⨒‡ėō7Ų’ą’ńUö„oę_ó÷šłönł?žgÅšļżcž†ūüž*¹~ĒŸ„üAą.OŚ\?‰õy4˜ä[fQ%…Żęņ7r³dĄīąöÆ¾ėŹ¾2ÉEų’cĻž£ŚĶŪł—üżü#žAż›„žOÅ’™ąšļżcž†ūüž*ųwž±’C}žæ’_jQGöže’?’fį?“ńę|W’’Ö?čo±’Ą7’⨒‡ėō7Ų’ą’ńUö„oę_ó÷šłönł?žgÅšļżcž†ūüž*½söużœožkµŻÖ³mŖĒ} FZ2…Xžäē9ż+Ž(®|FoÅStkT¼_’õč)ąpōf§ŁÆ7žaEWŽw…Q@Q@Q@Q@Q@yW?äć¾’Ų^’Š“śõZņÆÉĒ|/’°6½’”iōź“QEQEQEå_?äbųC’cœśnæÆUÆ*ųį’#Āūć’Óużz­Q@Q@Q@Q@Q@yUĒü6Ÿ’beĻž—A^«^Uq’'M§’Ų™s’„ŠPŖŃEQEQEQEQEQEQEQEW•|d’’‹š'žĒ;ŸżGµšõZņƌŸņQ~’Ųēs’Øö³@«EPEPEPEPEPEPEPEPEP^UćOł8ļ…’ö׿ō->½V¼«ĘŸņqß ’ģ ÆčZ}z­Q@Q@Q@yWĒł¾’Ųēž›ÆėÕkʾ8ČÅš‡žĒ8’ōŻ@«EPEPEPEPEP^Uq’'M§’Ų™s’„ŠWŖ×•\ÉÓi’ö&\’étź“QEQEQEQEQEQEQEQEšoķįšOć>?üæųwć_čŚ&«©ż†ķ,odX“{…‚`÷±Ø8R֏t‡®:É_Jüvż„<3š>ÄĆr’ھ#•7[čöīć³ŹÜłiīFO`pqłŪńć7‹~)xŖZÕe[ĖWße£4QYrņ@9R6w “Š÷°=|rēųcŻõō<ģN:žņīĻ֋EÓģmķVIfXcXēČd‘‚€2Ģyf8äžI©ėć?ŁćößKŸ²ųwāDė ĈķüC·j7`.įOo0qÓp,~Ɇhī!Ibu–)2:UŌWŠĮÖĮŌöu•æ'čtŃÆ ńęƒEWŠQEQEQEQEQEQEQEå^4’“Žų_’`m{’BÓėÕkʼi’'šæžĄŚ÷ž…§ŠŖŃEQEQEW•|p’‘‹įżŽq’éŗž½V¼«ć‡üŒ_ģs’M×ōź“QEQEQEQEQEåWņtŚż‰—?ś]z­yUĒü6Ÿ’beĻž—A@«EPEPEPEPEPEPEƒćoh_¼?>µā-J3O‡2S˶2rĢp~P āŖ1rj1WlMØ«³qŻcVf`Ŗ£%˜ąė_!~Šß¶õ¶‹öü:š+ė’™'×°{bx‘æŪ?(dz‘āß“ķm®ü`i“ M ųK$UlOx;˜ŸōĢqĻ%°šū¬·!Qµ\Z’·ĻüÅęW÷(}’äXŌ5 ­Zś{Ū뙯o.É5ÅĆI$cÉfcÉ'ŌÕz(ƶI%dxźĀ½Óö~ż«üPń'ĀG¬ųoPk;Œ4-óCrƒų%NŒ:ūŒäyÆŃ?€µ‡>6Ś„‘+£x¦5ĢŗTĪ›’š·ń®2Hū˃‘Œ1üŪ2Éźą›©zśÆ_ó>« ކ#Ż–’=¢Š(ƞ=@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Æ*ń§üœwĀ’ūkßśŸ^«^iāŻ&śēćēƝB+‰l-tj;‹¤‰ŒP¼c嫸RŪžv¶:ōŗ(¢€ (¢€ (¢€ ņƎņ1|!’±Ī?ż7_תו|p’‘‹įżŽq’éŗž€=VŠ( Š( Š( Š( Š( ¼ŖćžN›O’±2ē’K ÆUÆ*ø’“¦Ó’ģL¹’Ņč(Õh¢Š(¢Š(¢Š(¢Š(¢Š(¢Šć~.xśēįŸ€µ?ŚhWž!šŃr,ģśŻÜõ½X€Hć#ņóā‡ÅÆ|`ńÕ¼I~nw {Xņ¶öŹOŻ3ĒA’rNIÆ×Złgöˆż‹tļ}ÆÄ>Ž#Ä-™&ÓøK[ĘīW“R_ŗO\dµ}6KŒĆajZ¼u{K·łzžN>…ZŃżŪŃt>Sš&¢Ē¤ųMƼ2¾%ŸÄš“–#\Īlˆb]°ˆ™@”ł„³&ńŸ.3›ž ųM¦k'‰Œ’Z]\Kuqc¢Ļ&§ ¼†Hød‰ŻZ1ŒQŖŲŽĒāøxuĻ|'Õ5ßS×<'~²¼“¶ŗ–Õ‹ņ— Fīž˾ńfÆØjŃjr_Iä2łš=Øėīßŗ%Œ*Ęw|ß(óÖ¾īTźŌ»§=[·ę“ŪĖMśŸ9Āꎫ§ß}wķéc­ų…6ˆ¾šœŗw„ō½ļU²{Éī­'¼w —SƵD·”JĤü¤ē8 qV¼'”čwŸgōXouČ|ėéEü—P<Ö±”ęÕŠł,«¶A"Čsņ6x^7JńAµ»Ž][O·ń<DŃCk«OsåŹ˒¾L±°;™Ī7`—bA'5oVų©^i÷:^š_þ¹ĆM”闷FŹWķ³I¹ŽÕź„tÅ[§4¹#}ļ{łķ½öéų­ÅĶ%'²éoėśļ³õy> ųpI%²E'˜ŗÖ„¦gÉšńm¤€8Ü>öģ“Ķqśn—įŁ>Żjoe¢Å©Žjw–ÖĖ~ڃŻX­ŁŲB|¢ŹengąäuęøEńF²¤‘«_m?³Ī._›nžG_õģtöŖMypֱړņhŻ„HKŠģ3č  žūG„(aź-'Q½æÆĖńŖĘ÷ŒÆųv’ĒÆxąŸ†|7«jjĖ©-&/ Ōvžm¼ŃÜZ!č·“*¶.H"C‘†2U—ˆų‹cƒ~)x‚×E2iŃiš¬Éfa•÷Ą#ģ*äīČĄĮĪxėTµŸˆ~*ń&=[Čʧ–a)y,«å–V)†cņīD8é•SŲW¹|ż“ń×Ćy„‡ĢOĖo¦VSµC½Źa•ł¢a‚zōśN¼EDӔZNĢiŁÜłCĀæ|kąƒžÖuøų—Ŗė>—ĘZŽ¹{k¦-œ0Åle‚Żm,p䵥*g†Ģw’æii<u{§iŽ“]ÖU‡Kµ¶‹ķ³,¬ÖBńŻÖĪĪźd ™,/“‚J‚Hõxüįčm-­cŠtČķm¬[L‚³Œ$VŒ5ŗ®Ü,D"eŹv/ ē“ą/Ć8ü)/…Óįׄ×ĆRĪ.¤Ń—Cµo0é!‡ĖŲ\{­jK›įVך¾ß(Ły°Ņ÷é’ü’wĄ~&›Ę^ ŃuĖ*ļCøæµŽā]6ś"šŁŁrŃ²Čˆąƒ‘ó*ŸU+z©hŗ.Ÿį½&ĻKŅl-t½2Ī%‚ŚŹŹ†#Q…DEU@ą0*ķµŻ¶"7²¾įET”QEå_?äbųC’cœśnæÆUÆ*ųį’#Āūć’Óużz­Q@Q@Q@Q@Q@yUĒü6Ÿ’beĻž—A^«^Uq’'M§’Ų™s’„ŠPŖŃEQEQEQEQEQEQEę¾xcć~ŽaÕ ū&­m“ÕķŌyšw’}3œ”õ8Įęæ9ž1| ńGĮ=oģz寙a+bÓT·Ū܎øų_Õ#Ę żd¬æxcJń–‡u£ėvjzeŅģ–Śįw+Ē؃Č#@ ƒ^ī]›VĄ¾WļC·łv+ BŗŅ]ĻĘŚ+鏦#ö5Õ¾żÆÄYõæ .d–×ī¬W¾@’Yžšä¼0 ™ėō¬..Ž2Ÿ“¢īæ/Så+Q rĶ\Ņ4{ļjvŚv™g5żżĖłpŪ[”y$o@£­uß ~ xŸć>½żįū<Ć Ö”>VŚÕOwlu=”eŽŃŸ’³·†>éƒū>/ķ vhĀ]k7²w*ƒŸ-3ü ö,@5ęę9µ, å^ōū™Õ…ĮOīōsČgŲžĒĀæeńā‡TÖ@‘%µ©ė™I\z}ĮĻŽą¬)hÆĶq8ŖŲŹžŅ³»ü½¬£F#ĖQErQ@Q@Q@Q@Q@ĢK1  d“ŠW–ĶūQ|+Ži#‹Ęš~ Š4ŗh’ņ ĄąÆ™ ²äwČØž6*ųÄ_¼t¢Mļͫ[0Ź]ŚŪZM8·oTy– ŹxdWFČbŖC všĒQ¬QF”R4*ØŠP–ĆR|0’”›’$.æųÕšŌŸ ?čf’É Æž5^­EyOü5'ĆśæņBė’Q’ IšĆž†oüŗ’ćUźŌP”’ĆR|0’”›’$.æųÕšŌŸ ?čf’É Æž5^­EyOü5'ĆśæņBė’Q’ IšĆž†oüŗ’ćUźŌP”’ĆR|0’”›’$.æųÕQ²ürń׃o“k;ųü#į{éuyµ[ū)mśčŪMm $Ŗ®č¢ęIZPf8ÕKī}žÉEQEQEQEQEQEåWņtŚż‰—?ś]z­yUĒü6Ÿ’beĻž—A@«EPEPEPEPEPEPEPEP_&žŠ?³ƒuoŠn- —F_x‚]3T†Ą„Õ4Ūėß5Œ#³YŖ8!ÉĘīOÖUå_?ä¢ü ’±Īē’Qķfŗ(ā*įåĶFM3*”įUZjē{į/莊mt]N‡KÓ-—ŪĄ0=Ų“Ė1īĒ{šŲ¢ŠĮÉÉŻ½MIYQHaEPEPEPEņēķ3ūb'Ć]BēĀŽH/¼GĖw}2ļ‚Č‘÷ĻĻ ļŸ•O'*:°ŲZøŗŠ•vcV“(ĒžoCź:+ņÅüićK‰fÖüU«źBIīŻbą…HEĄ\ĻŚ§’žņ’ßĘ’śØšĶF½ź©?Oų(ńžméÄż”¢æ¾Õ?ü÷—žž7ųŃö©’缿÷ńæĘÆżY—üżü?ą‹ūY'ć’ś·öȟ濏ķuš{Nų®E‡5éäŽĀy4ø'Lā"—¬å–_³“(Žy;Ąū¢¾ņLqŖ—i € ¶2ŽēŹæšiY”™d%NA.xķėNūT’óŽ_ūųßćGś³/łūųĮķeüŸüö†Šü^ūT’óŽ_ūųßćGڧ’žņ’ßĘ’?ՙĻßĆžk/äüą“4Wćv“ā½sĆņ‰t½oRÓ%p{;É" śåXsļ_Gü żøi›Œrņ1ć’NMš¦ü]’EŪāžų{’•Téz¦©e”é·zŽ„wŸ§ŚD÷7wR¬QC‚Ģīģ@UI8Vgƒüyៈš9Õ¼+ā-'ÄŚP‘”7Ś=ōWpoP .ųخᑑœŒŠóO|ńlŸüo`Ÿ¼YćK½K@¾°“Ņõx4xb3Ė ,l 0< ϳę9·œųūį—ÅŪ/Š^žÄÕ¼Yām2Ņ[ .õū½F8cxÅŁkˆf·¶æ±¶ażrĪą¶[×õż~—Ću¾æ§łłķ±õ&—ŖYkšm®£§]ĮØi÷Q,ö÷v²¬±M «£©!”‚ ąƒV«āė†?t x Mš¶‘Æ[kz_‚`Ņf’ć\Xt{+Ä“uÜ M²+¤Ig2»y{f…Wxģž|ų„.‡©·ˆ~$|AšNnók„4:]ĪŌņŌ3‰onu©˜†¹PqeĶ$žŠ’æ-E/uŁZKśGÓŌW•Ā›ńwżoˆųįļžUQ’ oÅßō]¾ ą‡æłUPŖŌW70ŁŪĖqq*AHd’Y*¢’Äž½yü)æŃvų’€>’åU`|@ųć]sĄ~$Óm~5xēQŗ¼Ónmā³¹“Š)ŻāeXŻ—KV ĀH`@<ր;/ŽŸĆ_ƒ¾!ńE”ˆ÷0ځe"€źf•–8›uo 5ł=4ņŻM$ÓŹóĶ#ydbĢģNI$õ$÷ÆoŅ?c/ˆ’³_쳯ĀWń>’\¶WµųFÄłŗ]–g@Y^U/Xåˆ×®CuÆ ÆŃ8nœVuķŪīGĢf²~Ö1é`¢Š+ėĻ +cÄ^ ń„ZÜkŗ„¢›€ZØŚIo恌•Ž@Čéź+!~博¾$xÄ0‘ŪYiqė•Į·X„’ §–,[ŽæåNåPéåŗš¤E÷…r׫:n<±ŗÖ’+[ļž»­©Ę2½ŻæÆėž ²>Q_IjŽ>š.­§M¤­÷†llŻ.ßģƒ0y&²HćøIO…£Ł2īp±”ąm €+…Ö¼AįMĆ·ÖDš>§ ÓmāéEƒĘ°J.ž34A™ >Ļw¬iāg=6žś»on›ś|Ķ%F+U5ך’?ė£<žŠōŸŠŽ,š÷Šėū&ÓLµū>±t¶_ŁŗjŁęĄ„ņ·ķEŽr/—=«Ķ«ŖGR RŸcÅEŁ;’_Õ¼‚Š(­ŒĻŗąŸ?.5OkŽ ¼—ĢS-ķ€c’!‘"EW¾²šśŚŚśŚņK˜ķī"žKi<™Ö7 b}ŖŪŗŪYN8`{×ę/ģŁš‡Ä’n¼k„ųgĒzĒĆ«Ÿģo$ėZ2#8g™ ĘłĆ"79Ńž^Ū’c_ŲĒāWĄŸų£@×¾,ėŗ%Ķ׈ī5ŸĆ ¦ÜŪŽĘööź.ŽŲĶ*ŹĢŒ¬»‚ü€€rYæ(Ī©Ęž:j=lžō}žNXxóiQ^U’ oÅßō]¾ ą‡æłUGü)æŃvų’€>’åUxg z­å_š¦ü]’EŪāžų{’•TĀ›ńwżoˆųįļžUPŖŃ^U’ oÅßō]¾ ą‡æłUGü)æŃvų’€>’åUz­å_š¦ü]’EŪāžų{’•TĀ›ńwżoˆųįļžUPŖŃ^U’ oÅßō]¾ ą‡æłUGü)æŃvų’€>’åUz­å_š¦ü]’EŪāžų{’•TĀ›ńwżoˆųįļžUPŖŃ^U’ oÅßō]¾ ą‡æłUGü)æŃvų’€>’åUz­yR§žŌ’<¼]3Įā;¦ˆŚā÷tJ} ҜĄQ’ gÅmğž Kį“ģšn›—K > ƒčk²šG€ōæéÓŪißiž{©¾Ó{Ø_Ī×W“ d–V9cµU@įUUUBŖ€::(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€2|[į›/x_UŠu$/c©[Ik0S† źFAģFrØł;ńKįŽ³šĘW¾Ö¢"hNč.qĢ$ü²”īčAkõāø’‰Ÿ ü1ńwBžŹń6œ·‘!-čÅ&·b>ōn9§AÆw*ĢŽ_6¤Ææłžv3±1VŅHü‰¢¾ÉńGü¦õn%xŹ $˜ąÕm ŗŽĄÉ!¾”ҹŸųwŸ’č?įæūūq’Ę«ļ©ęŲ:‘ęŒ’žGĶĖ^.Ī?Š>\¢¾£’‡yų’žƒž’æ·üjųwŸ’č?įæūūq’Ę«_ķ,/óžüˆś­oåü—(ÆØ’įŽ~?’ ’†’ļķĒ’£žēć’śųožžÜńŖ?“°æĻų?ņŖÖž_ČłrŠśžēć’śųožžÜńŖ?įŽ~?’ ’†’ļķĒ’£ūK ü’ƒ’ ś­oåü—*K{yÆ."··ŠIī&qqD„ŲœrI=«źż'ž Ūā©„TńnepZĪ n\7—łgńÆ¢ž žŹ~ų3q§ Ė®x…TŖ_˜²0|ØĒŹ™łnH݃ŠóńYę„_#ę—k?Ō飗֨żķģ›šFoƒ?˜j‘"xW]_…!¼„C‘×h$ŸöšHĮÆm¢Šüڵiā*J­MŁõtéʔ#² (¢°4 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€?’Łqatengine-1.9.0/docs/images/qat_engine.png000066400000000000000000001107021500416242000205040ustar00rootroot00000000000000‰PNG  IHDRÕBŁjsRGB®ĪégAMA± üa pHYs%%IR$š‘WIDATx^ķ¼Åżö‡ˆ" ½)*Ҭˆ ‚ÅŲ5‰S4¶æ½7ŌhŒb‰Sģ&–WT$*5D°¢ŅT@A:b}ļwĪžĪ»gϹēŽ{īåœ{Ÿļē³gwg÷ģĢĪNyę7³³~(Ć !„BˆEk!„Bˆ‚ q!„Bˆ‚"q!„Bˆ‚"q!„Bˆ‚"q!„Bˆ‚’ų¶Čm¾īīxųh/ÅąžŻÜgķķ9wĻŲ·Üu{9ŚKŃÆWgw×ÅE{Ī=>įwѨ磽łœ³e×ö‡E{Ī=’ś,wśu㢽;“pOŽzl“ēܤwē¹.}<ŚK‘Ļ9-š7qĒ öœū`öBwäŁG{åLyšäh˹y_¬pCN½'Ś+'Ÿsš ?aÅŹ5nĄš1~;„0v£ļ·G[åäsqH\ų…Ÿ!< ž‰A˜ {H>ē6H#qH\†\6b°;hŠ–ŃžóĻ‚g’Ļ9g·›;ö€ķ¢=ēÓi$ä¤Ćvt§Ń?Śs>‘ÖBņ9šĻ Ķ“öC/į6’ņO>ē()ŹcŹcF±ē±lčUT!„Bu‹!„¢ H\!„"oā]I$Š‹¤¾E!„Bˆ¤qLqd¹B!DA‘øB!DA‘øB!DA‘øB!DAIœē‚ 8‰a„B!€ÉµĀ ꒩$ZB!„((źB!DA‘øB!DAIłL!„Bˆ†G>m&޹ąį—ŃDńóżß¹×>ļ>^<Ķ}ŗō#7wéŒčˆBdg£–]ŻĘ­»».m¶r»tŻĻ­»ĪzŃ!’ÉG#Ø[¤šŽēÆŗæ¾r¹{`ņMī•ŁOKX!ņę³å³Ż¤Ožs’ž:Ź)+GŽłģ•čˆÕGā¢Ä™½xšżæĖÜ»*„5äżłÆ{A¹"DMø(a­üĢ=żž?|—ˆBŹ“§ßū»/_„Ø.‰ā⮋жD1óęœÜó߈ö„¢0|°`²{kīKўyņÖc£­ģ$Š‹~½:G[¢˜łl٬hK! ˜„Ó£-!*RŁģœ n‘ęóG[BQXT¾ˆš qQĀĢ“åBQKØ|5!Q\ 9õžhK!„¢œ|&ŃJ|ńL!„¢:Ø[D!„EāB!„EāB!„%Q\h-!„B$ńĄČĆ¢­ģ$Š M¢%ŻŪoė®=ų1wćĻžvūoóĖČU!D[vmmeGŻ"¢$ųYŸ¾ņgAlæÉ£#å˜@ąÜŖ°I«n½ušųķĪ­ŗūõŚäŲ~g§ļįēŠōĒĪŚė¶ČE!Š ‰ Q“iÖ1Śr^$YL „ēęÜe3Ü×ß­ńŪó–ĶōėµÉśė6‹¶RĀ'NóõZśõŗė¬ē×¢ś Šjēķ3:rB‚Dq”I“D±²tõB/:l°q¢õ¢:Ģ\ųŽ;籃Żé’ŽĻ=õŽß#Wѐ@¢ź >&ŚŹN£ʈ¶Ó0ū֔OŽöD±BeŲP8~×Kܶķā¾ųr®[õõ ·YŪ­ÜĒ‹§¹›&œį| Žłģ7ś—ųm¬ĒķtžŪØU·“e#äļÆ]ķ׿Üé\æ~fڽ^` \pCČ\3ž×®Ąyüķæø7ēü×’‡n ¬ +æ^ī.xā’·÷_üł.˜ān{ń’¼{>Ų½Ā#Sos/ĢxĢovŸÄÅUĻļ·ńoČ6Ć\ĻŪ¹ÖMSż”„gį—óÜß^»Ź-YµĄ»ŃåŅÆĖž~jēM½ÕŚēT׹쾷’|pś¾Ā8ø’?zk¢.Œwŗ ¶ź“£wĪåƒzæs—mtėüvąõžXųæ=v‡ō9Åoēƒ6?ŌĒUü™†’Ÿ8ćq÷ļ©£üv>¶ŽwKĒĻķµŸ©š|“ MXš,6iŻ3} Āg÷Ö°“&DH>AŻ"¢ä pFҘ„SöøŚŸ—$,ŒMZG[åc.Ģ’±ē-®AEsŌŽHū=łÓ ~Ą 2*6;Ü“śumrĀ®—zŃ`• ĀĶ1Ćŗ\Z5mēNŚżŹ“°¶ķ{jŗ[)ŒÜM@4[/õEÄÓŻäō8(ķœ‹Ÿ\›ų”¦BܰGŁ’De欬āĪ »µvķ:$ŚrnŹÜ¢­Ź±°…ńĮö>[“÷ ]®Č ÆAųdBˆÜH\ˆ’¢UYAVXm{‚_'AėŌ*>ZĒXz&}ņœß‡Ėžžeŗ…š‹uĖ*Lū?V µŠÖ4•$lŃq{_©²ĪÆI+—Ö=­ĒpÉqB«›proöį©P@6nĖē[|ā>xóĢ×ĢpĒrĄ¹÷O¾Ń‹*ZĄü ć—ų±gcbü7ż\ŽOuĮN›’†_Cč?–Ąźo<†aĆjŻ»čŸ;īX€5ū, ÆAÜš{žBˆÜH\ˆ’¬”õ"l醄 KqϤ‘~ ½7Ś5ŚŹĶ‡ ŽL’?4ˇ/_šł„_>Zķ¬é"؊æ&\÷ģ)¾;ĮÄŻ ‹WĶ÷ېdį™šŃæŅ].”čѾw“U¬Ż •|Æ īč^±nā!t#ēSÉ¢ā€må·©ŠĶ’ē?zŲĒ˜’¤AŽ+Ö,¶R“iÖ!ŚŖų_˜³tŗ_[<Ąż“’˜ęn‚ ˆ'Ęj–ī'“`üoö“ŃVå„a ->6ĘBį™Dxš>C!źłL“™(.÷Ļ4£Ö3gĪt5ņk!ra­mė‚ˆC«Ųŗ+¬{q €ˆWŠ5ÅĘ"6Ø»Éč~÷ć?fŒ(& ”Ų€nķzE[)&ś|“•ź1 FUŗDņ%.–„ł“ĻD›5ī110bDÕ&.ʇ_|Ń_›uu9r¤Ūoæņ–Žż÷ß/įR0ė•V’õk&pZĢ&2X§ŽŽH~S ŗ`5°q Ö-@—Meę÷B€&*`ć*мI«h«b· oćTFxN¼[Š·+ĄāŽŚįtæĘĶ,;l:ØĀC1Č[6V¤*]"†-“ų„Kecmrݟ¢rj,.~ųa·ļ¾ūŗŪn+ül{챇ćMYօਣŽņ×ėŽ}ķĻĀ( ƒY/،ālY4Ø(xE”J…5żš…4uSł˜õ±óü‡łmßL`ė 3‰&Ø.”‰’«oVł{ćśVÉgƒ×?&„?|ā“%F[Ł Ļį5]«€év2”3kŃ{~ąäĶʰb,. ē.M ’Šv‰X·Ļ){\¹d†ó,lÄ "0ifS sē°Nŗ?īO3£ Q9‰āāȳ޶*ē¹ēžs\pX ¶±Œ1Ā[ Xģ8–ˆž={zĖ‚c;N¼‹Äöm1Ā똄Ļ9ē7nÜ8ļĪ9f 1ā׳š™»Y:X’Ā'Ö>f½Hź°Ł69fżī,ĢKĮk†VéŌ”£vųCŚäŲ”no&P©Śx{Ķ•s“Ę@T—°ÅO·÷ČÜIqB8˜ėį¢żžž¶`uÉg*ēŲ,4\­Ū)¼Īą-÷kˆ‹…Q>‡ųk»ń.»§pLD®oÖ£-:öM‡8”ė(Sņńāüšøą<Īa ox »?īOo‰†N>m&Š‹f§2UeP SycYŲsĻ=ŻŻwßIĮ±®]»zkĮĉŻŃGqnƌnöģŁžŪŁčŃ£‡»ļ¾ūüX›`°ė°LŸ>Ż‹‚Q£F¹kƽ֋ÜĻ>»| ŸĮõ—…š…]0ÜĒ8'Ÿš‰Śƒ9X„B…ŗ[ßżēĖ?N›ąCh1Sa0NĀžw³h$¹vMĀDÅHįk§¼AaēŁœ!oöæh+»WžŸ4čŌ*½o¾ūŚÆį_SnM ą^Ÿ5’ĘšŚØ üB¤Żüß?ų}ČĄ^ܳ…xøqžƒµĘ½vŠ{ųvMh½ ž,L­KdÉŖ/¢­dš?)lń.1ŽnĮĶžēXœs ŽYڲ8āU\!2󾨼ė“QYåYķ:©Ü©Ų©Č©x©¬©¤év ‚Ē¢Aeo`­02`Ą_qX† ęvŚi§ōuĄ¶ēĶ›ē‡×K‚ė t„ĖŹÓO§^AC8˜æ„°Ų1ĄŚ:ģ°Ć*Ü XŲ ÕES0ó‹ģš½,T0VŁ!˜TŹZźįlŒµ…'UĮå?cg!”[ ×ģŸÅ]&ŲžüĀ™iĮ†ˆ¹Tņw¼t~‹†Ø°ų§Ögč¼óĪ;ŻĄż6•02c0²A=gΜhÆ"ü’“O>‰ö2įü? …u_`-ÉüŠ½@X –DżĄśłs Ī›½ųżh«v±q“‚y-SdgćÖ©|I\…Ā,@¼ā+a!DqSmqĄŗ¬bgKA6°:l²É&Ń^E°|téŅ%ŚĖ„’%Y-l,ÖŗAņæāŻ †Ø˜y+EŲļnV ,Iꞌ`‡Mū7]uåg)B7нucƒ;–ˆ3ŗ~‰ЄÅI¢øølÄąh+;÷Ž{oz<ƒ-ŒMĄr`•6bĆ*ŗ!Ų»膄 ’£K$ü’są?Ö-cü -ˆlŻ(ųŹ6ʂ’ņĘ ]"¢~@ßz¼ßØ P—]ĢžÉ—W×v7Deć9Ö66蕹½2ū)æ X*čŌģ˜B¬}ņ™D+qĢE>dƒ`cØŲs±Ļ>ū¤_SE|p¾}`Ą%%š¼*J%Ÿ4ęa’3,čXMŒSN9Å[l§ĆÆŻvŪ­ĀXųõ,|aLøhĢ…¢””1¢ŗT[\TFŅ€NĆ*õZņŗĮ q!„ØM$.Du©Ń€N!„Bˆ8‰āā„K¶D1³aĖĶ¢-!„(,µŌąv‘Lµ'њōī¼h«ś0~"Ū`JĘ-ØK¤ęlŲBāBQ;tj‘żķ=ѰÉg-u‹”0µRĖBQ;lÜŗpSŌ‹†‡ÄE Ógćż–BåJŅDžȉ‹¦S‹MŻ®]÷O4K!j å å å‹ÕeKʈ¶ÓtīŠĀmŁ5÷EqĄ¤C|.śĖ5K3&‹BˆŖŠ„Ķ–nß­uż7Ū;r"“-»¶sŻ6nķ%Skó\ˆŗeõ7_ŗ żŪ+ćÓ%ł}!„ØŒ&›ŗĖ)›µŪŚķµÅéé×…Ø B4 0T&+…¢ H\рhÓ¦›5k–kŻŗuä"„…G“h !„"oŽ<ūįh+;µ6‰–B!źĢ®ü彊*„Bˆ‚"q!„Bˆ‚’8 ³ļ·»³ŽŪĶ{Ąv‘‹s§_7Ī=’ś¬h/ÅI‡ķčN9¢“ēÜE£žwOų ŚK‘Ļ9ųƒĘu{ŁŻ3ö­h/ÅAƒ¶t—ķ9wŪƒÆ»;~#ŚK‘Ļ9ƒūws7žµo“ē¼?ųŅÆWgw×ÅE{·—p‡äss…<0ņ°hĻłų#C˜SäÉ[öR]Rń1/łœÓ¢y7qĢšh/e¶Jź›ņąÉŃVj~ų¤Šäs~į'¬X¹Ę >Ęo‡fĀn®āäsqĪ»‚_ų³ą™„9>’}>ē6H#q7’ĘHkĻ"Ž•˜Ļ9k#Ł€Īæ<öžņX€ņ˜ņ˜QÓĒĶĶö+ƒ’ŚfΜ¹:7räČ“{øģ·ß~īÉ'Ÿō×·}!Dń“!.ā#Z…õ*÷ø3fø‰':†_Żwß}žŲAä¦Nšóų¢E‹üv¾ąß<ąĪ;ļ<æżõ×ūuȾūīėż1æĘē~žóŸ»yó*¾Ń „(nŌ-"DÅ*ģ¶mŪŗ=öŲĆocYø’žūŻāÅ‹ŻŠ©×!³o×®wĖǼėŃ£‡æN.‚_żśõsK–,q V|ķRQÜH\Ń@A0`)Ą2ѳgO_™Ó=a•~eĒ«ēßvŪm^,tļŽŻyä‘^4Œ=::#“;īøĆMš4Éæį²Łf›E®BˆµM8÷F6$.„hĄ<żōÓ^<Ü|óĶn‡vp“'OvG}“Ū|óĶ}7FeĒóÅDÄį‡ī×Gq„_ßyē~mŠ bć-Ī=÷\/Bžžy×ŖU«č !ÄŚ&œ`.ā"Ÿ? !ź, C† qgŸ}¶·J`­ĄŖ0~üųJēV‹k®¹ĘoŸsĪ9^8ōķŪ×ļ#\ø¦޹ ė…c}śō‰Ž !J… q‘¹CQśšcčī0+oe¼öŚk~{ٲe9ļ²Ė.~]ˆÄH(lĄ&\pĮ~-„Ø?Ø[Dˆ Ö*x¬ˆ, ¼²Ļ>ūø±cĒzKE®ć”EwėΰÅ0ńˆ®ĖõŸ{ī¹ČUQģ$}k'ަ’¢”éæ…5q~ä,‰ ĖEü yB!„U!Ćrqļ½÷F[™tźŌÉķµ×^Ń^9Ó¦Mó£Č³1pą@·É&›D{å<öŲcnåŹ•Ń^Eš7oī>ųąhƜ9sęø^x!ŚĖ„ķ[mµU“WγĻ>ėęϟķerĢ1ĒD[åŠOüŌSOE{™ąžÅyå•WrŽ¤ē¾øæÆæžŚ=üpęgr āxŒóÖ[o¹wŽy'ŚĖ„ēÅs‹ƒ_ų™­Ūż÷ß?Ś+‡{āŽ²A<ƒ’ā‡Äeė­·ž;ģ°ĢÆšņ¬xfŁŲvŪmŻvŪ•Ś mF²_ųB$-fƒ{J_@š'ķgƒ8$.ć(•£ź&L˜ąN;ķ4æ/„UA“h !˜½Šmٵ}“—ŒŽ)q^zé%7nÜ8 !D””<™8qbä"D&• Č-š7‰¶D±3}śt÷śėÆG{BQ(Wf̘ķ Qu2ÄÅÄ1Ć£-Qģ|ųį‡Yæ„(„Յråƒ>ˆö„Ø:ź)aÄ)„µĮ‚ ¢-!*2`ų˜h+;%Ģ'Ÿ|m !DałōÓO£-!*²båšh+;ā‚Q ¢4Šė¦BˆŚB勨 āāȳ޶„B!ŖŽŗEŹčٳ§»’žū£=!„BŌ„‚Š‹#FøF%.3gĪĢZ‰ļ·ß~éóF޹V„’Ł9\Ēą|ž/„BˆŚē®‹ж²SPq1jŌ(Ē„Ÿ,=zōp÷Żw_zæ{÷īŃY11aē=÷Üs~?arōŃGū÷®9ēŠ+®„A¬UvŻuWwłå—ūe³Ķ6‹\E¾“nŻŚ]tŃE>ž<šĄČUQ ōėÕ9ŚŹĪZļįSŠ”šxśé§£­ręĶK}©ÕĪ;ꨣü‚„äœsĪń3Ź…VÖfåˆ[5°zŲ±_|1r-‡’†–Ѱ读wZ40 r6vŲaæ^µj•ūų揿vmpź©§ś°œuÖY‘Kżą'?ł‰[wŻużöŪoæķ×k‹įƇ×Ė8bm’ńm‘BA…`$¹QĮ0Ą]{ķµīģ³ĻŽ\3± ŸY)CX;L”p½{ļ½×[Q ō”@įÖÄ ’³s I-EIĮ¹šĀ £­ĀA+|Ļ=÷tķŪ·w-[¶ōnß|ó[¾|¹ū'žxĀ»‡v˜ėÖ­[:Ģ„QzĻ=÷ų} µ|Č!‡ø 7ÜŠ5kÖĢ»-Z“ČWn|›°H 2ÄoO›6­Ā’ ®sĘgųmŅј1c¼(9āˆ#¼[ā?ĄÕ!§všk×®ß.äóĪ'.€ū"N81@Zą¼^x!- ˆū>}śųķ»īŗ+Æū¤"ēYńœ®»ī:ļ†ĀŸ8ųW›iƶā8 ėV[m•¾OK>ų [ŗt©wƒ|Ņ3–ž ƌŽyē‘kaAt QÖŗå‚䊯"“>Ä”pApŽ $øž ą\›‚žĢ3ĻōۈŒŠJBaYJĀ¢6Ą<}ÜqĒłø±B (Ą(|wŽyg_'žx¢ÆÜĀ0³M!NÅT¦æžõÆż½Ye ÜŸ!Æ įG¬oƒ 6šė8ųÅ×&‰WĀP ä į7+k*ĘŠŖÓ¤Ił':w®Ü\Š€µgõžūļū5˜q,ķ{챑KaY¶l™_S×&ä/ā7P–>8ą€Č%æō _į3¢.rjf£+NQ¼-B!G„n"#Ūx Äē!r ā ˆ"(€&ąW·Żv›'ŅP”ĄĒŌOEėōÕW_õ­8–'Ÿ|2]šRŠ×V!_Ø)œįóĻ?w7Üpƒó„ |‹ŠĄ o…5 Īį\ī“ÖcUŲzė­żš8Ij„_v}›ˆˆx-–/MęLW`vOX&ųi¤ŗ`3’ŗ&ynųłæęW—.]üŗŠ`yĀ/³ ŌaWńˆŸX,ĀÉŖņMĻB¬Mę}±"ŚŹNF·źÜ”E“W}¬«”²n‘8tUtķŚ5g Ұaü5#Ž-ßGhP˜q=Ä&.0,\wß}·?Z>Š BAkÉ 5 ²Š4ˆN8ĮoSŲ_vŁe~ŪLŁS§NusēĪõ(ēP8Ęͽ“ši„QQX‹‹óB3»u1p›o¾Łoć:ĻÖĪ„m­ķ¤pō«Ūs§ĄĆRY·HÜóĆ?ģ·Ć’Q!žļ’óŪ”{x>ń@%š¾“Lä”ɞė†ńK„ōČ#TøZĒ„ŃZǜĒ5ĆųĶ7.’ŗ.’@lŅŖ†šŽ³qī¹ēśgĻsæõÖ[#×ņ{%¼7ŻtSäZī¦;°“„µ$ŒC,•cĒŽMßW˜žˆ/Ņ ×³īKĆį}†éšļl ĀxG„ašį’łĻ2ŗŅ’Č7=ƒuYÄ櫐Ø[D$Ń÷ˆŪŻ”OŽö’ɰ\äcī($TģfU,ń ‚!ģ.aL’Ī Ēa„D¹®Y.`ß}÷u×_}“—!TZųßßD +£¤:•PɛyÖZ¶T’T¢VČćŽX ­fާ" aüĘüN„ÖÅĄ5N9åó‡ė‡ē†-m*€ŠlĪ6H˜ģ’U%“>Paä‚ūµÖ*ń~Į–0ÄMßÄI<ĪBāńK:Ļ„Ÿžī{–ĄyæF¾qA˜?9ū©)<{öˆ·Źą|Wa ?LKń8čcF˜ž_v= G˜¶ sŪ|óĶ}ewšAÜÄÓtœPĄńŒ³½!“oz¢Ų©ónĘ5X—kŻęĘĄĪøe«- ;ē™gžI[&8kī¬ö¹.•“aāĮ®sĮDGŹ™8q¢c(xź;T.V˜Z÷GŁZø@įĖ1÷ҶėP±YåE+Ó iZeX^8Ÿ’qp·s­2Ā­’ž~›V²łÅµ©€iqĒ o¬]VY&¬“N«Zx›šEhe‹Ā@‹–*~įļųńć3ŗPØ,±RpoꉷP„pŸœ—-~V¬ÅW<Īģ^ó ³t•ēļ~÷;oįŖ®0¬€’ŁZåTžÄ‹Y}ˆ›°µ¦%īŃāŠĒ’*p€ułaÅØ ĪĒo®miĢŹ֝J™Įuy¦ϬUV¦š,Xpā¢-ßō,D±SkākB\$ąF/Œ-ģÓ ݲu‡„’ -’Æķ³ 6Āk†Ē¬†ÕĀc֏†@>ƒšņį/ł‹Æ@©tƁz&Ģ*@«X8ßÜ&UŖG;S·"Ä_«˜B™Ā›BŁ nü”2±‚šĀ› 3Ø­u ¹ 2Ł{ļ½+ ‚¤;Įl8qŠ•¤ œū“óĀųµ ›J óxXi‡"ŁZģłĘ×”r4!Ā}P©"FŖ[ŁŁ3ŸW>šæp0±„%*{ėŗ"^Š=)öÖI¾Ļgŵ9ßĀM\¶mBŽgJ‡0M#ŽBk iÉD›=CČ'= ±6©óI“Diņå—_F[5#¬­pÖŅ [¦,°ŲI„×Į €Š%4ćcs }śŌ©0ĆšåźŠ±–=•m®×"mš#‹UĪÜŪN;ķ‘2ėć'F< Iše‹ßV­ZE[©1TĀvMkłCx^¾qĄ`ÜK|°'•]U­>„Ķžq®q„Ēāk=SŅ‰KK«WÆökƒ8²ūIJO+W®Œ¶ŖG®yYƒ”`BĪŽD1BÜ"#mt[™pČ7= ±¶(‰I“ÄŚ'47mŚ4ŚŹ¤C‡ŃVłÄf…Ä ŪźĀ}` Ķ×VȇPaŅĀGį½e£:­nü² ‚–ŖµP“Ę ŌĘPé'Żs6ņ‰ *;ÄŌÕW_]”å]UėžYx6ašĖÖ*Y£&]2µ…=_ž'‚Īę;!='½ Ć=!2m”%ÄŽB2ņMĻB#⢲ ¢~b&r*Ą¤iŲ£ K2)‡&Ū°“֛aĖ4\Ā7ja‹·h“Øģ­†ŗ4¬%œoŘ āŅD•5żłÜXq'QYüŚ8*,*$®І\äÕ‹DŲMœY7XM°“·NąO˜Nk›š¾,!*xūŪß*X›āp,×q#ßō,D1!Ė…šLž<9ŚrćŲūŲ_{ķµh«"“Ę)li]†}ČV›¹šĀ?¼ēŅןO×DžĆ`Ä0¼ˆ#«¼ĶOŗ hهįāķ ć‹/¾ˆ¶’±. *¬ŖˆĀb•>’%.Ā ·Ö¬Yć+⬲±/Łā×ZĒaEK…ĹįyF¾qĮ ø›µ ~½Ŗ ^»5’ZóŁĄĻpęSµö\yĪöų¹5ł€µĮā±&’éÖ8éĄfNŸ9‚„q4ł¦g!Ö&ł¼UZkӋڇ‚¬„s]dƒ¾÷p¼ĶA * åOaŹL•ńÖ¦AĖs1…©07³3˜;…q8V!„›‹T2¹ĀI‹ÓK&łMePŁį’²Įųŗ!ĄęzȆĶaį&ŒI](ax*{~v?łĘ…Åut`²‡\Ļ€<-+įēśŁęĢØ,-…’å™02[Z Ɨ+=AčÆå©$7ļ÷li𓇰łE*K–ÆņMϐėł<ųąƒW¹ü —jĶs‘ĻĢ[¢~BaL„F…@AfŠā¦°ęX®ŒTžfŠfMAVÄ“ä0s-;Ø4˜hČ żp€i|@œ…‹?š ,×0,¼ųe¬}ˆūK­2…$æĆ¹-&MšmU$Ū X Ż&,€x“žv ,ğa׳ū5kV„ńK…‚_ö;ĒZ»głĘžÅÓ×¢"“ŠģŗŁ 6aÄ}d#ō'Äü E adĢBŅ}ÄƗ+=A_F’Ų½Śq®—ŌeŲ »ÄędA(’ĘCĖ× ~Ć|•oz†lń%D1a¹ČG‘ˆā Š–‹ź­…WŸČ§Õ-²“ļŒ „ˆYØčC«Bhgf-5d¹ITĖr!„('ßV·ČNų–M}`oÖ .ĢŚ`c* ¦¢”!q!Dl#•G8}·Čę-”Ū„¾aƒ_¹G&£„Ļų³Z 8Āī0!ź7ž•9›ru‹”0ÅŠ axR—hØšŸ2£’°t•jwˆ”nQ]$.J˜ś:ĘAQH\ˆź’Ń-2qLł×ž„B!ŖJ†øhѼüƒPB!„!Gž]ywŸt–07޶„¢°Ø|Łų`öĀh+;ābÅŹÜāˆā”K—.іB•/¢&dˆ‹Ć3§6ÅI>_ņBˆź ņEŌu‹”0›o¾yā÷&„¢&P®P¾Q]$.J˜-·ÜŅõļß?ŚBˆĀ@¹Bł"D—meGā¢Ä8p 餓ü®½öŚō’ōŚkƹ8 «Ą°Æ†žrŹ)nҤIY‚]sįĀ…nŸ}öq·Żv›.Bˆā$C\0 S!ą7æł_ßu×]~m f̘įöŻw_×§OŸČµ"{챇 šÄOųu–‡k®¹Ę ˜3Ļ<Ó»ŻrĖ-~ >kn_źDŒ$YT„kY.„YA ōčŃ#£"7±ĄąŠź‚5dɒ%n芔®{÷ī®_æ~Ž"Į Dé#q!„Ø0¦!>†įŠ+®škėĀ€ūļæß‹Ž£Ž:*rÉėŻpĢ1ĒųuČ\ą×{ļ½·_ŸqĘ~=zōhæNįqį…śm¬&ˆ!DŻ¢I“„yacĀ«Pł·iÓĘŻyē~aÅįÄOōū!ēœsNZœ0Öb§vrcĒŽM_˰nhß¾½?’č£öū¬iŲ54Ļ<óŒļn¹ēž{¢£Bˆŗ$ŸI“$.„9aœ•9b`źŌ©īŃGõīǼ_‡„:Yž~śi7dȐčh97ß|³_#<Āóńį@žĆ@ÓQ£Fłp !Š“ qńä­ĒF[B‘Ā„ÄwÜįĒE Ŗ[¹Óµ1nÜ8o…ˆ <ŠÆ­ĖDQšdˆ M¢%DĆĆŗĀ%|Փ± ¼Õac(Ā×O«Źõ×_ļ×öškbс•$×üBˆµG>“heL’-„Øæ0vbÖ¬Yšž[Qmņł™Ę\!„¢ dˆ M¢%„Bˆš Ė…B! Jʘ‹|śR„ÅĆ×_ķ×ė­·ž_Ē±ćŠµkW’:i«V­ü~®’|óĶ7Ń^&ė®»nāW®\mUō×`ĢGĪ ’§yóę‰~ńŹj’F§N¢­ŠĢ™3'ŚŹæ’Āˆ_Ia4’7Łd“Ä0ęšmæ’Āˆ_óēĻö2ŁtÓMżćąWńøŁn»ķ¢­rø'›o$ Ā—ĘiÓ¦¹U«VE{™l»ķ¶ńAxŽyē¬Ļ¬cĒŽ‰“¢ń¼²=3®µćŽ;&ĘĒ /¼me˜£¤ų “”vŲ!1}ąW˜_Ā{$lŒöŹįžŽ~ūķh/“޽{ūtæH#Ł8ųąƒ£­r8?ʐ-¶Ų"1>^yå•Äø’ęŪļŻŃGķ%“(.Ężłh/LU2ŸAĀ©jęćü¤Čş¤Ģg”̐Ęx拳ÕV[E[åT7óń@/^ģ¾żöŪČ„"I™&OžmeB†Øjęƒ-·Ü21>H8Łācƒ 6š)ńžĮD{)ĀĖ}%Å~eKTTI™ærÅ÷•ųe™/éžöß’Œø'l’łĻ¢½Lŗuė–˜ł_®4Œ_Iß½÷ŽmeBüķµ×^Ń^9č¹āƒ8LŹ/=öXÖø'lI…é)WįLŚHŹ/Ļ>ūlΊ1i¦NžÕSO=ķe‚?Ii‘ēœ+xܓĀ™FćIiń­·Žņc6x^Iéæ²å1ņ$é#÷Ľec—]vIL÷Äa¶J‡ō~Ųa‡E{嚬xfŁ ?'„{ŅF®2æ’ņi1Ü÷‡4OŚĻq˜T¾)•Sy,ɟDqqöŠ–Ń^&…~(ÕÉułPź2CSĮW "[ĮWY„“Tš•r„c÷BÜ'U:Ľå±eĖ–¹–-[śWMa—ōœyV¹*8ZUŁ„=ēxCŅ}‘Ēr„©7Ž8ń9“æęĪķeB¾L¹ī+[‹–tŸ”¦ģ³ xʁlĻ™’&č<«\­gā#)M”5”qćĘŃVŹÆ¤|IÜW§ńÄ3ĪVnC’_Äq˜”.€g•ĶÆl7׏ÖpĶ%~H÷I~Ę\÷E£+ž¦€’„Ļ9ž¤“¹üāI~įO.«bŅ€8ä¾³‘ķ¹äJæ¹ČĢ^čęņ^ÖĄš¤Ź”HŹeā” JĪŁĢk>)óII~ŁĶ’Ų’ü"±-X° ŚĖ$›)/—HhŪ¶mVæ°\d{ÄGұ\~q~RN|äŖøÉDI Ž’d{ĪŁ2~Å3D˜`óĶ|q’ü‚\™’2-žXa”Ē„7ÉŻž“l™6×}A¶4°6 ¾JłUT*'ęĮą>Č_Bˆā$C\!ź/„..ų® ß a†P¦BŌ=§_7ĪŻxÖ¾Ń^2z[DˆL|VĪp gč¬.v-ūĀjM±ļšŲ4įuIe÷Rč{ 1bDśśń™KGŽ™>.kĀĄ}š?Ü8nXw„cį^ā÷æ!ēŗvœ0œžłŽ뢈ĒU6ī¼óN?ˆµOŸ>éī 0^„(FŌ-"„HWrįÆš.\čĪ;ļ<7iŅ$w蔇śŠršąĮ¾%}ß}÷łćūģ³OtvvśõėēĻŻwß}}7Ē…^čżĀ„¼iÆGž|ņÉi³>]°÷Ž{ūµĮ[#S¦Lń]ü/üt{ģ±žĖ®Tüģ_}õÕ> Ü×eĄ«ł¶¾Ļė¼ńūŅę™g|˜,^®ŗź*÷Ē?ž1:+uŸ„›p`iH’9Ͼ k_åL”%ĮżŪl+›@ˆŖrŅa;F[9(KŲčsųmі¢¾Ńŗuė–,Yķ•ÕjeE@B1¦Lųće•Øß/«,Ó’±ķ2±ąAYEšq<¾]VYśsƽöZ揶“plģŲ±~;ō+6°ė”UĘ‰ĒŁg!œדóN9åæ]Véū…mÜĄž{ė­·śu¶ū¶ćIKxÆvŻ\XŲ’®Łā户šÜ„Ø d¹BTJŅ\.Õ%i®ĖHY¹Ta9ūģ³ŻK/½äŸpĀ ~¤`¹Ø,ģ6†‹ć€‰¶|šAæmnU„LdÜK8H–©Ųs5+Qü:fÕ”»$¤L@T8æ°t±6Čw]|P“%„Łį­ ŗØ1ßc¦§‹£:ģ¶Ūn~)Ÿń L–ÅxĘ%°mo‰Ä»Dąwæū’•ń5×\ćŻ~łĖ_śuœ²–»_[8»@÷÷A×ć8ēłēŸ÷ŻTģø…l¶Łfī›š…÷?nć,ø—Ŗ¼¹aÓWŸqĘ~m Ī"Ćŗm„(62ÄEæ^£-!DC!iĢsA‹ŸJ˜ŠŽ‰­Ś·oļ^żõčhÕ`ĢĮŲ±cżĖ¾}ūśq\묳Īr+V¬š)nIV*mž3`Ą×ÉÖbæēž{ü[TŹÜć¹ēžėĒ3pfĮ6l˜ˆƒxÅ|ō-¼o «aĒ)/Xš'ßWh,6f"IPYønøįæ¢.¹hŌóŃVv4C§ ZŌµ9C§MĻ …*ZhõŸsĪ9¾ĖäŹ+ƌ\Soƒ`u`PdÜŗ „Ø=ņłzŗĘ\!j„uI` °·…┇ņė#ŽHžÄ3– !Dq‘!.†œzO“%„•ĆĄĒ+®øĀŻ}÷Żž•K^Ļ - 5….¬ qėĎ;īč»Z“h¹!Š…Œn‘|ĢBˆŅ¤¶»E„õŸ|tB¢ø0xs$ą‰UcŽM|mp’nўsGžż°’l{Če#»ƒmķ9wĀ„»IļĪ‹öRäsĪYĒķęŽ=`»h/õe¶ųT˜Üć”#Ź'“aąÉć>ˆöRäsžąŸqŻß^v÷Œ}+ŚKAx ·qŪƒÆ»;~#ŚK‘Ļ9Ä_ų…9üĮæžCų&įŖÉēœ-»¶wŒ,Ÿˆų#C:whįž¼õŲhĻłēĄóÉēœĶ›ø‰c†G{©Ļł“>℉”ō•d=ĖēüĀO`¦Ł¤©ģ 3a7ĀōnäsqH\ųŸŻ6ŸüS×yģøCvI‹ å1å±å1ÕcOć¾Ā|D†øBŌ_d¹BŌŠ)„Bˆ‚"q!„Bˆ‚"q!„Bˆ‚"q!„Bˆ‚"q!D=‡,“˜0aB“%„…EāBˆzĢŅ„KŻąĮƒ3ĘģŁ³ŻšįĆżZ! Ä…õ^93fŒ!§Ÿ~ŗ;īøć*żģ·BT‰ !ź9C‡õk¦ē¶5ÓN;Ķļ !D”Ń$ZB4čžŲ~ūķ½ØĄšńČ#øAƒEG…¢°Čr!D€īaƆłmÖBˆŚD–‹zĀēĻüÅ­˜1Ł}9kŠ[=·āüņBæyv…»fĄnƒõE.B¤hŗń–nƒn}]‹;ø ÷łuä*Dõø(qVĶ™ęfżó<·ģm½V(*ēĖÆ°•Ņŗ÷ ×õēW¹f›l¹Q5$.J„Å”sŹæx'„…¤ļµ/K`ˆj!qQ¼wĶĻÜŅĄbńL‹įnz“ķŻüĘåŸBˆ|čōķ,×sĶ›nŸåŸQoÕ{ėõ’Žö„Č č,Qc ‹‡Zå^jž3 !Dµ ģ  ”,1čn„¬¢ŖH\”( Ž4°X¼Ót`“'„Շ²„2ÅĖ!ņEā¢Dį­ƒ®!„(a™–5Bä‹ÄE‰¾nŖ®!D! ˽Ś.ŖƒÄ…B! ŠÄ…B! ŠÄ…"'‡ ŲȍæawæōīŽ2rBˆģH\QŒ<¹—ÆÜィäRwģ·s'æ^¾ņ[÷öĢå~»XAü®ŽŪÆKäš ēšhśæc¶ˆ\……@“h•(/Ū6Śrīā ’_“U? Š’Å>›ŗM:6sZ­ēŻÖ|ż½›»hµ{{ĘrwĖ#3½[ƒś¶wē’bĖhϹgßųĀ]sļ‡~ūīswp·oź·s1źŃ™ī‘‰ŸE{åPķµc‡h/“+’ń›0ea“WX°ļ}ĘK~]tjÓÄżó‚~~ūĶ–ŗ³o7#Ž/–}ķę,Xånx`ŗ›ædMäZ·`e1“»ßžß»‹ŻE}ßo'Q•s"—~žÓh˹ŻīYm ‘²\ˆ¢ā7‡twW’ŗ—Ū~óÖiaMÖū‘ė¾Qswš¹›·]äšÉĻv޶Rl׳U“Usš­æN“U÷,ˆ*k*šŗäšAG[Īżć™OżŗM‹uż:Ļ‹ē6śģ¼(YLŸ»Ņ Q˜1o„_ !źY.J”śh¹Ąb°@HPA<żŚü“•‚Vęįƒ7I Žl-MLāüęg+½$‹BuZ­—żjk·kÆT¼g³nŌ7č†!Ī5Ē\öŗwKŠ;Ä֌­7kįŻĶŹQĢČr‘Y.DMø(Q꣸Ą"a•Ó?Ēźžöō'~Ū@|üńŌŽ~ńqą¹’óŪ}ģ?ß{Sģų‘“3Ģł!µ).ī8³Æ6tÉ|¶ų+·ļN|MøŽūxyFXønÆ®-]Ėę#—r¬[Ē®VņUõ‡ųūõ]żLĄ!Ā_IŻa|‡ŻKŁā.tŸ»pµvõätWž¼üĪbwŠnłū|ģÅĻŅĀkUæ­Z§»},\yb¶ćvƄį{ęĄ}€¦!?vļ„oŚĒ_¦»¹āi€0ķÖ»]ZĢļćŹÄn˜&ĆųĒŖµĆę­½ūõ|TkŻcu‰Ä…Ø źE50p0.,€Š†JØ ØĢBvÜ"Uøs•„Ū£ó~]W4Y7•­śoÕĘW|VAfŗ œi˜`I!vM»TÅ*h¬Bˆ7Žköoümr7SŲ%2ę©£­üXóMŖkĀŗ’Ś·lāĆh÷Ł1ź6APŅÕŽ…±p^ĪūƈŽ8×­s³h+ÅnۦĂ„ =ģ²éŃ9•ž€{ ļ’²Ÿ±0…qĶ6ቆńĻ3äŚ,Łŗ„hH¤r‡k*+ųW¬žĘƓ˜æ8y  -S³z|ųé—~ĶąO B‹ ‘šB ŻŽ4`A$ÄĮ_ĪĻÆ˜äžpėŪ^4Į6›•æĪi­]¬+ Ō“Ö7Šņ[éŁČǟaūwńńĖ1üĄ/¬/@ÅIK=Ö0±– žŻV†Å½AųM8o}d¦&öĢ,ü„ K^,-”PD€†ć96n—%v< īĶ„BÅīšÄ ĆdĻ„pŁõ±¼ÄįŽ°lXü7„ī2!*CāB=7.oeV‡°•żŠ„¹Ö0xūģoyŌ&']?ÅWŽX]fĢK‰Q`ۘåÖ7&{[Ž•‘Ė*c³ ¼;{yŚdO%h~õīQqž ,Tš !“ŲWtŸXNE›ōFchš›p²XÜņļ™Ž T\̚†Įž5V»Ē7>\ź×Il±i¹åŹÄ÷žŠĖӇ†Éŗ•×ÓÆĪ÷ŪÄ qēź¦ŗ–ŠżU]!ź ‰ Q,Y‘ŻZ‘ōŁCŲŹfƤ -_Zµ¶ä3fć«„–²A7Pq™°7DŖJÜė:¶˜_fā7ģ­Z÷¹^ż AØ`u°1!qLČÖ5ńJyśœŠ)Š&zuMYcR7ša" ,mĄņ•™i. SO6–’ŗ=$*„؈ą( Āp-šfļ³īŅ©¼ož×“¼U’ˆˆ°R°Ö4•T’émc㠬ҷĮˆT˜a…ZŪŲ ĆÄX®īĄāb‹œłtćTDAŲ56–¦²0šš a!¢h0+-ͤ1a«>œ-ņ€]6ōėŹˆ›ž×6tWXEi÷ŽØ ²<÷/ļVhe×aЁp”[Å»ž35ž”6°±!Ž£€ž›¤„CxŽu6ŽB1‹D®.ČęOĖę™"6<7)žXB!,„HFāB /æ½(Śrīų!]+ŒĢgū·?ėķ9÷ųĖåƒęl¢,*褏 ģ‰Wbkŗ+¬?żĻoł°ņz-}!Ķģ\Ė*Mi†ĀxeöĻŠĶŗQųOmN“·€Åʞ ĀĮ,NŒ1BK޽éQY—Äżī÷š—Ó1ĀsyŪĘĀ„uŒA»¼~*„؉ Q4Š·oŻTŗ¼śgŻįkŒˆ`‡5Ć*¢·¦/óė8”ūšż7‹¶jFüm–$kK.ĀŁ$™“Ć®ĆD`TbI«‹‰1ā0 ;ńjÖ  25kŠ ­-xŽ6ƒ74,L8šœy«Ä»FŒ|ŗD%&®š?l Eh©Ādb”q0&¬Ņu›"„HF9Eæ»ł-?X’JĆ*^ Ą7ၘuz_?†b—mŹ+Ž}åóh«"”»Ķ“v¬śź»h+7łžgćā—żßī‹›ĖWW<VTšg¹¹o1CŅ5óõhŻ'Å+ū¼ņjŠš­›'_I ø8ᘃʦŲć,ŒsƒqtÕX…ÜnXsā]CLÄļ¶ Ćfb¹Ę%wæ_Aˆ°ĶdW —§Ī ƉæIaāÕŌs‚‰É²ÅæB3t–,õłĆe¹ĄŒ9ŪŗØJuŚf›@‹Ź>œÕŃÜ!>#em“4Ż·h˜h†NQd¹%-p¦öFT”z‹ŃŽ|”¼hyŖ•Ā“ŽuV’Źŗ˜„"d¹(QŖå¢>Z(’ØkėŻLL{%…·U4wCĆF– Q$.J‰‹śzųŃ.@T`9ØĖī!āH\ˆš qQ¢H\!j‰ Q4ęB!„Eā¢Diŗqj2 čōķ¬hK!jNX¦„eł"qQ¢lŠ­|¦Ąžkތ¶„¢ę„eJXÖ‘/%J‹;D[Īķ³bŒŪvõ ўBTŹŹ#,k„Č č,a޽ęgnŁŪ¢=ēži1ÜMo²½›ßø[ä"„łAW‹PX“ī=Čmó’Žö„ȉ‹f՜inŹ9»E{BQXś^ū²k¶ÉVўł£n‘†LOę§u!„…¢UY™"a!j‚,õ„ĻŸł‹[1c²ūrÖ·zī‘kÕųlå÷īĶłßŗ!ŻSS@ !¼ĀąMĘXløĻÆ#W!Ŗ‡Ä…H3eŹ7|ųp÷ę›zūDˆBsÉ%—ųEˆ†€ŗEDš„K—ŗÖ­[G{BˆBré„—F[āŽ;īp5rēŸ~ä"źB! Ā‹/¾čEƈ#"—dīŗė.æ>āˆ#üŗŌįž{öģķ øBˆ:fŃ¢Enäȑ¾B¢bbéßææw+4ūķ·Ÿ_ź’®]»F[™Ģœ9ÓMš4ÉõčŃĆ­X±Āß;į3a_ĀxįöĆćGu”w_ŪTE\“mŪև=žī3¼7[ˆŸ'Ÿ|2}¼6ŅI”‘øBˆ:aAeqĪ9ēø}öŁĒ-\øŠĶ˜1Ƶk×Ī»ŗ«`Üøq~)ʏļ×Gy¤_'ĮP@–‰'ŗ%K–ųx”+eĄ€>®pēų}÷ŻēĻ?蠃|¼–÷ßææ§óĪ;Ļß ūqöŻwßtp<柒üēnńāŅł€œÄ…HS٘ Ō²)nÖ“¦Nu~ŪZb֒ȦÄYā­ ®É’CU’ĒɌvŻbh±Q~ųaßr§5j”Ż»wwO?ż“»öŚk]ļŽ½}ŗ¶ō¦ĖT¤ģ“g*į¹–7ié²o°Ķ¹äÓ°õĻ6ēfĆĀ.ü‡®p?Ģ‹wŽyg…caZ•.‘=öŲ#-Byäæęžpī“kS鏹īóĀųäæ¹‰Å«-ųĖ=‡ńv’¼öŚkŽcœ“M$^pĮŽjsüńĒūż»ļ¾ŪƳA8ūõėēÉņåĖ#× L į)˼? :4Ś«HY”Ē[E?œrŹ)~æ¬åšC›6müR¦¾½ĒXŹ MæÄį’Ł’\™:’”,ĆyøfYkĪ»‡’ĮĪaßĀC8„(,“7Ų&ĶgƒtĶ9,S¦LńiŸķ²JĘēæģ—µ~Ó×ćłĘņ†åA¶Y€ćä/öńĆņ±ķ'†…mü“żŪoæ=®ž‹;a·<Ė1»ÜĀkÖšænaųģ^ł™čš÷Š?ܗŻń€?ay†wĀͶ•gI˜_¬ł…ƒk²?ģs-Ö,\pŲ _ČŲ±c½;qv ī āĻģśųńÅ'^·I.éEƒ$—ø°Œb‰ž5™m2edÜBp‹_Ć Ć’įģ:\Ā’pĢ Ė„–)…(v,[Åci< «hĆJ†Š 7*/Ū&OŲõØČ öYāŪ–7©˜ ĖKVįʼn‡Åö) öYģXŅõY[™a~…×¶ķųĀ1Źƒ{fŸėįēó'i±r’xłĒā•p…ūvš¾X‡ńŽWHüš&r’īėrŸ<ߊĻbGŻ""MM^E½žśėżś€pG}“ß6·ŹĄ\Y–ŃŻUW]åĶ…€é0S#ĒŹ2ZŗŸUˆRdĻ=÷ōė$s8ć Ā.„cŽ9ĘÆ_}õUNYEå»SÖ;ķ“S“•?łv‰”ÕMé…ī¢!C†xwƒrĻģŸ}öŁéx Ėą”‡ņē”UÄžĻĀŲ–8Ս»^½zE[Uƒn#ūĀŲŹ““O>ŁļßvŪmžŽ īÉĀN—÷٧OŸčhi q!ņ¢LYūµõ1’QĪ=÷\_Łļ²Ė.>ń‡™šķx†É…,×±’–©łŒNvģõ×_÷}B”*ōµ÷ė×ĻW4–ŸČ'¤k*›·ß~Ū»Åaœūā‹/ö•é°aĆ¢#)N8į?†Ąśś© āģ½÷Ž>Æ=šĄ>³\sĶ5žŲžūļļׅ€ė3ց1Œæ€.]ŗ¤ß©NEÉõų/ńdå įg¬0ˆŻeēæ,x ?‡2 wŽ3>¢e Ļ„øē\qÅŽĶ„$Ü{ļ½~}ķµ×¦Ė3+[ómŒ• "/®¼ņJ?ŗ™L‰āFy“ŃŸžy_H’±~łĖ_Fg»ō6ƒ×rajŽ2vŲa~]Ł@'!JŅ'Ķ[~"/!ØÖäµlœuÖY¾‚¦WŒäĮöķŪ{Qϵļ¹ēļN¾ü9öŲc}žEܐ‡-;6=H²pM¬˜}ūöõaåśĖ–-óĒhxT¬X-‰'®oåV ®ĻńžóŸžÖSÖ4F°ųpŒJģ8’»õÖ[½[!ą>‰{žĮōéÓ½XWAĆ1αœĘ™gžéפ…U«VłķzA™rĀ3f̘ŹZCŃ^2ōS’lJ”ĻOˆb¢Å­õчć#¬æ¦plK!°Į‹įؐµÅ]Ņbć"DõåB¤ÉgĢż”˜[yļœ–CųŚØ¢v¹īŗėü:Žś-eõAÖ„`EąZÅ4v Rü^m)¤%§!"q!ŖL˜!Ķģ'„Ø]0­Ÿx≾ė$ŒČŲ Lš6Aˆb 㫨‡ Kõ’$ѧ×ī’³NŒöŹł÷ŲēÜ?Ź> ’įæq~>ā"·2”©y³fnƎmŻõ—œ¹”óŅkSŻmw’+ŚĖä‡qūŽ%Ś+ē’ėītÓg͉ö2łēØĖ¢­rfĢžć®»õŃ^&‡ œčį›śī‡Ń^&Ü×Ķ›F{)¾\¹ŚyÉMŃ^Ššœķ¶ŁÜżņˆ¢½rĘ=’Š’ßW¢½LNv˜ėŃu“hÆāćĖ•ć~ņ+’uĖ–-q'œōŪ²’¹–Ć==ņä„h/“C† J|ĪÄĒü/²OV“”¦ˆ{KSĶ›UŒ+Ų­’vn÷2[@¤Å³ēF{™IqŪŻŁĒ†÷IĻ™“ųÖ{Ó£½Lˆ ;¶‹öŹÉ•~»o¶qNæš7[?r©Č>ƒvIō‹ųąž’ ~v@ł€3ćó‹Ü3²§©>½6O|ΤŤüldóėå×Ė'b‹ƒ?Ié—“ųł‚ģ³&Å!ĘlPę$Żi1©ģ°tÄāi xf!{ģÜ×½ųźæĶ³Jŗ/ü"N²‘Ķ/žĻĻ!I÷Eŗ˜1ūÓh/“NŚ%¦©$æ6hŽ,Śr‰÷…_¹ŹüJŗ/ābåŖäō I~A®8$¬I~Ę\q˜`~…q`$łŁņ¤Qč’­ Gė4¹Ÿ+ās’ÆjĒ*‹Ą\‰4[įFŲsż/d¤lĢü8¹ĆÆ\’ćxR"ČõŸ¤„ ÜÓŌw?Šö2ÉöĢ(œćń<÷ó/ÜW«¾Ģ*Œ(ĢćfČ®ż¶++Ä¢®—ķ޲g¢U9żźŌ”m¢ø Īõ?ÄEüŹU™BRe…_TŽŁŲgŠĪŃVErż‡Š;É/žs®’QČ&‹‹ YÓ=zR…ϳŹÕXŲ ł”‰•"7WZLņ‹Š#—Ųā?§ ˬ@ž™šj„(¤÷ėGeo,ž’ī‹ō”+>®æä÷‰’ĆÆxCŌĻėöėĪõŪ!ˆ˜\a$%lüŹ%d²©ōø_ax¹Æ$戋\~õčŗi¢_Iā¶[’ģ×§œśŪÄĀærÅįKŠĒ$!c¶l­* cŅ{vŪ$1>ųOU[“\?Wa™­E‹_¹ācŸA»&Ę}®Ā«]R‰{ZųŁā‘B/)>š+WÜg¹ā#›_X² nH*Ą[®Š;›%æŽz/{!KŘ$.rYØztŻ81>ˆ‹—_+Ś+ĒZŌų•Īa«ūҳOr¼ĆocKŖL‰ū\ń±÷wN¬ąš+[9@Ł‘Ķ:˜+>öžń.‰q’÷ĒfÄ}˜ĘņµĢ†æ’Ņé!™ ā0)gƒ²#)>HS¹āžš%‹‹›|™“Ķ _qAšJw¦ĖÅ$’Ed‘ˆ Ńp¹ä’K*¬……ƒŠ*nECA:…BQP$.„BQP$.DfŠ«ī·E„BCāB!„EāBäóŽļ·ß~~Pš-|Ū€ eþ›ĄĀ fõ Ɠ“ä _‘äüšś&ā瀅ß>ģdš}ó—ķ»¾}`JˆBĀG®Čżū÷O§AŅ-鍏~eƒćv~8Kn<Ę—¤|’ †?–zöģéżĀģšń2Ąņ7’³s Ź ŽQ6ˆśÄ…H“mśo >ōcŸ 6ųś ' ·ūšėįæ¹ ĖźbCJ‚9c³>óĢ3~m<õŌSŃVÅmxä‘GüŗŌ>w,Š*^*{¦Ņēcd閏\ńŃÆøŲžGåL¾ūŖi”!l„Ćņ #¬ļæ’¾ßē`šŅK/łµaŸ>ē|>„2¶Žzkæõ‰ ‘ 1 ąK‹ .ōÆÓQŠšeE Ą‰O=Ģ>‚‚sģė>ų _3e8×`±/‚¹±ŌöŁe ņ°EŠøš0AŧŖ…($^xaZT0„·„ż‰'¦…Cü³ź0~üx_q“©ąŁ6ėA85æ}rµ¹q<hXŲ’%χ_4µķ0ϐÆB” J„Yb½ž#q!rrĆ 7ų5ŌØQ£üē¢+@XPÅ?­N|ÖŲ*u)k‹w.Ÿ1ÓZTVZ+,aa~ĖAˆšB³ü€Ą>餓ü6šĮ,>TčqėÅ£>ź×»ļ¾{ŗ‚’ūß’īׅbŊіssę¤&Š#ŠŲ°zį?„yĘņ•å§Px¼üņĖ~M™ ź?"MR·ˆµBöÜ3s¶8„†Y/&Ožģ×Ę]wŻå×Gq„2dˆo‰…-¬Bƒ…Įś€m‰†÷wŽńk+ )¤­@4a¤ĀPŌÖµ»ķ¶[“UN(„ß}÷Żh+%JčZ ?‘ÆČ_€›Uš…ay….QŗHāć$Ā0Śż˜„⬳Īņkʳj>÷\jfځśµØßH\ˆa– „‰a&ÕŠüi]#O<ń„_Æ-?üpæ¶‚Ī ĆŽ½{§EÄ /¼ą×vŽY^„Ø+,_A8®Č,„–ŸČ_qQ\(°LZ× ā‘ĮĄS;Eķø q³TŠhįzķµ×üZ]Œ ‰ Q#¬µv<­ūgĆ®‘B¶°Œ°_Ł–$¬•h†;ķ“S:Œęfē„-4!ź‚0téŅ%Ś*·†‚×ņ™ua ÄcŹ”)~|Šh`Œ•aM„8a¶F偅 ±n];XCBį$ź/"'Öśˆw{ęNė6 M6"üŖ«®JwQšV‰QčVUĄÜkƒåč¢ Cōs[÷ CQtīÜ9ŚŖŲķa„yį a~#?YŽ"ŸĒā« ÖĘ[1čLtChٰ.F³Ś˜ ÄŗŻ£ŗ"''ž˜śz ‚9¬EEKÄZ&TÖfź¤R¦rĪ…½¢ŗ¶°īā‹/ökŪGDX?³³n! bÖ*ęsĻ=·ĀX$Ę6Ų¼*œcVĮŃ£Gūu.ā«« y®ė!ßŪ¶58įabŻņŒ54B±n—ż÷ß߯EżGāB¤IŠyüńǧ+ܓO>ٵoߎ·– nE]}õÕéÖ½©ĄŒ隸ļ¾ūü1Z9µŃĀŹ—Įƒūu’Õń†Kl'D!ą-čZ"Ū€›c˜E|Ļ[ÖmqēŁ?ć]Uš¹6łŽŽn¹āŠ+üڈ糓„bŻŽŁ›&¢ž#q!rBAæ+…œ@ė%ly™UĆF”sĢ1~‚uĆZ9fömÕŖ•_›{U±’'a׌Ÿ†ƒµ†`£ļ{Ta(j ZżTŗ6_…A>³¼v蔇z«V,¤×¤‘–ß8Ē, ÖPØĪ÷‚;ģ0ŸēĆp‘ßĒŽ›Ljüņ—挶RaĒ_pĀ ŃVŖĮ!ŹToķĢX$JZō˜6 ¹TSi[Ÿ/Ż$ń×Մ)°ä[Ü"Ō=öŲōųĘ;„saQģČr!Ņd›ž;W^y„ŸĮϬ…¢²o$°X Mˆś†Y é ­… )/… ߢ¦H\ˆC×”¬Bŗ ¦OŸ.«…(9$.DQ‚X±ĮjŁ› K‘?Iy)\/^)Dõ‘øiŖÓ-"„H†ütÓM7E{Į=œÕVˆś†ÄE‡AœI…ÜšįĆŻģŁ³£=!DUAØ’éOJhĢ`w!ź3 œ®]»ŗÓO?=ŚKAįĒ”æ²bQ3ƌć…ŗæōŅKŻ7ŽØü%ź5  ¹ &x1~†*ü„Ø9¼Ö=t芓€§;A›õĶs!¼„Ā ?f䣚C\!j‚}ūķ·÷݌ä­7ß|SĀ]Ō{d¹¾EaGį‡þ „Ø9ä-ėæ’żļ%,Dƒ Ćr±÷/E[Bˆ†ÄųR_±¬ */„h˜TV^Čr!„Bˆ‚’ÕrQVŒ¢ōØIžWy!DĆ"߯:¹wīįNŚ?rĶDßBäK¾y¾JāāćĖܱ#ŸpŸ/žŹ5oÜŽµlŚĀ­ßøItTQL|õķ·|õ ÷å· ŻFm×w÷œ} Ū¬c«čh9µ).¾XŗĘŻūģ÷žĒ+ÜģĻV¹ļ¾ÆP܈:¢ė†ĶܶŻ[ŗcöŚÄuh]³2›ņ’oOź>ųt…ūtĮźČU”:ŪÆļ¶Ł¬,üd·iǦ‘k&ł–Uź~ć“ī£9+]·6[¹Ž-ŚKXQĐ?ɧŻĖņ+ł–ü[—¼ōĪ"wāõSÜ/īfĢ])a±™żł*’xƼ·8r­:Ļæł…æĘŽX aQϘ·š+’\O¾aŠ÷śüȵśä-.č ™>÷K·ŻĘ½"!D©@¾%’’ė,w?ż‰ūrõ·‘‹(x£Ē~ģŸOU™2}™ūĒ3ŸŗÕk¾‹\D}äėoæw÷©{ķż%‘KõČ[\<öæé®Ķś£=!D©Až%×ĻLZą»ADńćŁÉ_D{ł3īµµk­øūܼ)¾w÷–~Ÿķpł×e;{wøģW[g’Ķ!Ż££Łįv~x½BB8ø>a,V,Yćƽ¾ Ś«y‹‹·gĻ÷c,„„ ł—|\|\V‰āeę¼ŖğóEń=Óå+æõcžpėŪ®eóĘ^€„<öāgž8–šƒ÷ŲČ2`£čH&TųĄł,tŻü»ķ¼[Cdöē5ėŹĢ[\,žr•ĘXQÉĒuĮ{³«nvuGužĻ“O¾Œ¶Š·g.÷BcćöÉ?ü4öķ7oķ×qLDüsü'~ ·<2Óżīę·ü¶YĢ¢·¢°fŸė `Ų6 …żpC䥮½ŚVø’µóYņ±“Ō&ŸĢ_ķÖłQ£hÆźTi@§Bäƒo7z>1QņČÄĻü: ːC/zÕMš¶Ō»>hcæžqŸö~m"XTųVÄ‚…}ųß»‹½…a„pŁz³nŌ£3+XZLx¬-j2fJāB!DIƒµ€ <Ū@Õ~[„,M˜ė×ÕĖālŻ„SJ”ŲõĶsĖfU^][śė›ø”KL¼”"¢ Ü{QoŹyrłŪDO\½k†›B 딯ŻÜ…«ÓŻ­ŽS±c0+n¶äkX±ś›h+B†ėņÖÕyĒą>ā×/u$.Š9ę“ų(fėŪĖÅ’³E…L4ØoŹtÖgXŁ‚įu²eÄ­ÖóėŽmŹĒå4Y/•¼B7!„(6 “eŲՓ#×rl@'‹Y.śėūi7Ā*+SCĢŗpɰŌ[a—H¹Ä÷Ń¢éŗŃ^ż@⢈”ŏ"§/ek°Ēr śéæU›h+Ő]:E[U£ŁśėD[ĪõÜøy“U‘/–}ķ×¼Ā$„„„ …ŸļŻÅÆĮvŁ0±besŲ%ŒŃ 1fe4$Į„Ln\ĒÄĶąķ;ųuMŗqÖ6EŹqūuIl¦ā¶>,Øń5_ļe{½ +…%ś™Ÿ„^;cjW•o×榆 2²%×§c.{ݟöķļF.BQPĪŁė¬f„EhÄ»YāXWH’`ąŲOķķĖhŽc1übߎüĮ#n4 V•R%ļo‹4:ą*÷“­~ķ‰Ś†®:"āÜæ¼›‘ČĀWš']?ÅoX='{łÅeeSļžĻńŸŗæ=]žŗ NHŌ€ø°L`ŠGIF„H’ą`|Ż o~“4-0, ‘i¦}ü„·¤pO˜_Ÿ¶Ä]sļ‡žøØ;ž3ķæī‡±ēE{)²åł|Čö_s/$tĻķµc‡tzÓ­÷ŚütG¤ļ»S'ßmG^zļćåµ.€ér“Į{a~0“åGņotjÓÄżó‚~ŽĶąŲ»³—gäĒBQÕē]ϓԱr˜ŸY.,]&•„„Ę#Wģģ6hZn5‡|Ė Y.АøÕ!I½’ĶzŃ}£Ģ®Š7šė·g,÷­»ćÉļyה\ć+(h©ģžX³Oe!D¾X÷\“uSi-iĪD7< Ū6ˆ4ŹpÆMLXž!BŚ­ÜĖ»m›ļ!CŌÆķłDvģ-‘’N]č×¢‰‹"dŪnåŻKæĢ>hįņäń “Œ¬Š²Do]#‘xaW`"Dń^łŅB'>&Dˆź€eŒ“õó+&„ĒžP©›ų°“‡™ŁņA]`é<|Š¹Āa÷bēh@tqbo‰`a*åī‹ŚB⢩iabÖ ZKōo|˜šō…Ö[]æ;M8¬ļrĀ”…éB“B6ßץ„Ø ņM“ĘåEŚŖÆRŲBPc­ /ŠbŻz¤½;ĪģėĶ»,¼NZ5éöŠ5Ż”Uµ ŠÖŗ…Ÿ ģģ×XóEƒ¤‹ŅBn­Ņī„Ž%RS$.Š+«V ė&ykś2憧_-’¦Dļu[”żMÅū ­1ŁŽ>"_h="<‡`ÅbĄ(ū1O}ģ…-‚š>p‚Įą°K‘ī“ć‡tõ¢ CŲ„ĀumŒS¾ŠēNXŸ‰hüĆ-žfA÷Āų ĪÅ*“ė\!Љ‹"äƒOĖ'ci½AöwŸ­o³œUĀĘ?0®ĮZeį`1 -Y D}«Ųõ|ä[•óĖZü§’ł-_ɓGĘśX×!•7]“4ł/yē€]6L涍ĒéRįÜŖbV:®‰åƒė›[>Ē5 (E$.ŠŽī0Ic$ĀĮa”—ÆU‚Ā®®XoŻņy2 LÓēę_Š ‘„¹`”ۃ®7yÓµ½6øÕføS *o„7<“bX×$?®XIš¤©2žżĀ<掮g«tŽ4·lŲ½Ų+āIW…(v$.Š 3+iéÜųŪķҳk"4{ōnē÷1±žå‰Ł~;ģį8+¤l”fPŲÕ˜–m2ś“y‡Ā1!BĘSWLœĻ[ų•_ƒc-¶šŠ“Y÷Ū¹“’?–>Ę_T„×"7Łŏõ‰‹"…·*lä;ÓłæŲ2ݽAw‡u}`bµ zųž›ł5<łJł Ńb&Y®i‚„*Ų$/¶P€W÷ ąüp^ę#¢¶ą•UņŠY&Ųę\aL†‡°ć¶€Ķ؈ ą8ć9lüEUa® ƒł]*ĆĀay„:Ż1õ %į3bīŚ ž)õšĄ5Ā0Ē ?Į`ž%}–”T»°%.Š„³^29K¼paßD•6 ’Ģ×­s3ļ–«uŽRße›Ō»õa×DŅ`Ņ|˜RPƒµųĄÜī||Vzp 6’&ó"–×|“JGńż8w?õI…ń ¤;ņ– ņc3²`Ä?ēZzfĶ~>X:_²"5p9œĀyģ+ŸG[)ģܰ+ŌĄOņĶ9 |Ö[ĘŖŲ¤Tf]āk¤į›=Ō„”šm#Ā֎ŶŪ}‚}»¤ŌŠ %L8s&d›=S£”gč…„ŖĻ{m=SĀI%åذy‹įAYųī¬å®W·–¾fcd¬œ¤|ä›TźX“¬ģäæŒĖ gV…šÕIß,^tqs]®gÆä&>³Ž D+»- vżų~]£:(dF±“x­$„Ø=’ĢÖįR*­éRĮā“J8*½ÓnI½ÕC…lŻ X9Ą^¼%„ēs.’Å„„łC¹jĀ‚W˜7œo+é *˜ˆ0LXT†‰’RDā¢Äa¼jųĄs’'«…¢A‚õĮ˜4-5aąū“Ow?Ųy憦ūµ›ķDb$7c–ˆŖŒ…°1üōKæęIłGöōėųWMķķ ĆD c$ Ä¢£ŖsōX˜ _KŠu׬ļĖ „Ö ¾ÕSUņžgļ®ÜņÕł©-!DńAž%×k«"łŃm£Ŗ?Ÿ=whļ6l»~“Ww0¦Ģޱ±|Ÿ(—5"üKX©ˆ®CŹ+Ę&lBBŽņ°‰’܉H1æ6Ų³*„aŖĢ’b~qĻ„Æ®æ/Ӧźnæ:F{Õ#ļWQo|ōuwćæ§ø-;l¹!J‰¾xĻž³¾īō”ż#—Łņ|>dūļ;³–»›šį>žæ*rÅB—ŽMŻi‡÷¬Ņ€DcÜėóŻĶĻt_ץ\^W$½Ę‰`Ąņ€`ŠģĄÉ¬ó£F~ŒĒ»%""ßņ"oĖRĻ7poĶmŲŗQАoÉæqaQ[lŪ­„ū徛Öh@˜(<<_’4õåן°o’N¾‚Ų§½ėŌ¶īĒ䋽%RŖÆq® :“nāvß¶¾Ł„EUČŪr/Xꎳ„ū|ńW®yćö®eÓnżĘśĄ„hČ0ʂ®/æ]č6j»¾»ēģŻf3æ)S– ć‹„kܽĻĪńżŽ³?[å¾ū¾Bq#ꈮ6sŪ–UøĒ쵉ÆDDÕøä’Kü"ņ//Ŗ$. ŗHžxu†›:k¾[“"yś\Q‚ĢϹ¦mœk©‰€ ĘGĻ:·ł^ŃNŻŅ®Es×§['wąĪ=rZ,jS\ŌT¹4l5jäbUeƒ„VŅ؟ >ÜżųĒ?vƆ ‹\DM)…BIā¢rT¹4lōüĖÉ7Ļkž ‘féŅ„®uė䙼„Bˆ|‘øB!DA‘øB!DA©T\,xį^7ķ†c£½r&ŗµūjAjĀ!D2C‡¶„¢įP©øXöĪŻŻūF{)æń¤kŗŃęnżŽ]#!D<ņH“%„ ‡ŹÅÅ»/øö»ķ„X2õ?®y$8>u’{łŲ¶Ž’čÖožŁß»æuį^i Ē»WäĻõųM½EÄHŗē²ąĪłęĪµĢóW|ųŖwē8~įŽßęg¶°!„¢vČ).Øø×kŪ9ĆB±ü½‰®]æüö—3'»nœģ¶üżŻīŪ•Kżę}Ļux”wo³ćžnĮ‹x÷™=ƵŻa?ļŽß _z(gX„BQ;ä«?Ÿm•ƒ%ą»Õ_ŗ[ģģ÷[n3ĄM=w€Æ“ Töß­^īO~Ś}>~“ūnĶJ×l“­¼„¢ķū»®Ē\ę’’q²s;ģ~xś\žXÓļų·DĢön׬óžü ŗļą69ä,k–la¢®øé¦›¢-!„h8äM7ģįVĻū0Ż…Įśćū.v’ō÷~Ę_’ą6>šw®ĻÕ}÷ ¬³ž¾¢ßīņg]·_\å6z† Ic7 éœūõāϼ˜Ąś0÷ń]Ū~CŅV¬Ž±~s·Ń~'»ĘĶ[»ÕŸ}čĻg™}ļEž¼laÉhž‹Āsśé§G[BŃpČ).°NPńņĄåŽRĄzßļ+thŅf#oq`±qžäWeżtž¬œēŻ€®ųŲ Hŗē¶ź5ĄM>}÷޵‡łn ü¤+ęĖYośkńĀżnƒnŪūóŪī8ċĪē:MŚvöīŁĀ"„BˆŚ£č¦’ĘRĄŚ ź–Įƒ»‹/¾Ų 4(r5EÓ×4żsĆFĻæœ’ž›®‘–[×ļ‚J!„ØĻø` fŅ O!JY„ ‘¢BŌ'žžłhK!B!„(("^EBQ²¾-råņŸūuHóĶz»^<ķ•Ćü³’q¾[§y«Č„"Ż~~„kĶčĀ4Ž_-ü$Śs®q³ņ’³äײ÷^t³’y~“WŽż—Ł;“ę²ą?+gæķU„p3oFč?|»j™Ÿ°+-·ŚĶuŽ’”hÆœÅ“ĘŗÅo<ķe²éĻĪvM:t‰öŹIŗ/£Y—^‰÷E|0›i6:•ż'ÉÆyOŻm•³Ļo®r7žį—®OļdæÖ|ń‰[TvoŠ8įY“>XāÄ„ē¤“_+?Ī|^ėD’]æģž’ī‹’|»²ÜÆ8­¶Ł#ŚŖH’_įMņ‹{ś.‡_üēī»ļvƆ ‹\R„q'7uŽ©½-аŃó/'ß<ŸU\\śłOż:¤ÕÖ{$VųTT¹*Ę­N’GbņĘi}}%’óŽ7M‰öŹ”¢švć/¢½Lŗ– ™¤ Ÿ’šßl01W*œ©ēż8ŚĖš/‚Ä&K‚ūJŖ¬˜#u÷ƞZīĪß„¹ėŪ·ÆėsÕ#×rø§\b –$J‘¹ŠŚŽ{āųČ÷Ä½Åłä_×ø9’ķeŅėüĒ]ė^2 „×~Ż-«Ą@œ2īķ9'‰āæā…ł$ō+Žh@›_įÉcq‘ś›t_œŸķ¾ųo¶Ęqæāż—£½L¶üĆ?ļ9Wف€ļrč’E{åķśč>ŗżŌČ„"ķwR¢Ø&ŒßÆ^ķUd½v›$–Sć ų$˜ė'É/ŅĒWQ~Nŗļ$æHqæĀFC¾żL*o8yYC(  Ł „Ńī+‰ę]{'Žo<†p~’_¹ ėwÜ,«øØNc’d;VģŌX\üo±‹Hžs®ø'žˆĒ8<ēĶ;×½tL›Č„"ˆČ¤t_—"’8ĢV”’ŽwśĖ¬hÆŹŽwÆĢžī7)‘Iå@e 5üŠē1Ņ`uÉŹj‡Iep”j»ß»Ä-zż‰jē±8UÉc!a‹Ē1$=gŅE¼|  ķ{R¢_ÄE’Šżæunõėj‹‹Źž(źŪoæ½3fŒ·\ˆĀP,ęŌl•TRžĻ7ĀĘBų_ž?7¼NU €ˆ„%ōæź“h Ku „‘8’æ÷D.Ij,@®J‘ūJ ųUĖ~Y\Ē ?jŚ"Q$‡Ÿ»#ŚK6ŚīøbeŠZšįsF$$Å}6ŃDši±õn‰a侖äčbĘÆ¤ĘS.ĮJü% īėÓ,–Č~ššU\ąW6qA^I• »|ÄEu!ą/Žš’łµÄ…ȉ‹ĀS }µ5Éó „¼PŸ{ƦŸ(čŒ$‘ ńs捀$ĘāēĮ×|ź×•åy½-"D-¢I“„µB"¾d#~b"\’H:/Ū¹IH\ˆ4zµšh-!DCDāB!„%oq1éŌ­£­Ō—Kßŗp/7ūŽ‹"—ځĮ+ų%„BˆŅ!/q±ų']Ӎ6÷۟=}»’$ś&CĻØõŒ­žģ#×b‹£=!J&ŃBˆ†F^ābłÆøõ;÷tÓn8Ö}9óM·ŻåĻŗ¶;ńǾZ0Ū[xÆėB°jp>n3žś揵ćÕć7õ‹—ķ’ˆ˜V½śmą<žĻy¬ŁžcīožŁ?ķĪuŲ·ó ®Ėp'|ƜG®K»4ź¤ČUˆš1|ųšhK!ł‰‹÷_rĖߛčÖߨ‡Ū|DÅ÷¢?üóń®y÷¾ž½į6;īļ>{źvļĪ`Ū‹Ÿr=~õGææ^ė ]Ÿ«'ŗN{ wK¦žĒĻö’eļNt­¶-7wł“—ż’ywýwß,ļßĮżī«/ż>īėµŽČ}žŸæśóyļøē‰·¤ßūå\ŗXęžæ?¹.G^čŻ×iŗ!üŪų§æ÷įXöī i‘#„BˆŖQ©øĄšõāyn³£/u _zØB„K…Ķ1„ĆēćG»•³¦z”øouĘ=nżŽ]żžźy¦÷7mįÖYƒœ’_żŁ‡&™į;€ÕćėEs}wɊé“\—ĆĻOŸ‡ućē’ķŽ¾to‰ĄŚĀ’¼ų€Ūš'æJŸPĀóEŁ}}·f„_ŽõŚvvĶ6ŻĘŸ#„BˆŖQ©øX2łiß=A%ÜżW7øļ»8ŻõŠøyk_ońŪŃ~Į‚Ą8 ,tßĮŸ¾‹c›ņ.Ž/gNń3Ķeū?ā éF[Dg§b‘@œ —… °¦¬*-€Pa&7®‹õ£Ķū{ėDē~S–ķ½ØAŠą7˜ÅÖiŅÜuŲżp߯C‹‰"!„BTJÅŻTĪ€Ąč°ūīż‘‡{Į~ӍzŗÉ§ļąŽ¹t÷ŻŖåž<,­z šŪßĒ*å!Ū’é2Ł ²`ēŅ ‚bę_Ļš’×iŚŅ}³$åžÉ—{ńćÆŪoˆ›7öoåĄ*ŅrėŌLbX-¾^ś¹?‘d‚l“’ɾ»÷ÅÆgŸz·>¬œIrČ!nöģ”ˆÕG³ !"%;ż70×,łĢēÕĒ2ķw›6mܬY³ü=ö˜{ä‘G4©V@ÓWަ’nŲ賗“ožĻk@g1B÷F›>?‰öDu¹ńĘŻ£>ź¦LIua­ųӟžä.¾ųb !„Õ¢dÅć/čV5Ą0 Ę„—^źŽ;ī8}C!Dµ)Yq! ǰaĆüšo‹`Į8ķ“Óü¾Ø9X…„¢”Qkc.¾łö;węčēŻ‹ļĪuļ|<ß}żķ·ŃQ”¬^āÜó×;·ó εė96\ÖkÜŲõڬ“Škcwżń{ŗuWO‡ė“ėõõ¹7lōüĖÉ7Ļ׊øxvŹl÷«Ÿr­›µtėŗ6®åśøu~“NtT+K>}ÓµŁ4łķ‘†Ęwßē–õ„ūś‡%néWĖܘӆø½śVżõd‰‹ś*—†ž9łęł‚w‹|óķ÷īW7=åÖūQK×±YWצY+ ‹AĀ¢Ņ,i·Só®®ń­Üš2±Œ5N!Då\\œ9ś9×d \×¶š„JŌz“ļźÖmŌÜwó !„Øœ‚‹‹Ž™ćZ®×.Ś¢~Цi{7į­O£½üéŚU"[Ńš(øøxļ“~Œ…õ Ņō“9_D{łĆ¤dBŃŠ(ü˜‹ļ¾Ó Qļ Mė'!„ȏ‚‹ !„B4l$.„ØE&L˜m !DĆAāBˆZdšąĮіB4$.ź‡ ŲØŽOb$„¢tø(—żjk_¹‡Kļī-££±sYƒ ƒlĖoéīĻ«)wŸ»ƒ_„BˆŚF⢆PaļŚ«­ŸՖĒ^üĢżńŌŽ‰Ā W×–īżWų5<2ń³ō’žpėŪŽmŌ£3Ón·<2Ó» !„„‚ÄE @aē~2µ?vŃ_ߏ\…Bˆu•3B„1`c)’ĘeäāĒ}ŚūuX©#ā0ī#É¢M˜[”[& Ö¬*N`æßV­£=ē­/B!²!qQCؤ“0‹…Y0؜97ģn0÷ŖŠ±M“¬Ö’|At ¬[†0`Ķˆe" gu,,"…&ŃB4D$.j]ńń†Æ "§+ƒóĀ®öqĻöŚj –¬‰¶jʤiKÓ~³Ęš,a8Y4“zh-!DCDā¢Š5@eĢÉ9ŅŚ§k“q….Ćö9ž/’ŗŠ[¬;ÅĘ`TŗeøĪÆģZaPŖ©ŠąB!B$.jČ”½źV¬ž¦B7‚ –¤Ņ§’īŅ©iś-‘8X āƒ+s@“0`æ˜O#ž*l¾ą7B+†č°y:Ā{ŖźŲ!„ —F?”m{0JuųсW»½¶ķ5lģĶ ŽģŠČŅē?Óžė~{^“—5r±,VtŌ$Ļד¼(Jį9ŠŚCĻæœ|ó¼,µŻ< ‹†KėÖU°+„õ‰ !j‘%K–D[BŃpøB!DA‘øB!DA)øøXwuÜwßķ Q? MÆ×8yĀ“\L™2%ŚBˆ†CĮÅÅ6]:ŗå_}ķ Q? MoµiĒh/¶ß~ūhK!·ŻÄ-[³0Ś¢~°xõB÷ćmóŸģL!2×?Ų­łīK7s”>5-ź-˜å¾ła„»į„½"!„¹(ü˜‹Ęėø1§qß4Zį>_9Ū-YµLc0DÉAš%ķĪ[1Ė}W––ļ>}’²“]šģ"„õ’‚ĻŠi|óķ÷īĢŃϹ’¾=ǽ’é÷õ·5ū’g½ą£gŪ\­ßR€Į›[oŚŃ ÜvcwĆ {zŃ\4Cgż@346lōüĖÉ7Ļךø™(ŠbDā¢r”w6zžåä›ēeēB!DA‘øB!DA‘ø¢€,]ŗŌŻtÓMўs³gĻŽ¶œwēøBŌw$.„( |õOś“{ōŃGż~·nŻüš}܅¢! q!D3fŒ>|x“—²f\zé„īĘoŌ'Ų… ‰ ! Ģ AƒÜŠ”CÓƒī®]»z7!„hH\Q `„˜0a‚ßžŪßžę­BˆŅĮŗ6㐯5vŖr$.„Øčž@`Ąļ’{u‡” ‡rH“U,Rį@]Q’@<œ~śé_5FX„]ž";™DėĀ /Œ¶D.®øā wĮųķÆ¾śŹ­æžś~[Ō_^xį7pąĄhÆ8øüņĖ£­šD+™Įƒ»ćŽ;Ī 6,=‰]\=ö˜{ä‘G$ė9X.³fĶJ?ŅÄĮģN;ķ“謆GŽyqņ“?¼č—ŖPVaF["dɒ%?”@~ ŻģwķŚ5ķ.D]‘”W«“ēšü·Ų)«T|žeM޵|ūüóĻGgˆśĪŠ”CøńĘżógĶ~C'ß<Æn‘Z„– ­žø7ܧ–Å ƒpéŅ¢õ –o°+Œ•²ēĻ«ä_|±ß•#qQːé·³Į}¬1·)‘ Qü\rÉ%é~wåŪ† @;EYß¾}ż¶Ø‰‹ZʧY/hżP@Éj!Di`oś•oŒÆĄbՐĒYT‡‚ čŒKāł·>væś‘{ńŻOŻ{Ÿ,r«¾ž&:ŅxćŸĪ}žžsnć܎?‹fė­ė¶éŅĪķŃkSwŠĪ›»ĮŪmõ¤¼Z:W¬žŚ~fŖĻūÆō¹ūō‹eśŹ¤EĄ¦Z¹{nč~Ü»‹;~Ÿ>®EÓõ¢#Éä›ēėĢrqŹ­O»/yČŻś’Žp“Ź —UkŹ„…&Ó@–އ9·īśĪõÜ+łx‘,<žĻĶ½ī({^'ŻņTŁ!ŖĻæ_žĄõ8ž6wöčēÜæ^śĄ}²aĮ‘FZ“hYĖ˧_,wžļCwVYžģ6|”Ļƅ NÄEŸSļr÷NxĻW\ß|÷}䌥@X :Ū¹–EÅĶ÷e…’ź²ēuĻ„w]ļwE®BT’ü¤öĒ'ÜĖW5ܼ/D šmYž\ōåj÷ĖžŸ;žOOF®Õ§ÖÅňQćŹ –ÕnłŖ5‘KQb¬\ż[°l•;łÖ§#!ņƒЃ§ł.oB7ełtåWßø‡_œęxįżČ±zŌŖø`ŒÅßžó¶ūlń—‘‹(E,]éžńģ;žy ‘Š’ü”B” ĖWÆń†ß0Ø&µ*.*S?ß}’]“'J™ļ¾’Ž?O!ņĮ›ĖW®‰ĘV4~wP?7õ–每Ÿé~{®_’ļ†_ŗ½6ĪHńį_NņĒć˧ūūóÉūDg„®‡;ėl°ę›ļüóĢ—™3gŗ#Føž={ś©sYŲ>’üóŻ¢E‹¢³2 ĻńÅ#W—v˶Œ92:³"mŪ¶õĒĆkĮwÜįŻ9üŸżžżūū}ƒ°Ś5ā~L:Õ»fQ‘g§Ģnpc,žsåŃīO'ķķĒ–Żšļ×ÜļļļžśĢ[n“ö-ŻÓ—éŽøutfŠ9 WųsĀåƒ9‹Üo~ŗcĮoēń, É^}»ŗ}wģķÕų‰ß!掘åQxhP>óĘĢhÆźŌŖøų`Īāh«z˜"—x Ą°s-Sr^üæį’”y“Z“: Ūł>O*Ż~żś¹Ūn»Ķ͘1#ru~ūŖ«®r›o¾y¢Ą@pN›6müž-·Üā×5aɒ%ŃVE–-[ę×v¼K—.~=iҤ a{õÕWÓē<ōŠC~mŒ7ĪÆ¹WQ‘)3D[ ƒœłS_ńŻņ’Žp»žńwwŃ?_p7?>ÉżöögÜ¦ĒŻā¦Ļ[ā®?~Æč쫿žĘŸ.?9’>/~«D«ĖĮ—=ģÆ[_!~YDķšöĒ £­ŖS«ā¢&óXPŃ3ĻB£®N/dÜFž<Ń$·ū6›ų–5k˜ųī§ž üßöÉtIpš"E¾ĻóŠCõ2"aāĉ~>–ŪoæŻēXŅĒīī½÷^æ¾śźŌóząŅ½]#œįŚkÆM»}öŁ‘kõŲ{ļ½£­” 0^z)õN7ąĒsĻ=ē×L°#*2wŃņh«a°æ¾ģČVŃTVŽ3ņ±h/7ļŗČ5k²n“W3ĀF‘u±`A±†Ż6X\B.ūł@ß=Ćqŗy¬;‚}ŹåĶ;·M»6:ĪgY’ŗ-ģø±YĒV¾!gŻI ļ?Ķ 6°kć'~³m×dæ>×咜ĒõŲēś†…‰ū“óXĒė•ųu’ŗ·ź;ójkU\T2 iąŁ’Œ\RqÉĄGŚ&rIa !Š®EÓō~!É%HD9O>łdŚZńųć»=öŲĆoĆI'äĪ;ļ<æU#Īż÷ßļׇvXŚššĆuēķŚµKū ŠgžIU=zōšėPx˜åb§vņkQN(ė;T֔;ćßĢŽżšń‚e¾Į“ż6ß05P-ÅZēŽ=Į[\¬bå^.ąÆyٽ/ŗŸķ¶„X^pĆOüf{‹_ßż»"€zlč’Ļy\żńW‘¢mŁó¾÷vīĖ’åĻ{é½9¾;ŹÄžŅPµć\ŽP±kKd§(Å™‹„””ļūļ{>#‡ ņčoć>š›2Ł{ńQ¶_hP°¦“Ɉ¶Ŗh¶MeŪB8ķ<ėf •¾Įuģ8pŒsL,qÜ®ƒ’†]‹pÅŁł,q…_¼óĪ;і« ,ŒŻw/ŸÕīQ‚EćČ#ōż 'œąŻļŗ«0sl 0Ą°åœsΉŽ”³Ļ>©ö7Žšk¬X+vģ‰'žškƁččŽ½»ß “N­›ūõĀå«ü:_𮷮ϻįBžße«żXŚ‚ “¬«„õ[³¤ĒPŲ½<öŹG~(¢QEwM>LxūćtWL¾bźŠ_,«ģ×w{œõōų?ĀēΧņPˆ0"īFv\‹U,uīęaFŠyčĪ~æe³&nõšoÓĒYÓxULž„øhײ©[“|u“W‘7gĢ÷ėķ{tņk A!:€Ł%ŁÆmHœ[oŚ.CE3  ‹ ī$ŗq:¶ję÷q'lˆ’¢«+(aŌtvŽqē" Ān…`ŃįXū£nņū SśŁžSדlŁ2ŚrnŊіs’{ŖūÉŗ¬›‚ŹĮ”uĮžūļļ×f‘0+ƒ<LLfÉxłå—ż1$“oŁ,ŚŹMŚ·šåEøPö]~ßKéJĢ*ÉŖ^;×’»¢EKƒØ` é{·’Ś—9t™˜U#.ųū ŃVžģ¼eg7wŃ /dBøw«Üóį˜A½üŚāĢą”Å}ŗwŒ\Rƒić×& ƽŽõ‚‡†ń@ń'ņ§(ÅEU į[ –)«’!BØÜĆÖ~®ė$™ę–hÅLŲl܆%ņ.S,Ök1pŁēø%b,8˜ėæĀLùD!˜š ‹—°+‡šŌ…šŹÅņåå}x;wök,ŒÆX¬›bōčŃ~]±,Œ×ˆZZ°LX÷ĀĀĀE—bĒĘ[„–Ń0!_ŅźŻ{ūģƒ01żĒ+'ņŗ [Čē  įŚ»m=ßv-»6•e¾Ä+ńŽ1«c?ąWūl—·Õ3×µ×&X‰BL› &ŚęäæøQOLöń@ńgÖkQ9E+.ā§a ³`P9cE¹W‡ų€ĪŚ4ƒamĮ\ō{buAŲėV{ĢŗHl©L$ `āńBŸbmco]@ŲķaX·BŲ0~üxæ†öķŪ§».°Z€ ŗĄ,X&ĢJĮ˜ŠpLĘkƽęŲyē”U4lžS–OɓŁ#÷Ÿs°»č˜ĢnĀ| Ūb×2q•,Ūuėč»: ‚ÉŗCVNU‡xÅvĆ«Ģó׏»—aWFe`m€ų3 ްM­āL%„ń@+0Öj‘E).PŠŁ³_Q¦ų±9ĮC” `?)±d`¬ $~=8ń}氍[h‘”{%ģAåā“Ėż’Ćx±„6”…oƒ2nĀÖ ę‰°œ'žx¢_Ć 7Üm%ƒµ >OEm1xš`æęµSÄM(‚lÜįe|ȾūīėE‡T@äI<]TŠäa*:޼@œ:*ÕŻVUŽŗö1·xÅW6ϳؼˆB5‚7o{˜ĮāB™KYb0ėźĘķZ$Š84ŽØŲķĶŹd}†×£+ėĢ#źć‹{ć>ć!Ę@083|ó#kĻK‹Å×»zŲ _gÄ-B¹ n¹†Õ!¬ń;[w½Č¤(Å•ÄL6­*Y`šMX¶oƒsŠŗ7,!˜¬K… m]"I"©2Ė"ĖE\Å×6T¶£FņŪTĪ}ūöõV,6ˆńaƎŅÅ` DDŲuĮboiŲkŖµĶ.»ģā×&`] vlĻ=÷ōk!€Ö-eVWŽø āgԜ…˽‰½ŗßj Ķ`G¬#4v…›x’Łī‹ßŒ\Źłōżēż±÷_śGäāü~øš!J*Zę7`Śéź¾ŖY*0‡D‡VĶźż}Šāēw·÷ÆżÖ¦Š-zqa•ķŠE™sĢĒUē\[’*óµĮ׫—»ķ6u ē”ĢXTęʱ5«–F.)¶Śõh7਑~Łłą "W!Š 6ęS`r©¤ Žģ³ßqpKšH ŸĘęŗ“ĢāßŃĮWŹ­@e›k… Ƕo3DānŸ¦œcv~ø„óō^¾Āł›ŪžI‡Ó°ėĘZ–vķ¤oŽŁU†]?Ū\!ÄSx/!ø¶\×Īvų¬-Ī-“žc¾aā”?\;lVāĶĪ#=Łóā6|Fqų_ŅqKĀ”Žš9WęöšS÷„=ŒŸx:ćŚńs ~ßųŽ70·Čæ_žĄvp’Č„š”„å‚ uĮĒ“£½ˆ&Ķ2fUεJ™õ“’å÷Õæŗ Ż&Ūŗ…Ÿ¾ķ„@­Yµ¬ģžŹ§×®ĻL’g/śBxŽˆĀāÅĪ Åbøšæ“«`ńöqƒ{ų’ų9ģ‡Ē «aቇrkhP ",ų4vRKžĀšI‹ųf…jnļ’śxóŽP`r=Zf̊IA \Ƅ ĒŁg"§pęZŽ!tųŌ8“I±MX™ó­Ł ü9LųÄtܼ掷Ɵ?&~­p~››OŽŪMžń¹Ÿ‡ęÄżūśY5kNūŲaø0_×ę\ęģ ”"bŠĀ’r(UńUUfѬ ¦Ä¶o…po}{trÅŽČĖvm»ā-~67cÅ?aĪ“čqņ •å꯿­ąiÉęĀ?,b –­ņ˜qœÆ„žń³*<·)Ńg$āp}fEKC@ŗqą~ĘĻŽI5T Ó_Ęe~½5|ιü"ī|²āĢŃĻś°’€OŃńtF2ĮYx÷Ķ„_Ó?[’¾o¾Ā}ĒĘÆMĻHW…¤$Ä•ķ¼SƒHŒ¹¾č6Ž"s®žŖœktŲl{æ6«ĘŚfżf­½H¢Ę3m‚kæiļhÆ~S.¤*ĘAe˜õ¦kŸżżmߞoUč¼Åīé’“žĢ²…°`ߎ±@(01k’1½„K¤*[fdŒĻ® ‚Ģ>yüŸžō˜źÕ„Ct$¢ žyZļLż‹ė’Ÿß§eĘ̌#5ŲW׿WZX-¶ū’[&BŹ*šøx3¶sŗbą“ą’{nśŚ*6ū¾a’fź@Ip}*V{u~»®żw„ąų}ś$~”ÓąŚ63„Ur„yč®[ų ūØĆ’"ʘaBÅCŕ‹w?łĀ9„’šā‹x4r]›ū ¾ĀóC <7 +k¾[’4”_>aāCnńŹŚ>O…ā”°#jC%¹DnC‚é™ozģõhÆ HZ†“ą(™Ķ6üT6š‰š°eKĮŹōŅńV6Ö fŗ½üżōŁa@+ŪwS”µt±JÄĶü·Ż4]1PPS˜œļ›šž/Ü /ßĪ Œ˜óm±Ö1ą?­f ‚Āoūģ9_RE@…’e®MÅAø©äö޾›æW*ŁcF>ęŚysoŻ1L”ŁÕ“®“,aŠ[ øŽų+ņ-{³„į7p#]YÜ&‰[ąś“ģIĢ„Ģ}`!Ą €ŲEŌql Ī']šœ+ó +ŻeI :H[v¤īC>ß©uóœ÷Ķó"?ą6ĖSePšRy$‚˜Ż©øķÉās×!|”ļ>f•°–šÉŻ Ļšžó„O>-Nkó1-ŃP„Ą £Ā¤õhSüS 'Šó—®ōk,*„×*Zųōüįx÷ ”Y378B…{EŲPŁ[KåŠ2Ą’“ķ!|VĮ*{k%›•ņ¹6÷Aŋ5%\ģ|ÖÄ5a&ülä ī¤ū¶ i!JkĖŻ!¹ć6ŽłK|ń½T<“–ųņ,•»Y5‘›d‘0Ė÷]™_XxžI`Į”›(Ū5HĖ<¬h¹ī›sāéqJW]mQ2āĀ kLĶT =vČģ«3ņ=7¬”‹ÉjaPъoH-^ėJ° Üā p-{Ž,¹*{āBw³:é# ;×k_&zŻėmU„-­+¬ Viü|š¶žC`!TĪ“‚’PŠĒ… Ö*dt((šĆV$ūts˜  2³ŠĮĄš@WŹŽēß_”õHN„ƒł=\?ŗw Ÿ*üÅ*ž×*Q®mfpZŃXaƽ1Ė_ŪZ²v߈²x…K…Ÿ4v!­cZ¾\kNŅ8‹\×ę>hÉ/ÄkøŲqƒšræ7üū5?Ę ¹ĀtąN=3Ęøšœ‰;Ą²¤Ąó0ĀøĆõĶAx‰g0AiV £}ĖLæų¦”ÉČå—=?ī3Ž Ō%^¹†YŅ ī‹iq’ė¾ OųY~üć>°(Õ%#.€~p¬ ¹*£*ē+TFTJPq„oÉ`­ faXƒöžX]`c.XϘüØw3K‘Ķ¢aĻóƒŃPžaeXöT蘇ćŲo}Siį†`ąÕΰ•Ķ5GAlīXBl …*Öģ#DØĢ,\oēq>Ÿ§U üJ²p“vń;üēŪĢŹłqīčg¦ś}ĀF|„kÉ"°čZ ćĖ&żŹ ÅæWß®~@lh€|®Ķ}dksö©x«@YĒq‹MH®01–![e ×’ėUwTΖư’¼qópæŪ8\’å÷ēF{Ī5’Łõé±!”U'ā'¼7Ž"!=ń¬*ó H[8»6× Ž¶Ū–ŽŅc×°tĘq»0į•tßä+Ī£[ĶŅĒĢBĘk”))qacņiVåÜb…Źs{e)sĮRŹ,_ųq‹ 7“u?0ØŅØķ®X½Ģ ų5sŹXæm¼÷āßĆĄó#Ģ<ŗźD9“<Ō –˜Żˆ/ģĢ\l…„ŁĮ¶h9‡~qZhVŪX/(h¹9Ļ:tßśņ#ŻŹÆ¾ń ƒ@aĻ2¬­ÕnÆŚ`̤Q‚Å% ×ĆRa÷„¹=¬ÄB* i­aī‰ė„į7¼…g½uż6a­7!TņŒĮ¢b•&ä{mĪĮÄnńc ’'üt;Ń¢&®q··8lKRŲ²…‰gŒu+WeMü’–v޲³’<;~2†ĘŗĪˆ[°c¶P”sżlc “jÖƽ„÷†Į>ńžĖ/ƒx@œŁgī¹Ųgść׹8÷ĆŪ1 č“4b÷MڰsWAw•‰#Ė#60·6Ńōß@Ófśo*p*īų\ö éÖ»§^¹ •w|¼ ćsŗ#H)v ຈ•x·Yܝ’®XōIśzĒk`ݰs"t„ Š€°0¦Ēö³ŻcM(Åéæ’ųaåQ_ ĀäµKkZ¹XĀA©ÅB1‡­®ĮBvį?^Øq~@Ø!H!ˆ[ʦÄÅwn4ż·ØŠŅOŖt”(­Iqsw§ņÆģĒ…ÄŻŁÆĒń0 ṈÜ Āīg»Ē†•.Ā‚×įźā“‹AXŠRelC8ī£X(ę°­ °1®Å,cՅ1 Xß°\ÄĶņ–Qm[, ‰ !ÄZZ6³)Ć}e3«×5Ä/&śbŒēbŪŚ€A©Œg '_«¤= Ņe] Ž:ėõ}µ(ŃWQ…µƒŗE„BQ$Čr!ņ'‹åB”²\!ņ§H-Ķ¢W•Dż@ĻS!D>ŌŖøŲ²æø&ź=O!„łP«ābē­:»õÆķ‰Rf½Ę?ņĻS!„ØŒZ|Ŗvu4f“>°Ī:ė¤?=,DelܾņoZ!Š›ŚVü’jUØÕššv›¹_ģŁĖujÓæu‹рØėn!Dż"ß<_0q!„( $.„Õ„NŅ¢t‘øBäK¾y^c.„BQP$.„BQP$.„BQP$.„BQP$.„BQP²¾-"„hXŌäm!DĆBo‹!„¢Nɰ\!„BŌY.„BQP$.„BQP$.„BQP$.„BQP$.„BQP$.„BQP$.„BQP$.„BQP$.„BQP$.„BQ@œū’-®2%J/¾IEND®B`‚qatengine-1.9.0/docs/install.md000066400000000000000000000254601500416242000164150ustar00rootroot00000000000000# Installation Instructions ## Installing from packages Distributions such as Fedora 34+, RHEL 8.4+ & 9.0+, CentOS 9 Stream, SUSE SLES15 SP3+ and Ubuntu 24.04 each include `qatengine` package built with QAT_HW qatlib intree driver(for 4xxx devices only) within their repositories. Install `qatengine` package using the corresponding distro install command. Refer qatlib [install](https://github.com/intel/qatlib/blob/main/INSTALL) on the configuration settings. More information about installing QAT Engine using intree driver and co-existence is in [here](https://intel.github.io/quickassist/qatlib/index.html) There is also pre-built binary RPM package for the distros like RHEL 9.1, Ubuntu 22.04 and SUSE SLES15 SP3 with QAT_HW(OOT driver for 4xxx device) and QAT_SW co-existence. Please refer [here](qat_common.md#binary-rpm-package) for the details. Also there is dockerfile available for QAT Engine with QATlib and HAproxy with QAT which can be built into docker images. Please refer [here](../dockerfiles/README.md) for more details. ## Installing from Source code. QAT Engine supports various crypto libraries and QAT generations with both hardware and software based accelerations. Follow the steps below to build qatengine for specific target. Clone the the Intel® QAT OpenSSL\* Engine Github Repo using: ``` git clone https://github.com/intel/QAT_Engine.git ``` The complete list of the build configure options to enable or disable feature(s) is available [here](config_options.md). The prerequisite to run `autogen.sh` is to have autotools (autoconf, automake, libtool and pkg-config) installed in the system. - [Install with make depend target](#install-with-make-depend-target) - [Install Pre-requisites](#install-pre-requisites) - [Build QAT Engine for QAT_HW](#build-qat-engine-for-qat_hw) - [Build QAT Engine for QAT_SW](#build-qat-engine-for-qat_sw) - [Build QAT Engine with QAT_HW & QAT_SW Co-existence ](#build-qat-engine-with-qat_hw--qat_sw-co-existence) - [Build Instructions for BoringSSL Library](bssl_support.md) ### Install with make depend target `make depend` target in the QAT_Engine supports cloning and building the dependent libraries OpenSSL, QAT_HW(QAT1.x & QAT2.0 OOT Linux driver) and QAT_SW(cryptography-primitives & ipsec_mb automatically based on the QAT Engine configure flags specified and platform underneath. Please follow the instructions below to use the option. ``` cd /QAT_Engine git submodule update --init ./autogen.sh \ ./configure \ --with-qat_hw_dir=/QAT \ #For QAT_HW supported platforms, Needed only if platform supports QAT_HW --enable-qat_sw \ #For QAT_SW supported platforms, Needed only if platform supports QAT_SW --with-openssl_install_dir=/usr/local/ssl # OpenSSL install path, if not specified will use system openssl make depend make make install ``` Here `make depend` will clone the dependent libraries and install QAT_HW driver in /QAT and QAT_SW in the default path(`/usr/local` for cryptography-primitives & `/usr` for ipsec_mb). `qatengine.so` library will be installed in `/usr/local/ssl/lib64/engines-3` where openssl is also installed as mentioned in the openssl install flag. Please note make depend target is not supported in FreeBSD OS, Virtualized environment, BoringSSL, BabaSSL and qatlib dependency build. The dependency library versions would be latest as mentioned in [Software Requirements](software_requirements.md) ### Install Pre-requisites Install QAT_HW and QAT_SW dependencies based on your acceleration choice the platform supports. ### Install OpenSSL or Tongsuo This step is not required if building against system prebuilt OpenSSL\*. When using the prebuild system OpenSSL\* the qatengine shared library will be installed in the system OpenSSL engines directory. ``` git clone https://github.com/openssl/openssl.git git checkout # Latest OpenSSL version tag Eg: "openssl-3.0.14" ./config --prefix=/usr/local/ssl -Wl,-rpath,/usr/local/ssl/lib64 make; make install ``` If you prefer to use TongSuo (BabaSSL), clone using `git clone https://github.com/Tongsuo-Project/Tongsuo.git` and use the same install steps as mentioned above. It is recommended to checkout and build against the OpenSSL\* or BabaSSL\* release tag specified in the [Software Requirements](software_requirements.md) section. The above example installs headers and libraries in the `/usr/local/ssl` dir. `OPENSSL_ENGINES` environment variable (assuming the example paths above) to find the dynamic engine at runtime needs to be set as below for loading engines at OpenSSL\* ``` export OPENSSL_ENGINES=/usr/local/ssl/lib64/engines-3 ``` Load/Initialize Engine using the the OpenSSL conf file is located [here](openssl_config.md) ### Install QAT_HW & QAT_SW dependencies For **QAT_HW acceleration**, Install the QAT Hardware driver using the instructions from Getting Starting Guide based on the QAT Hardware device for QAT1.x or QAT2.x available in the [IntelĀ® QuickAssist Technology](https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html) page. If **QAT_HW qatlib intree driver** over OOT driver is preferred, then configure the settings and install the driver from [qatlib install](https://github.com/intel/qatlib/blob/main/INSTALL)
User Space DMA-able Memory (USDM) Component The QAT_HW driver requires pinned contiguous memory allocations which is allocated using the User Space DMA-able Memory (USDM) Component supplied within the QAT_HW driver itself. For Multithread use case, the USDM Component provides lockless thread specific memory allocations which can be enabled using the below configure option while building QAT Hardware driver. This is not needed for multiprocess use cases. ``` ./configure --enable-icp-thread-specific-usdm --enable-128k-slab ```
Shared Virtual Memory QAT gen4 devices(4xxx) supports Shared Virtual Memory (SVM) that allows the use of unpinned user space memory avoiding the memcpy of buffers to pinned contiguous memory. The SVM support in the driver enables passing of virtual addresses to the QAT hardware for processing acceleration requests, i.e. addresses are the same virtual addresses used in the calling process supporting Zero-copy. This Support in the QAT Engine can be enabled dynamically by setting `SvmEnabled = 1` and `ATEnabled = 1` in the QAT PF and VF device's driver config file(s) along with other prerequisites mentioned below. This is **applicable only for OOT driver package** and not supported in qatlib intree driver. The Following parameter needs to be enabled in BIOS and is supported only in QAT gen4 devices. * Support for Shared Virtual Memory with Intel IOMMU * Enable VT-d * Enable ATS
For **QAT_SW Acceleration**, Install IntelĀ® Crypto Multi-buffer library using the Installation instructions from [Crypto_MB README](https://github.com/intel/cryptography-primitives/tree/develop/sources/ippcp/crypto_mb) and IntelĀ® Multi-Buffer Crypto for IPsec Library using the instructions from the [intel-ipsec_mb README](https://github.com/intel/intel-ipsec-mb). ### Build QAT Engine for QAT_HW Build steps for QAT1.x or QAT2.x **OOT driver** unpacked within /QAT using OpenSSL\* built from source and installed to `/usr/local/ssl`. If System Openssl is preferred then `--with-openssl_install_dir` is not needed. ``` cd /QAT_Engine ./autogen.sh ./configure \ --with-qat_hw_dir=/QAT \ --with-openssl_install_dir=/usr/local/ssl make make install ```
Copy the IntelĀ® QuickAssist Technology driver config files This step is not needed when qatlib intree driver is used which is managed by `qatmgr` in the qatlib. QAT Engine built against OOT Driver needs Intel® QAT Driver conf files with `[SHIM]` section instead of default `[SSL]`. The default section name in the QAT OpenSSL\* Engine can be modified if required by either using the engine ctrl command SET_CONFIGURATION_SECTION_NAME or by setting the environment variable "QAT_SECTION_NAME". The example conf files with `SHIM` section are located at `/path/to/qat_engine/qat_hw_config` The files are grouped by acceleration device(dh895xcc or c6xx or c3xxx or 200xx or c4xxx or 4xxx), please choose the files according to the QAT acceleration device type in the system The files are also split into `multi_process` and `multi_thread` based use cases. For event driven polling based application, change the parameter `Cy$nIsPolled=1` to `Cy$nIsPolled=2` for each instances($n) in the respective config file to use event driven polling support. Event driven config files are only supported in Linux. Once you have decided which config file you should use, or created your own you should follow the procedure below to install it: 1. Stop the acceleration driver as described in the Section "Starting/Stopping the Acceleration software" from the Getting Started Guide available in [Intel® QuickAssist Technology Driver](https://developer.intel.com/quickassist) 2. Copy the appropriate `.conf` file to `/etc` for n number of QAT devices 3. Start the acceleration driver as described in the Section "Starting/Stopping the Acceleration software" from the Getting Started Guide available in [Intel® QuickAssist Technology Driver](https://developer.intel.com/quickassist)
Build steps for **qatlib intree driver** installed from source(/usr/local) and policies configured as in [qatlib install](https://github.com/intel/qatlib/blob/main/INSTALL) using the system OpenSSL. ``` cd /QAT_Engine ./autogen.sh ./configure --with-qat_hw_dir=/usr/local make make install ``` ### Build QAT Engine for QAT_SW Build steps for crypto_mb and intel_ipsec_mb installed to its default location `/usr/local/lib` and `/usr/lib` respectively with system OpenSSL. If Crypto_mb and intel_ipsec_mb is installed using the prefix option then pass the corresponding paths using the configure flags `--with-qat_sw_crypto_mb_install_dir` and `--with-qat_sw_ipsec_mb_dir`. ``` cd /QAT_Engine ./autogen.sh ./configure --enable-qat_sw make make install ``` Note : If QAT_HW qatlib intree driver is installed in the system then configure `--disable-qat_hw` to use QAT_SW only acceleration. ### Build QAT Engine with QAT_HW & QAT_SW Co-existence Build steps for QAT_HW & QAT_SW Co-existence with QAT_HW 1.x or 2.0 OOT driver unpacked within `/QAT` and QAT_SW libraries installed to default path and OpenSSL built from source is installed in `/usr/local/ssl` ``` cd /QAT_Engine ./autogen.sh ./configure \ --with-qat_hw_dir=/QAT \ --enable-qat_sw \ --with-openssl_install_dir=/usr/local/ssl make make install ``` The default behaviour and working mechanism of co-existence is described [here](qat_coex.md#qat_hw-and-qat_sw-co-existence) ### Build Instructions for BoringSSL Library Refer [BoringSSL section](bssl_support.md) for steps to build the IntelĀ® QAT Engine for BoringSSL\* library which supports RSA and ECDSA QAT Hardware and QAT Software Acceleration using BoringSSL. qatengine-1.9.0/docs/legal.md000066400000000000000000000003661500416242000160310ustar00rootroot00000000000000# Legal Intel, Intel Atom, and Xeon are trademarks of Intel Corporation in the U.S. and/or other countries. \*Other names and brands may be claimed as the property of others. Copyright © 2016-2025, Intel Corporation. All rights reserved. qatengine-1.9.0/docs/licensing.md000066400000000000000000000010601500416242000167100ustar00rootroot00000000000000# Licensing The Licensing of the files within this project is split as follows: | Component |License | Details | |---|---|---| | IntelĀ® QuickAssist Technology(QAT) OpenSSL* Engine | BSD-3-Clause | This product includes software except qat_hw_config dir. | Example Intel® QuickAssist Technology Driver Configuration Files contained within the folder `qat_hw_config` | Dual BSD/GPLv2 License | Please see the file headers of the configuration files, and the full GPLv2 license contained in the file `LICENSE.GPL` within the `qat_hw_config` folder. | qatengine-1.9.0/docs/limitations.md000066400000000000000000000205571500416242000173050ustar00rootroot00000000000000## Limitations * When **forking** within an application it is not valid for a cryptographic operation to be started in the parent process, and completed in the child process. * Only **one level of forking is permitted**, if a child process forks again then the Intel® QAT OpenSSL\* Engine will not be available in that forked process. * **Event driven mode** of polling operation is not supported in the FreeBSD Operating system or in the qatlib RPM. * QAT Engine doesn't support **ENCRYPT_THEN_MAC**(default) mode of operation meaning when Encrypt then MAC is negotiated for symmetric ciphers say AES-CBC, the requests will not get offloaded via QAT_HW, instead uses OpenSSL SW. Disable ENCRYPT_THEN_MAC with the flag `SSL_OP_NO_ENCRYPT_THEN_MAC` programmatically using SSL_CTX_set_options() to offload symmetric chained ciphers via QAT_HW. Please note disabling ENCRYPT_THEN_MAC has security implications. * OpenSSL 1.1.1n and OpenSSL 3.0.2 introduced misleading error message(undefined symbol: **EVP_PKEY_get_base_id**) during engine load which can be ignored as it is not a real failure. This is later fixed in OpenSSL\* 1.1.1o and OpenSSL\* 3.0.3 release. * QAT Engine built for OpenSSL3.0 is only compatible with dependent libraries also linked with OpenSSL3.0 libraries due to [OpenSSL#17112](https://github.com/openssl/openssl/pull/17112). Same applies for OpenSSL 1.1.1. * HKDF based on SM3 is not supported in QAT_HW, The request will fallback to OpenSSL software if fallback been enabled otherwise failures are observed. * There is a limitation with thread specific USDM: *memory allocated in one thread should be freed only by the thread which allocates it*. When the QAT driver is configured with `--enable-icp-thread-specific-usdm`, and when QAT_engine is used as the default OpenSSL engine, it is required that OPENSSL_init_ssl() be called from the same thread that calls OPENSSL_cleanup(). Incorrect cleanup can lead to a segmentation fault (segfault). Also, memory allocated in a thread is freed automatically when the thread exits/terminates, even if the user does not explicitly free the memory. * SVM mode is not supported with BoringSSL library and KPT mode. * AES-CCM ciphers are not enabled in OpenSSL by default. Need to enable it manually using the openssl.cnf section as below ``` openssl_conf = cipher_conf [cipher_conf] ssl_conf = cipher_sect [cipher_sect] system_default = system_cipher_sect [system_cipher_sect] Cipherstring = ALL Ciphersuites = TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 ``` * FreeBSD qatlib Header files are not installed to the install path due to a known issue in the driver. Header needs to be manually copied in the default path (/usr/local) as below or to the install path specified during driver installation. ``` # Create destination directory from the QATlib 23.09 top directory: ./install-sh -c -d '/usr/local/include/qat' # Install Header Files: /usr/bin/install -c -m 644 quickassist/include/cpa.h quickassist/include/cpa_dev.h quickassist/include/cpa_types.h quickassist/include/lac/cpa_cy_common.h quickassist/include/lac/cpa_cy_dh.h quickassist/include/lac/cpa_cy_drbg.h quickassist/include/lac/cpa_cy_dsa.h quickassist/include/lac/cpa_cy_ecdh.h quickassist/include/lac/cpa_cy_ecdsa.h quickassist/include/lac/cpa_cy_ecsm2.h quickassist/include/lac/cpa_cy_ec.h quickassist/include/lac/cpa_cy_im.h quickassist/include/lac/cpa_cy_key.h quickassist/include/lac/cpa_cy_kpt.h quickassist/include/lac/cpa_cy_ln.h quickassist/include/lac/cpa_cy_nrbg.h quickassist/include/lac/cpa_cy_prime.h quickassist/include/lac/cpa_cy_rsa.h quickassist/include/lac/cpa_cy_sym_dp.h quickassist/include/lac/cpa_cy_sym.h quickassist/include/dc/cpa_dc.h quickassist/include/dc/cpa_dc_dp.h quickassist/include/dc/cpa_dc_chain.h quickassist/lookaside/access_layer/include/icp_sal_poll.h quickassist/lookaside/access_layer/include/icp_sal_user.h quickassist/lookaside/access_layer/include/icp_sal.h quickassist/lookaside/access_layer/include/icp_sal_versions.h quickassist/utilities/libusdm_drv/qae_mem.h /usr/local/include/qat ``` * HKDF infolen > 80 is not supported due to QAT driver limitation. * Symmetric keys are not protected by [Key Protection Technology](#qat_hw_kpt.md). * QAT Engine does not process the plaintext if the length is not a multiple of AES_BLOCK_SIZE for chained cipher AES-CBC-HMAC-SHA when built with OpenSSL v3 and above. No padding would be added to the plaintext as specified in RFC 5652 or RFC 5246. ## Known Issues ### Functional * AES-CBC-HMAC-SHA chained ciphers does not support **pipeline feature** when built with OpenSSL 3.0 as the corresponding support is not available in OpenSSL 3.0 - [OpenSSL#18298](https://github.com/openssl/openssl/issues/18298) * There is an issue in **sshd** daemon application when using the QAT for default openssl. sshd looks to be closing the file descriptors associated with QAT engine and driver after initialising openssl. Similar issue was present which prevents the ability to ssh out of the system using the QAT engine in versions of the ssh application before OpenSSH 8.7. The issue has been fixed with this commit [c9f7bba](https://github.com/openssh/openssh-portable/commit/c9f7bba2e6f70b7ac1f5ea190d890cb5162ce127) This update can be applied to sshd to work-around the issue. * Known issue with QAT_SW SM2 in `ntls` mode since QAT_SW SM2 doesn't have plain sign and verify operation support in engine. Disable QAT_SW SM2 to workaround the issue with ntls. No issues with TLS mode since it uses digestsign and digestverify which is supported. * Known issue in Software fallback with OpenSSL3.0 Engine(only) when disabled via co-existence algo bitmap for algorithms PRF, HKDF, SM2 & SM3. QAT_HW PRF and QAT_HW HKDF are not accelerated in OpenSSL 3.0 engine due to the issue [OpenSSL#21622](https://github.com/openssl/openssl/issues/21622) * Known issue in Co-existence mode with QAT provider on OpenSSL 3.2 and above during QAT_SW offload when QAT_HW modules are not present. * Known build issue with the latest commit of BoringSSL; hence, IPP Crypto 2021.10 should be used for the QAT engine with BoringSSL (use the BoringSSL commit mentioned in the Software requirements section). ### Performance * There is known performance scaling issue (performance drop with threads >32) with ECDSA Ciphers in the QAT Software acceleration using multithread mode in the Haproxy application. This issue is not observed when using RSA ciphers or in multi-process mode. * SM3 is disabled by default due to performance drop observed in **multithread scenario** for all ciphers suites due to the additional locks at engine_table_select introduced by engine digest registration in OpenSSL - [OpenSSL#18509](https://github.com/openssl/openssl/issues/18509) * In Co-Existence mode, Performance is lower than QAT_SW only when process number >=64 due to known issue. * Note regarding multithreaded performance with OpenSSL/*: In some cases, using QAT_Engine with OpenSSL at higher thread counts can produce *worse* performance, due to issues in the way OpenSSL handles higher thread counts. Check for `native_queued_spin_lock_slowpath()` consuming CPU process idle time, and see the OpenSSL GitHub issues and web articles below. - Performance bottleneck with locks in engine_table_select() function - [OpenSSL#18509](https://github.com/openssl/openssl/issues/18509) - 3.0 performance degraded due to locking - [OpenSSL#20286](https://github.com/openssl/openssl/issues/20286) - https://serverfault.com/questions/919552/why-having-more-and-faster-cores-makes-my-multithreaded-software-slower - https://superuser.com/questions/1737747/high-system-cpu-usage-on-linux * Nginx Handshake Performance in OpenSSL3.0 is slightly slower compared to OpenSSL 1.1.1. The same behaviour is observed in OpenSSL_SW as well [OpenSSL#21833](https://github.com/openssl/openssl/issues/21833) * Performance scaling is not linear in QAT2.0 supported platforms for ECDSA and Chacha-Poly algorithms. * Performance drop observed with ECDSAP256 algorithm in the OpenSSL speed tests with FreeBSD 14 intree driver. * Performance drop observed in QAT Engine with [async-nginx](https://github.com/intel/asynch_mode_nginx/tree/master) on FreeBSD OS with asymmetric and symmetric ciphers. * BoringSSL on FreeBSD OS is validated functionally with limited performance validation on Nginx QUIC POC. qatengine-1.9.0/docs/openssl_config.md000066400000000000000000000123311500416242000177500ustar00rootroot00000000000000# Using the OpenSSL\* Configuration File to Load/Initialize Engines OpenSSL\* includes support for loading and initializing engines via the openssl.cnf file. The openssl.cnf file is contained in the `ssl` subdirectory of the path you install OpenSSL\* to. By default OpenSSL\* does not load the openssl.cnf file at initialization time. In order to load the file you need to make the following function call from your application as the first call to the OpenSSL\* library: OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL); The second parameter determines the name of the section containing the application specific initialization settings. If you set the parameter to NULL as in the example above it will default to look for the `openssl_conf` section. If you want to use your own section you should declare a structure of type `OPENSSL_INIT_SETTINGS` and set the `appname` field to a string containing the section name you wish to use. The example config file sections below assume you are using the default `openssl_conf` section name. If converting an existing application to use the Intel® QAT OpenSSL\* Engine you may find that the application instead makes the now deprecated call to: OPENSSL_config(NULL); Where the parameter is a const char\* pointer to the `appname` section you want to use, or NULL to use the default `openssl_conf` section. Currently this will give the same behaviour as the `OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)` call but as it is deprecated it should not be relied upon for future use. For further details on using the OPENSSL_init_crypto function please see the OpenSSL\* online documentation located at: In order to start using the openssl.cnf file it needs some additional lines adding. You should add the following statement in the global section (this is the section before the first bracketed section header): openssl_conf = openssl_init The string `openssl_init` is the name of the section in the configuration file which describes the application specific settings. You do not need to stick to the naming convention here if you prefer to use a different name. The `openssl_init` section can be located at the end of the global section (as the first bracketed section), or further down the configuration file. It should have the following added: [ openssl_init ] engines = engine_section The `engines` string is a keyword that OpenSSL\* recognises as a configuration module. It should be set to a string which is the section name containing a list of the engines to be loaded. So for the Intel® QAT OpenSSL\* Engine the section should contain: [ engine_section ] qat = qat_section The `qat_section` contains all the settings relating to that particular engine. For instance it may contain: [ qat_section ] engine_id = qatengine dynamic_path = /usr/local/ssl/lib/engines-3/qatengine.so # Add engine specific messages here default_algorithms = ALL Where `engine_id` specifies the name of engine to load (should be `qatengine`). Where `dynamic_path` is the location of the loadable shared library implementing the engine. There is no need to specify this line if the engine is located within the standard path that OpenSSL\* was installed to. Where `default_algorithms` specifies which algorithms supplied by the engine should be used by default. Specify `ALL` to make all algorithms supplied by the engine be used by default. In addition the `qat_section` may contain settings that call custom engine specific messages. For instance: ENABLE_EVENT_DRIVEN_MODE = EMPTY is functionally equivalent of making the following engine specific message function call: ENGINE_ctrl_cmd(e, "ENABLE_EVENT_DRIVEN_MODE", 0, NULL, NULL, 0); You should set the setting to `EMPTY` if there are no parameters to pass, or assign the value that would be passed as the 4th parameter of the equivalent `ENGINE_ctrl_cmd` call. It should be noted that this mechanism is only useful for passing simple values at engine initialization time. You cannot pass 3rd parameter values, pass complex structures or deal with return values via this mechanism. Engine specific messages should be specified before the `default_algorithms` setting or incorrect behaviour may result. The following [messages](engine_specific_messages.md) are supported: * `ENABLE_EVENT_DRIVEN_POLLING_MODE` * `ENABLE_EXTERNAL_POLLING` * `ENABLE_INLINE_POLLING` * `ENABLE_SW_FALLBACK` * `SET_INTERNAL_POLL_INTERVAL` * `SET_EPOLL_TIMEOUT` * `SET_MAX_RETRY_COUNT` In case of forking, the custom values are inherited by the child process. By default the engine will get initialized at the end of this section (after all the custom engine specific messages have been sent). This can be controlled via an additional `init` setting that is out of scope of the documentation here. For further details on using the OpenSSL\* configuration file please see the OpenSSL\* online documentation located at: By setting up the configuration file as above it is possible for instance to run the OpenSSL\* speed application to use the Intel® QAT OpenSSL\* Engine without needing to specify `-engine qatengine` as a command line option. qatengine-1.9.0/docs/qat_coex.md000066400000000000000000000144411500416242000165470ustar00rootroot00000000000000# QAT_HW and QAT_SW Co-existence Intel® QAT OpenSSL\* Engine supports QAT_HW and QAT_SW Co-existence when both QAT_HW flag `--with-qat_hw_dir=/path/to/QAT_Driver` and QAT_SW flag `--enable-qat_sw` configured in the build configure option to provide acceleration from both QAT_HW and QAT_SW combined. If the platform has support for both QAT_HW and QAT_SW, the default behavior is to accelerate asymmetric algorithms and Symmetric chained ciphers using QAT Hardware and Symmetric GCM Ciphers using QAT Software. If the platform doesn't have QAT Hardware support then it will use QAT_SW Acceleration for QAT_SW asymmetric algorithms that are supported in the qatengine. The default behavior can be changed using corresponding algorithm's enable flags (eg:--enable-qat_sw_rsa) in which case the individual algorithms enabled (either qat_hw or qat_sw) in the build configure will get accelerated. For the algorithms RSA2K/3K/4K, ECDHP256/P384/X25519 & ECDSAP384 to reach better performance, QAT Engine uses both QAT_HW and QAT_SW for acceleration when QAT_HW capacity is reached with co-existence build. The Control flow is mentioned in the Figure below.

drawing

## Recommended settings and working mechanism 1. For those algorithms that can achieve stronger performance with QAT_SW, we only use QAT_SW by default. These algorithms include:`AES-GCM`, `ECDSA-P256`, `SM4-CBC(256-1024 bytes)`. 2. For those algorithms that can achieve stronger performance with QAT_HW, the request will be offloaded to QAT_HW first, and after QAT_HW capacity is reached, it will be processed through QAT_SW. These algorithms include: `RSA-2K/3K/4K`, `ECDSA-P384`, `ECDH-P256/P384/X25519`, `SM4-CBC(2048-16384 bytes)`. 3. It is recommended to set "LimitDevAccess" to 0 in QAT_HW driver config file to utilize all the available device per process for Co-existence mode to fully utilize QAT_HW first and then utilize QAT_SW. 4. For SM4-CBC, It is recommended to set "CyNumConcurrentSymRequests" to be smaller to trigger QAT HW `RETRY`. And The number of async jobs should be appropriate, Number of async requests has to be maintained properly to achieve optimal performance. The following is a best known configuration( tested with 1 QAT DEV using OpenSSL speed App on SPR and the "CyNumConcurrentSymRequests" is set to 64): | Packet Length | 1 Multi | 2 Multi | 4 Multi | 8-64 Multi | | :---: | :---: | :---: | :---: | :---: | | 16 bytes | 64 async jobs | 64 async jobs | 64 async jobs | 64 async jobs | | 64 bytes | 64 async jobs | 64 async jobs | 64 async jobs | 64 async jobs | | 256 bytes | 96 async jobs | 96 async jobs | 96 async jobs | 96 async jobs | | 1024 bytes | 96 async jobs | 96 async jobs | 96 async jobs | 96 async jobs | | 8192 bytes | 48 async jobs | 88 async jobs | 136 async jobs | 176 async jobs | | 16384 bytes | 48 async jobs | 88 async jobs | 152 async jobs | 176 async jobs | ## Run time configuration using HW & SW algorithm bitmap Intel® QAT OpenSSL\* Engine supports a runtime mechanism to dynamically choose the QAT_HW or QAT_SW or both for each algorithm using the ENGINE ctrl commands: **HW_ALGO_BITMAP** & **SW_ALGO_BITMAP**, Bitmap of each algorithm is defined below: | Algorithm | Bit | HW or SW supported(Priority) | | :- | :- | :-: | | RSA | 0x00001 | Both (HW > SW) | | DSA | 0x00002 | HW | | DH | 0x00004 | HW | | ECDSA | 0x00008 | Both (SW > HW for P256) (HW > SW for other curves) | | ECDH | 0x00010 | Both (HW > SW) | | ECX25519 | 0x00020 | Both (HW > SW) | | ECX448 | 0x00040 | HW | | PRF | 0x00080 | HW | | HKDF | 0x00100 | HW | | SM2(ECDSA) | 0x00200 | HW > SW | | AES_GCM | 0x00400 | Both (SW > HW) | | AES_CBC_HMAC_SHA | 0x00800 | HW | | SM4_CBC | 0x01000 | Both (HW > SW) | | CHACHA_POLY | 0x02000 | HW | | SHA3 | 0x04000 | HW | | SM3 | 0x08000 | SW | | SM4-GCM | 0x10000 | SW | | SM4-CCM | 0x20000 | SW | | AES-CCM | 0x40000 | HW | **Note: ECDH-SM2 is included in ECDH SW group.** If one algorithm is expected to be enabled, the preconditions are: 1. Supported in configuration, e.g., `--enable-qat_hw_gcm`. 2. Enabled in [default algorithm] directive, e.g., `RSA/EC/DH/DSA/CIPHER/PKEY/DIGEST/ALL`. Algorithms that are enabled in HW_ALGO_BITMAP will gets accelerated via QAT_HW method and algorithms that are enabled in SW_ALGO_BITMAP will gets accelerated via QAT_SW method. If an algorithm is enabled in both HW_ALGO_BITMAP and SW_ALGO_BITMAP then the one that has highest priority (listed above) will be accelerated. If none is enabled, OpenSSL SW will be used. **Note:** 1. The default HW_ALGO_BITMAP and SW_ALGO_BITMAP value for each algorithm are set to 0xFFFF, which means all algorithms are enabled by default. If both HW&SW bitmap aren't set, QAT_Engine will offload the algorithm depending on the configuration and [default algorithm] setup. 2. The XX_ALGO_BITMAP commands are only workable when the corresponding offload mode is enabled, e.g. SW_ALGO_BITMAP is supported only if the QAT_SW is enabled. 3. In case the QAT_HW&QAT_SW are both enabled, it's recommended to set both HW_ALGO_BITMAP and SW_ALGO_BITMAP in the meantime, disabling the unnecessary and enabling the necessary offload mode for each algorithm. 4. The offload mode with higher priority must be disabled when you want to enable the lower priority one for each algorithm. **Example 1:** Algorithm combination to be enabled: RSA(HW), ECDSA(HW), ECDH(SW), ECX25519(HW), SM2(SW), AES-GCM(SW). Make sure these algorithms are supported in configuration and already set `RSA,EC,PKEY,CIPHER` or `ALL` in the [default algorithm]. ``` HW_ALGO_BITMAP: RSA(0x0001) + ECDSA(0x0008) + ECX25519(0x0020) = 0x0029. SW_ALGO_BITMAP: ECDH(0x0010) + SM2(0x0200) + AES-GCM(0x0400) = 0x0610. ``` * openssl.conf ``` [qatengine_section] engine_id = qatengine default_algorithms = ALL HW_ALGO_BITMAP = 0x0029 SW_ALGO_BITMAP = 0x0610 ``` * testapp ``` ./testapp -engine qatengine -async_jobs 1 -c 1 -n 1 -nc 1 -v -hw_algo 0x0029 -sw_algo 0x0610 [test_case] ``` **Example 2:** Lower priority Algorithms need to be enabled: RSA(SW), AES-GCM(HW): ``` HW_ALGO_BITMAP: 0xFFFF - RSA(0x0001) = 0xFFFE. # Disable the RSA HW BITMAP because it has higher priority. SW_ALGO_BITMAP: 0xFFFF - AES-GCM(0x0400) = 0xFBFF. # Disable the AES-GCM SW BITMAP because it has higher priority. ``` qatengine-1.9.0/docs/qat_common.md000066400000000000000000000063261500416242000171040ustar00rootroot00000000000000# OpenSSL 3.0 Provider Support Intel® QAT OpenSSL\* Engine supports Provider interface for OpenSSL 3.0. The qatprovider support can be enabled using configure flag `--enable-qat_provider` and the default if not specified will use engine interface. This support is added as an experimental feature and tested with OpenSSL Speed and testapp only and not tested with any application. Example OpenSSL Speed command to test using qatprovider: * QAT_HW ./openssl speed -provider qatprovider -elapsed -async_jobs 72 rsa2048 * QAT_SW ./openssl speed -provider qatprovider -elapsed -async_jobs 8 rsa2048 # FIPS 140-3 Certification Intel® QAT OpenSSL\* Engine contains changes to comply with FIPS 140-3 Level-1 Certification requirements using QAT Provider against OpenSSL 3.0.8. The FIPS support can be enabled using the configure flag `--enable-qat_fips` only with OpenSSL 3.0 using provider interface which needs to be enabled using `--enable-qat_provider`. When FIPS flag is enabled along with provider for OpenSSL3.0, it will run self tests, integrity tests and will satisfy other FIPS 140-3 CMVP & CAVP requirements. The FIPS is build as RPM using the specfile fips/qatengine_fips.spec with QAT_HW & QAT_SW Coexistence enabled along with other flags enabled. Please note that the version v1.3.1 is only satisfying FIPS 140-3 Level-1 certification requirements and not FIPS certified yet. The FIPS 140-3 certification is under process. ## Support Algorithms in FIPS mode | Mode | Algorithms | | :---: | :---: | | QAT_HW | RSA, ECDSA, ECDH, ECDHX25519, ECDHX448, DSA, DH, TLS1.2-KDF(PRF), TLS1.3-KDF(HKDF), SHA3 & AES-GCM | | QAT_SW | RSA, ECDSA, ECDH, ECDHX25519, SHA2 & AES-GCM | # Binary RPM Package QAT_Engine supports Binary Package via RPM which can be found in the Release page (Assests section) The Current Binary RPM Package is created for the distros RHEL 9.2, Ubuntu 22.04 and SUSE SLES15 SP3 with with default Kernel and other dependent packages from the system default. The RPM is generated using QAT2.0 OOT driver with QAT_SW Co-existence which means it will accelerate via QAT_HW for asymmetic PKE and QAT_SW for AES-GCM and supported only on [IntelĀ® XeonĀ® Scalable Processor family with IntelĀ® QAT Gen4/Gen4m][1] with default build configuration in QAT Engine against OpenSSL 3.0 engine and can be build using `make rpm` target. Dependent library versions used for building binary package are mentioned in Software requirements section. Example commands below to install and uninstall RPM Package ``` install: RHEL & SUSE: rpm -ivh QAT_Engine-.x86_64.rpm --target noarch Ubuntu: alien -i QAT_Engine-.x86_64.rpm --scripts uninstall RHEL & SUSE: rpm -e QAT_Engine Ubuntu: apt-get remove QAT_Engine ``` The binary RPM Package will take care of installing dependent libraries and kernel modules in the default path and OpenSSL being installed in `/usr/local/ssl` Since it is using different OpenSSL version(refer Software requirements for version) than what is present in the system. LD_LIBRARY_PATH must be set to this path below. ``` export LD_LIBRARY_PATH=/usr/local/ssl/lib64 ``` [1]:https://www.intel.com/content/www/us/en/products/docs/processors/xeon-accelerated/4th-gen-xeon-scalable-processors.html qatengine-1.9.0/docs/qat_hw.md000066400000000000000000000135751500416242000162360ustar00rootroot00000000000000# Intel® QAT OpenSSL\* Engine HKDF Support The HKDF support in the Intel® QAT OpenSSL\* Engine is available only from Version 4.8 of Intel® QuickAssist Technology Driver for Linux HW Version 1.7. By default this support is disabled as it is added as an experimental feature. It can be enabled using the flag `--enable-qat_hw_hkdf` in the configure command combined with modifying the Intel® QuickAssist Technology Driver file's config variable 'ServicesProfile' from its default value of 'DEFAULT' to 'CRYPTO'. # Using the OpenSSL\* Pipelining Capability The OpenSSL\* pipelining feature provides the capability to parallelise the processing for a single connection. For example a big buffer to be encrypted can be split into smaller chunks with each chunk encrypted simultaneously using pipelining. The Intel® QAT OpenSSL\* Engine supports OpenSSL\* pipelining capability for chained cipher encryption operations only. The engine provides a maximum of 32 pipelines (buffer chunks) with a maximum size of 16,384 bytes for each pipeline. When pipelines are used, they are always accelerated to the Hardware accelerator ignoring the small packet offload threshold. Please refer to the OpenSSL\* manual for more information about pipelining. # Intel® QAT OpenSSL\* Engine Software Fallback The Intel® QuickAssist Heartbeat feature provides a mechanism for the Intel® QAT OpenSSL\* Engine to detect unresponsive acceleration devices and to be notified of the start and end of any reset of the acceleration devices. The Heartbeat feature suspends all QAT instances associated with that acceleration device between these two reset-start and reset-end events. Application using QAT needs to have the utility/daemon that periodically checks device which is needed as part of heartbeat functionality. An acceleration device can be configured for automatic reset by the QAT framework upon heartbeat failure by using the `AutomaticResetOnError = 1` field in the `[GENERAL]` section of device configuration file `/etc/.conf`. The Intel® QAT OpenSSL\* Engine's software fallback feature requires this field to be set. The Intel® QAT OpenSSL\* Engine's software fallback feature, when enabled by the user, essentially provides continuity of crypto operations for the application between the two above-mentioned reset-start & reset-end events. It does this by exhibiting the following behavior: * Any requests that have already been submitted to the acceleration device that goes down but have not completed will be handled as on core requests and will complete. * Any new requests coming in while the acceleration device is offline will either be submitted to the other acceleration devices (if any are available) or if none are available then the request will be handled on core. * Once the acceleration device has come back online new requests will be able to use instances from that acceleration device again. This should all happen in a transparent way with the only noticeable effects being a potential slow down in performance until the acceleration device comes back online. ### Requirements: 1. This Intel® QAT OpenSSL\* Engine supports the Intel® QAT Driver Heartbeat feature on the following QAT Enabled Devices or Platforms using the driver Linux Hardware v1.7, v1.8, v2.0(qatlib intree) and FreeBSD Hardware v2.0(OOT package) * [Intel® Xeon® with Intel® C62X Series Chipset][1] * [IntelĀ® XeonĀ® Scalable Processor family with IntelĀ® QAT Gen4/Gen4m][2] [1]:https://www.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/purley/intel-xeon-scalable-processors.html [2]:https://www.intel.com/content/www/us/en/products/docs/processors/xeon-accelerated/4th-gen-xeon-scalable-processors.html 2. Asymmetric PKE, Key Derivation algorithms supported by QAT Engine/provider and Symmetric algorithms like AES-GCM, AES-CCM, CHACHAPOLY, AES-CBC chained ciphers supports software fallback on device failure. Other Hash and SMx algorithms doesnt support software Fallback. 3. Software fallback feature for symmetric algorithms are only supported in FreeBSD platform. ### Testing the Software Fallback using OpenSSL Speed application Pre-Requisites: Build QAT Driver using `./configure --enable-icp-hb-fail-sim` flag and change the driver config files `/etc/.conf` to have `AutoResetOnError = 1` as mentioned above. Driver needs to be built with same version of OpenSSL as the application, to meet OpenSSL's requirement of version compatibility between OpenSSL 1.1.1 and 3.x. Set the below envs to compile Driver against same version of OpenSSL if needed. * `setenv LDFLAGS "-L/lib"` * `setenv CPPFLAGS "-I/include"` 1. Manually set the `enable_sw_fallback = 1` in the e_qat.c otherwise this needs to be turned on with Engine Ctrl messages at runtime from the application. 2. Build QAT Engine as per the steps mentioned in the Example build in the Installation Instructions section. 3. Run OpenSSL speed application with qatengine from /bin e.g., `./openssl speed -engine qatengine -elapsed rsa2048` 4. Inject device failure using the command. `sysctl dev.qat.0.heartbeat_sim_fail=1` 5. Check device status(0 - device failure, 1 - device active). `sysctl dev.qat.0.heartbeat` 6. On successful software fallback, there will not be any errors reported from OpenSSL speed test. ### Additional Information Additional information on this Heartbeat feature can be found at the Heartbeat Section of respective QAT Hardware programmer's Guide below * [Intel QAT Software for Linux—Programmer's Guide: Hardware v1.x CE Release][3] * [Intel QAT Software for Linux—Programmer's Guide: Hardware v2.0][4] [3]:https://cdrdv2.intel.com/v1/dl/getContent/710060 [4]:https://cdrdv2.intel.com/v1/dl/getContent/743912 qatengine-1.9.0/docs/qat_hw_algo.md000066400000000000000000000037461500416242000172370ustar00rootroot00000000000000# QAT_HW Algorithms list, its supported platforms and default behaviour | QAT_HW Algorithms | v1.7 | v1.8 | v2.0 | qatlib(intree) | | :---: | :---: | :---: | :---: | :---: | | RSA Key size < 2048 | ** | ** | ** | ** | | RSA Key size >= 2048 <= 4096 | * | * | * | * | | RSA Key size 8192 | | | * | * | | ECDSA Curves with bitlen < 256 | ** | ** | ** | ** | | ECDSA Curves with bitlen >= 256 | * | * | * | * | | ECDH Curves with bitlen < 256| ** | ** | ** | ** | | ECDH Curves with bitlen >= 256 | * | * | * | * | | ECDH X25519 & X448(ECX)| * | * | * | * | | DSA | ** | ** | ** | ** | | DH key size < 8192 | ** | ** | ** | ** | | DH key size >=8192 | | | ** | ** | | HKDF | *** | *** | *** | *** | | PRF | * | * | * | * | | AES-128-GCM | ** | ** | ** | ** | | AES-256-GCM | *** | *** | *** | *** | | AES-128-CCM | ** | ** | ** | ** | | AES-192-CCM | | | ** | ** | | AES-256-CCM | | | * | * | | AES128_CBC_HMAC_SHA1 | ** | ** | ** | ** | | AES256_CBC_HMAC_SHA1 | ** | ** | ** | ** | | AES128_CBC_HMAC_SHA256 | ** | ** | ** | ** | | AES256_CBC_HMAC_SHA256 | * | * | * | * | | SHA3-224 | | ** | ** | ** | | SHA3-256/384/512 | | *** | *** | *** | | ChachaPoly | | *** | *** | *** | | SM4-CBC | | # | # | | | SM3 | | *** | *** | | | SM2 | | *** | *** | | \* Enabled in the default build of qatengine for the specified platforms when `--with-qat_hw_dir` is provided in qatengine/qatprovider build configure.
\** Insecure algorithms which are disabled by default in QAT_HW driver and qatengine/qatprovider. Can be enabled using configure flag `--enable-qat_insecure_algorithms`. Driver will also needs to be built with the flag `./configure --enable-legacy-algorithms` to enable these algorithms at driver.
\*** Algorithms disabled by default as those are experimental.
\# Disabled by default as it is specific to Tongsuo and not applicable to OpenSSL. To be enabled when qatengine is built with Tongsuo. Please refer [config_options](config_options.md) on details about algorithm enable/disable flags. qatengine-1.9.0/docs/qat_hw_kpt.md000066400000000000000000000112521500416242000171020ustar00rootroot00000000000000## Introduction Key Protection Technology (KPT) enables customers to securely deliver their networking security sensitive credentials to IA platforms. IA platforms with Intel QuickAssist (QAT) IP will deliver this capability. Once, customer keys are securely delivered to the QAT on IA platform, the customer keys are protected within the QAT IP while in transport or in use. The QAT_Engine with KPT feature can expose the KPT2.0 asymmetric capability to the other applications e.g. Nginx, OpenSSL, etc. ### Supported Algorithms * Asymmetric Cryptography: * RSA 512/1024/2048/4096/8192 * ECDSA 256r1/384r1/521r1 ## Requirements ### Hardware The Key Protection Technology(KPT) feature in the Intel® QAT OpenSSL\* Engine needs QAT acceleration devices with KPT capability on platform with Intel® Xeon® with QAT 4XXX Series Chipset. ### **Key Protection Technology Library** This library provides the key protection services for applications upon various Intel® security hardware technology, like QuickAssist Technology, etc. The Intel® QAT OpenSSL\* Engine comes with the KPT library in its subdirectory `kpt/lib`. Please refer [here](../kpt/lib/README.md) for detailed information. ## Build Instruction for enabling KPT To build and install the Intel® QAT OpenSSL\* Engine with add `--enable-qat_hw_kpt` to enable KPT configure flag to the qat_hw target build instructions as below ``` cd QAT_Engine ./autogen.sh ./configure \ --enable-qat_hw_kpt \ --with-qat_hw_dir=/{driver_package_dir} \ --with-openssl_install_dir=/{openssl_install_dir} make clean -j make -j && make install -j ``` ### KPT Tool Wrapped private key(WPK) file is a customized PEM file used by the KPT feature. Sample code of KPT Tool is provided to create or parse the standard WPK file according to WPK format definition. This tool can be built using `make kpttool` in the top directory. **NOTE**: Re-generate the WPK file while the platform is changed. * KPT Tool Usage ``` Usage of kpttool: kpttool -act [gen|par] -alg [rsa|ecc] -in [|] -out -act (action): gen (generate wpk (wrap private key)), par (parse wpk (wrap private key)) -alg (algorithm): rsa (-in rsa private key file), ecc (-in ecc private key) -in: -act gen input cpk (customer private key) file -act par input wpk (wrap private key) file -out: -act gen output wpk (wrap private key) file e.g. kpttool -act gen -alg ecc -in ec_secp256r1_private.key -out ec_secp256r1_wpk.key e.g. kpttool -act par -alg ecc -in ec_secp256r1_wpk.key e.g. kpttool -act gen -alg rsa -in rsa_2k_private.key -out rsa_2k_wpk.key e.g. kpttool -act par -alg rsa -in rsa_2k_wpk.key ``` ## Test the KPT Feature ### OpenSSL Command * RSA ``` RSA ENCRYPTION # echo 123123123123 > plain.txt # openssl rsautl --encrypt -in plain.txt -out cipher.txt -inkey rsa2k.pem RSA DECRYPTION # openssl rsautl --decrypt -in cipher.txt -out decrypt.txt -keyform engine -engine qatengine -inkey wpk_rsa2k.pem RSA SIGN # openssl dgst -sign wpk_rsa2k.pem -keyform ENGINE -engine qatengine plain.txt > digest.txt RSA VERIFY # openssl dgst -verify rsa2k_pub.pem -signature digest.txt verify.txt ``` * ECDSA ``` ECDSA SIGN # openssl dgst -sign wpk_secp521r1.pem -keyform ENGINE -engine qatengine plain.txt > digest.txt ECDSA VERIFY # openssl dgst -verify secp521r1_pub.pem -signature digest.txt verify.txt ``` ### Nginx In Nginx use case, `engine:qat_engine` needs to be prefixed before the WPK file path for `ssl_certification_key`, which will tell Nginx to load the WPK file using the QAT Engine instead of the original function. For example: ``` server{ ssl_certificate cert.crt; ssl_certificate_key engine:qatengine:wpk_file.pem; } ``` ## Known Issues & Limitation 1. The worker-instance model is not aligned with previous usage. Since the KPT needs to get the instance in master node to load the WPK file, the maximum worker number will change from 64 to 63 while each worker being assigned 1 instance. If 64 workers are used, `nginx -s xxx` will fail and need to kill all nginx processes forcedly. 2. Non-shared mode is implemented by default, and shared mode is not supported yet. 3. SWK provision number limitation for each device is 128, otherwise, the QAT Driver will return with error code -3 (CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED). It means that: `num_instance * num_server_block(use WPK file) <= 128`. * If 64 workers are used, the maximum number of server block that uses the WPK file is 2. * In case only 1 server block used the WPK file, the maximum number of worker is 128. 4. Directive sw_fallback will not be supported while KPT capability is enabled. qatengine-1.9.0/docs/qat_sw.md000066400000000000000000000026561500416242000162470ustar00rootroot00000000000000## Intel® QAT Software Acceleration This Intel® QAT OpenSSL\* Engine supports Multi-buffer based software acceleration for asymmetric PKE algorithms RSA, ECDH X25519, ECDH P-256/P-384 and ECDSA P-256/P-384, SM2, SM3, SM4-CBC, SM4-GCM, SM4-CCM using the Intel® Crypto Multi-buffer library based on Intel® AVX-512 Integer Fused Multiply Add (IFMA) operations. This Support, when enabled by the user using the [build instructions](install.md#build-qat-engine-for-qat_sw) for qat_sw target performs operation by batching up multiple requests maintained in queues and uses the OpenSSL asynchronous infrastructure to submit the batched requests up to 8 to Crypto Multi-buffer API which processes them in parallel using AVX512 vector instructions. QAT SW Multi-buffer acceleration will be beneficial to use only in asynchronous mode where there are many parallel connections to fully utilize multibuffer operation. Software based acceleration for AES-GCM is supported via the Intel® Multi-Buffer Crypto for IPsec Library. The implementation at engine for AES-GCM follows synchronous mechanism to submit requests to the IPSec_MB library which processes requests in multiple blocks using vectorized AES,AVX2 and AVX512 instructions from the processor. Software acceleration features are only supported in the system that supports IntelĀ® AVX-512 with the following instruction set extensions: ` AVX512F AVX512_IFMA VAES VPCLMULQDQ AVX2 ` qatengine-1.9.0/docs/software_requirements.md000066400000000000000000000045761500416242000214110ustar00rootroot00000000000000# Software Requirements Successful operation of QAT Hardware(QAT_HW) acceleration requires a [QAT Hardware driver][1] depending on the platform and OS mentioned below. QAT Software(QAT_SW) acceleration requires optimized software libraries [IntelĀ® Crypto Multi-buffer library][2] and [intel-ipsec-mb][3]. Depending on the use case crypto library like OpenSSL, TongSuo(BabaSSL) and BoringSSL needs to be installed along with a QAT_HW driver or QAT_SW libraries or both. This release was validated on the following versions and expected to work on all Linux distributions and also from the latest versions from the links below. ## QAT_HW Drivers: * [IntelĀ® QuickAssist Technology Driver for Linux\* HW Version 2.0][4] - **QAT20.L.1.2.30-00078** * [IntelĀ® QuickAssist Technology Driver for Linux\* HW Version 1.x][5] - **QAT.L.4.27.0-00006** * IntelĀ® QuickAssist Technology Driver for FreeBSD\* HW Version 1.x and 2.0 - **QAT.B.3.14.31-00003** (FreeBSD 13.2) * [IntelĀ® QATlib for Linux with intree driver][7] - **QATlib 24.09.0** & **QATlib 24.02.0** (for Dockerfile only) * [IntelĀ® QATlib for FreeBSD with intree driver(FreeBSD 14)][8] - **FreeBSD QATlib 23.09.0** (FreeBSD 14) ## QAT_SW Libraries: * [Intel® Crypto Multi-buffer library][2] - **IPP Crypto v1.1.0** & **IPP Crypto 2021.10** (for BoringSSL only) * [Intel® Multi-Buffer crypto for IPsec Library release version][3] **v2.0** ## Crypto Libraries: * [OpenSSL\*][9] 3.0.16, 3.2.4, 3.3.3 & 3.4.1 * BoringSSL\* commit - [23ed9d3][10] * [Tongsuo][11] - 8.4.0 (BabaSSL) [1]:https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html [2]:https://github.com/intel/cryptography-primitives/tree/develop/sources/ippcp/crypto_mb [3]:https://github.com/intel/intel-ipsec-mb [4]:https://www.intel.com/content/www/us/en/download/765501/intel-quickassist-technology-driver-for-linux-hw-version-2-0.html [5]:https://www.intel.com/content/www/us/en/download/19734/intel-quickassist-technology-driver-for-linux-hw-version-1-x.html [6]:https://www.intel.com/content/www/us/en/download/19735/intel-quickassist-technology-driver-for-freebsd-hw-version-1-x.html [7]:https://github.com/intel/qatlib [8]:https://github.com/intel/qatlib-freebsd [9]:https://github.com/openssl/openssl [10]:https://github.com/google/boringssl/commit/23ed9d3852bbc738bebeaa0fe4a0782f91d7873c [11]:https://github.com/Tongsuo-Project/Tongsuo qatengine-1.9.0/docs/troubleshooting.md000066400000000000000000000066721500416242000202020ustar00rootroot00000000000000# Troubleshooting The most likely failure point is that the Intel® QAT OpenSSL\* Engine is not loading successfully. If this occurs some of the things to check are: * Enabling debug settings with QAT_Engine is valuable tool when debugging issues with QAT_Engine using `--enable-qat_debug`. The debug messages would be logged in the console(Eg: OpenSSL Speed) or to a file depending on the application(Eg: Nginx would be on `path_to_nginx_install/logs/error.log`). If you prefer to write to a file use Eg:`--with-qat_debug_file=/opt/engine.log`. * When using qat_hw OOT driver package, Has the correct driver config file from `qat_hw_config` been copied to `/etc`? Check it has a `[SHIM]` section and that the Intel® QAT Driver was restarted so that it picked up the new config file. Otherwise below error would be reported during the test. ```bash ADF_UIO_PROXY err: icp_adf_userProcessToStart: Error reading /dev/qat_dev_processes file QAT HW initialization Failed. ``` * In case of qat_hw OOT driver, has the driver config file(`/etc/qatdev_id/conf`) is configured with enough number of process in the setting `NumProcesses = ` where n is the number of process your application would be using. Otherwise the below error would be reported for the process that is not getting qat_hw instance. If QAT_SW is enabled, the process would be using qat_sw as a fallback mechanism. ```bash icp sal userstart fail:qat_hw_init.c ``` * In case of qat_hw qatlib intree driver, refer [install](https://github.com/intel/qatlib/blob/main/INSTALL) page for the policy settings to configure the Numprocess and service required as per the use case for better performance. * Is the Intel® QAT Driver up and running for qat_hw? Check by running `adf_ctl`, device details along with the state should be `state: up`. Also check the Intel® QAT Driver software has been started. * Were the paths set correctly so that the `qatengine.so` for engine and `qatprovider.so` for provider was copied to the correct location? Check they really are there. * Has the environment variable `OPENSSL_ENGINES` been correctly defined and exported to the shell? Also check it is really pointing to the correct location. * If building from OpenSSL prebuilt RPM Package, has the OpenSSL development packages (openssl-devel for Redhat\* based distribution and libssl-devel for Debian\* based distribution) been installed ? * In case of qat_sw acceleration, has the dependent libraries are installed in the default path or provide the path via `--with-qat_sw_crypto_mb_install_dir` (for crypto_mb) and `--with-qat_sw_ipsec_mb_install_dir` (for ipsec_mb) if installed in the path other than default. * On certain systems, it might be possible that `qatengine.so` or `qatprovider.so` is not able to locate `libcrypto.so` & `libssl.so` if built from OpenSSL\* source. It is recommended to add the OpenSSL\* install dir to LD_LIBRARY_PATH as per th example below ```bash export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/ssl/lib64 ``` * If seeing failures with USDM memory allocation, either with non-root or root user check memlock limit with `ulimit -l` and increase the memlock limit to desired value if it is low. * Algorithms like DH, DSA, SHA1, RSA keysizes < 2048, EC curves < 256 bits are considered insecure and disabled by default at QAT_HW driver and QAT Engine. If you prefer to use these algorithms, Rebuild QAT_HW using `--enable-legacy-algorithms` and QAT Engine using `--enable-qat_insecure_algorithms` configure option. qatengine-1.9.0/driver_install.sh000077500000000000000000000052431500416242000170520ustar00rootroot00000000000000#!/bin/sh #QAT_HW OOT driver Location QAT17_DRIVER=https://downloadmirror.intel.com/838409/QAT.L.4.27.0-00006.tar.gz QAT20_DRIVER=https://downloadmirror.intel.com/843052/QAT20.L.1.2.30-00078.tar.gz #Supported Devices numC62xDevice=`lspci -vnd 8086: | grep -c "37c8\|37c9"` numDh895xDevice=`lspci -vnd 8086: | grep -c "0435\|0443"` numC3xxxDevice=`lspci -vnd 8086: | grep -c "19e2\|19e3"` num200xxDevice=`lspci -vnd 8086: | grep -c "18ee\|18ef"` numC4xxxDevice=`lspci -vnd 8086: | grep -c "18a0\|18a1"` num4xxxDevice=`lspci -vnd 8086: | grep -c "4940\|4942"` QAT_ENGINE_ROOT=$PWD #Install QAT_HW OOT Driver and copy config files if [ "$numC62xDevice" -gt 0 -o "$numDh895xDevice" -gt 0 -o "$numC3xxxDevice" -gt 0 -o "$numC4xxxDevice" -gt 0 -o "$num200xxDevice" -gt 0 -o "$num4xxxDevice" -gt 0 ] then if [ "$num4xxxDevice" -gt 0 ] then echo "QAT2.0 Driver" wget -O QAT_HW.tar.gz $QAT20_DRIVER else echo "QAT1.7 Driver" wget -O QAT_HW.tar.gz $QAT17_DRIVER fi mkdir -p $1 tar -zxvf QAT_HW.tar.gz -C $1 unset ICP_ROOT unset ICP_BUILD_OUTPUT cd $1 ./configure make uninstall; make clean; make install -j if [ "$numC62xDevice" -gt 0 ] then for(( i=0; i<$numC62xDevice; i++ )) do sudo cp -rf $QAT_ENGINE_ROOT/qat_hw_config/c6xx/multi_process/c6xx_dev0.conf /etc/c6xx_dev$i.conf done elif [ "$numDh895xDevice" -gt 0 ] then for(( i=0; i<"$numDh895xDevice"; i++ )) do sudo cp -rf $QAT_ENGINE_ROOT/qat_hw_config/dh895xcc/multi_process/dh895xcc_dev0.conf /etc/dh895xcc_dev$i.conf done elif [ "$numC3xxxDevice" -gt 0 ] then for(( i=0; i<"$numC3xxxDevice"; i++ )) do sudo cp -rf $QAT_ENGINE_ROOT/qat_hw_config/c3xxx/multi_process/c3xxx_dev0.conf /etc/c3xxx_dev$i.conf done elif [ "$numC4xxxDevice" -gt 0 ] then for(( i=0; i<"$numC4xxxDevice"; i++ )) do sudo cp -rf $QAT_ENGINE_ROOT/qat_hw_config/c4xxx/multi_process/c4xxx_dev0.conf /etc/c4xxx_dev$i.conf done elif [ "$num200xxDevice" -gt 0 ] then for(( i=0; i<"$num200xxDevice"; i++ )) do sudo cp -rf $QAT_ENGINE_ROOT/qat_hw_config/200xx/multi_process/200xx_dev0.conf /etc/200xx_dev$i.conf done elif [ "$num4xxxDevice" -gt 0 ] then for(( i=0; i<$num4xxxDevice; i++ )) do sudo cp -rf $QAT_ENGINE_ROOT/qat_hw_config/4xxx/multi_process/4xxx_dev0.conf /etc/4xxx_dev$i.conf done fi adf_ctl restart echo "QAT_HW Driver installed successfully!" else echo "QAT_HW Device not supported to install from make depend ! Install driver manually" fi qatengine-1.9.0/e_qat.c000066400000000000000000001375151500416242000147370ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file e_qat.c * * This file provides a OpenSSL engine for the quick assist API * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Defines */ #ifdef QAT_HW # ifdef QAT_HW_INTREE # ifndef ENABLE_QAT_HW_SHA3 # define ENABLE_QAT_HW_SHA3 # endif # ifndef ENABLE_QAT_HW_CHACHAPOLY # define ENABLE_QAT_HW_CHACHAPOLY # endif # endif #endif /* Standard Includes */ #include #include #include #include #include #include #include #ifndef __FreeBSD__ # include # include # include #endif #include #include #include /* Local Includes */ #include "e_qat.h" #include "qat_fork.h" #include "qat_evp.h" #include "qat_utils.h" #ifdef QAT_HW #ifndef QAT_BORINGSSL # include "qat_hw_ciphers.h" #endif /* QAT_BORINGSSL */ # include "qat_hw_polling.h" # include "qat_hw_rsa.h" #ifndef QAT_BORINGSSL # include "qat_hw_dsa.h" # include "qat_hw_dh.h" # include "qat_hw_gcm.h" # include "qat_hw_ccm.h" #endif /* QAT_BORINGSSL */ /* QAT includes */ # include "cpa.h" # include "cpa_cy_im.h" # include "cpa_cy_common.h" # include "cpa_types.h" # include "icp_sal_user.h" # include "icp_sal_poll.h" #endif #ifdef QAT_SW # include "qat_sw_rsa.h" # include "qat_sw_ecx.h" # include "qat_sw_ec.h" # include "qat_sw_polling.h" # include "crypto_mb/cpu_features.h" # ifdef ENABLE_QAT_SW_SM4_GCM # include "crypto_mb/sm4_gcm.h" # endif # ifdef ENABLE_QAT_SW_SM4_CCM # include "crypto_mb/sm4_ccm.h" # endif #endif #ifdef ENABLE_QAT_SW_GCM #ifndef QAT_BORINGSSL # include "qat_sw_gcm.h" #endif /* QAT_BORINGSSL */ #endif #ifdef QAT_SW_IPSEC # if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) # include "qat_sw_sha2.h" # endif #endif /* OpenSSL Includes */ #include #include #include #if defined(QAT_SW) || defined(QAT_SW_IPSEC) /* __cpuid(unsigned int info[4], unsigned int leaf, unsigned int subleaf); */ # define __cpuid(x, y, z) \ asm volatile("cpuid" : "=a"(x[0]), "=b"(x[1]), "=c"(x[2]), "=d"(x[3]) : "a"(y), "c"(z)) # define Genu 0x756e6547 # define ineI 0x49656e69 # define ntel 0x6c65746e # define VAES_BIT 9 # define VPCLMULQDQ_BIT 10 # define AVX512F_BIT 16 # define AVX2_BIT 5 #endif #define QAT_MAX_INPUT_STRING_LENGTH 1024 #ifndef QAT_ENGINE_ID # define QAT_ENGINE_ID qatengine #endif #ifdef ENABLE_QAT_FIPS int qat_fips_key_zeroize; int qat_fips_kat_test; #endif /* Qat engine id declaration */ const char *engine_qat_id = STR(QAT_ENGINE_ID); #if defined(QAT_HW) && defined(QAT_SW) const char *engine_qat_name = "Reference implementation of QAT crypto engine(qat_hw & qat_sw) v1.9.0"; #elif QAT_HW const char *engine_qat_name = "Reference implementation of QAT crypto engine(qat_hw) v1.9.0"; #else const char *engine_qat_name = "Reference implementation of QAT crypto engine(qat_sw) v1.9.0"; #endif unsigned int engine_inited = 0; int fallback_to_openssl = 0; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int qat_openssl3_prf_fallback = 0; int qat_openssl3_hkdf_fallback = 0; int qat_openssl3_sha_fallback = 0; #endif int qat_openssl3_sm2_fallback = 0; int qat_openssl3_sm3_fallback = 0; int fallback_to_qat_sw = 0; /* QAT HW initialize fail, offload to QAT SW. */ int qat_hw_offload = 0; int qat_sw_offload = 0; int qat_hw_rsa_offload = 0; int qat_hw_ecx_offload = 0; int qat_hw_ecdh_offload = 0; int qat_hw_ecdsa_offload = 0; int qat_hw_prf_offload = 0; int qat_hw_hkdf_offload = 0; int qat_hw_gcm_offload = 0; int qat_sw_rsa_offload = 0; int qat_sw_ecx_offload = 0; int qat_sw_ecdh_offload = 0; int qat_sw_ecdsa_offload = 0; int qat_sw_gcm_offload = 0; int qat_hw_chacha_poly_offload = 0; int qat_hw_aes_cbc_hmac_sha_offload = 0; int qat_hw_sm4_cbc_offload = 0; int qat_sw_sm2_offload = 0; int qat_hw_sm2_offload = 0; int qat_hw_sha_offload = 0; int qat_hw_sm3_offload = 0; # ifdef ENABLE_QAT_FIPS int qat_sw_sha_offload = 0; # endif # ifdef QAT_OPENSSL_PROVIDER int qat_hw_dsa_offload = 0; int qat_hw_dh_offload = 0; int qat_hw_ecx_448_offload = 0; # endif int qat_sw_sm3_offload = 0; int qat_sw_sm4_cbc_offload = 0; int qat_sw_sm4_gcm_offload = 0; int qat_sw_sm4_ccm_offload = 0; int qat_hw_aes_ccm_offload = 0; int qat_hw_keep_polling = 1; int qat_sw_keep_polling = 1; int enable_external_polling = 0; int enable_heuristic_polling = 0; pthread_mutex_t qat_engine_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_t qat_polling_thread; sem_t hw_polling_thread_sem; /* QAT number of in-flight requests */ int num_requests_in_flight = 0; int num_asym_requests_in_flight = 0; int num_kdf_requests_in_flight = 0; int num_cipher_pipeline_requests_in_flight = 0; /* Multi-buffer number of items in queue */ int num_asym_mb_items_in_queue = 0; int num_kdf_mb_items_in_queue = 0; int num_cipher_mb_items_in_queue = 0; sigset_t set = {{0}}; pthread_t qat_timer_poll_func_thread = 0; int cleared_to_start = 0; pthread_mutex_t qat_poll_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t qat_poll_condition = PTHREAD_COND_INITIALIZER; int qat_cond_wait_started = 0; #ifdef QAT_HW # define QAT_CONFIG_SECTION_NAME_SIZE 64 # if defined(QAT_HW_FBSD_INTREE) char qat_config_section_name[QAT_CONFIG_SECTION_NAME_SIZE] = "SSL"; # else char qat_config_section_name[QAT_CONFIG_SECTION_NAME_SIZE] = "SHIM"; # endif char *ICPConfigSectionName_libcrypto = qat_config_section_name; int enable_inline_polling = 0; int enable_event_driven_polling = 0; int enable_instance_for_thread = 0; int disable_qat_offload = 0; /* By default Software fallback disabled in QAT FIPs mode. * Always enable_sw_fallback is zero in QAT FIPs mode. */ int enable_sw_fallback = 0; CpaInstanceHandle *qat_instance_handles = NULL; Cpa16U qat_num_instances = 0; Cpa16U qat_asym_num_instance = 0; Cpa16U qat_sym_num_instance = 0; Cpa16U qat_svm_num_instance = 0; Cpa16U qat_contig_num_instance = 0; Cpa32U qat_num_devices = 0; pthread_key_t thread_local_variables; pthread_mutex_t qat_instance_mutex = PTHREAD_MUTEX_INITIALIZER; qat_instance_details_t qat_instance_details[QAT_MAX_CRYPTO_INSTANCES] = {{{0}}}; qat_accel_details_t qat_accel_details[QAT_MAX_CRYPTO_ACCELERATORS] = {{0}}; useconds_t qat_poll_interval = QAT_POLL_PERIOD_IN_NS; int qat_epoll_timeout = QAT_EPOLL_TIMEOUT_IN_MS; int qat_max_retry_count = QAT_CRYPTO_NUM_POLLING_RETRIES; unsigned int qat_map_sym_inst[QAT_MAX_CRYPTO_INSTANCES] = {'\0'}; unsigned int qat_map_asym_inst[QAT_MAX_CRYPTO_INSTANCES] = {'\0'}; unsigned int qat_map_svm_inst[QAT_MAX_CRYPTO_INSTANCES] = {'\0'}; #endif #ifdef QAT_SW /* RSA */ BIGNUM *e_check = NULL; mb_thread_data *mb_tlv = NULL; pthread_key_t mb_thread_key; #endif #ifdef QAT_HW uint64_t qat_hw_algo_enable_mask = 0xFFFFF; #else uint64_t qat_hw_algo_enable_mask = 0; #endif #if defined(QAT_SW) || defined(QAT_SW_IPSEC) uint64_t qat_sw_algo_enable_mask = 0xFFFFF; #else uint64_t qat_sw_algo_enable_mask = 0; #endif /* Algorithm reload needs to free the previous method and reallocate it to exclude the impact of different offload modes, like QAT_HW -> QAT_SW. Use this flag to distinguish it from the other cases. */ int qat_reload_algo = 0; /* For QAT_HW & QAT_SW co-existence submission. */ int qat_rsa_coexist = 0; int qat_ecdh_coexist = 0; int qat_ecdsa_coexist = 0; int qat_ecx_coexist = 0; int qat_sm4_cbc_coexist = 0; __thread unsigned int qat_sw_rsa_priv_req = 0; __thread unsigned int qat_sw_rsa_pub_req = 0; __thread unsigned int qat_sw_ecdsa_sign_req = 0; __thread unsigned int qat_sw_ecdh_keygen_req = 0; __thread unsigned int qat_sw_ecdh_derive_req = 0; __thread unsigned int qat_sw_ecx_keygen_req = 0; __thread unsigned int qat_sw_ecx_derive_req = 0; __thread unsigned int qat_sw_sm4_cbc_cipher_req; __thread int num_rsa_priv_retry = 0; __thread int num_rsa_pub_retry = 0; __thread int num_ecdsa_sign_retry = 0; __thread int num_ecdh_keygen_retry = 0; __thread int num_ecdh_derive_retry = 0; __thread int num_ecx_keygen_retry = 0; __thread int num_ecx_derive_retry = 0; __thread int num_sm4_cbc_cipher_retry = 0; __thread unsigned long long num_rsa_hw_priv_reqs = 0; __thread unsigned long long num_rsa_sw_priv_reqs = 0; __thread unsigned long long num_rsa_hw_pub_reqs = 0; __thread unsigned long long num_rsa_sw_pub_reqs = 0; __thread unsigned long long num_ecdsa_hw_sign_reqs = 0; __thread unsigned long long num_ecdsa_sw_sign_reqs = 0; __thread unsigned long long num_ecdh_hw_keygen_reqs = 0; __thread unsigned long long num_ecdh_sw_keygen_reqs = 0; __thread unsigned long long num_ecdh_hw_derive_reqs = 0; __thread unsigned long long num_ecdh_sw_derive_reqs = 0; __thread unsigned long long num_ecx_hw_keygen_reqs = 0; __thread unsigned long long num_ecx_sw_keygen_reqs = 0; __thread unsigned long long num_ecx_hw_derive_reqs = 0; __thread unsigned long long num_ecx_sw_derive_reqs = 0; __thread unsigned long long num_sm4_cbc_hw_cipher_reqs = 0; __thread unsigned long long num_sm4_cbc_sw_cipher_reqs = 0; #ifndef __FreeBSD__ clock_t clock_id = CLOCK_MONOTONIC_RAW; #else clock_t clock_id = CLOCK_MONOTONIC_PRECISE; #endif #if ! defined(QAT_BORINGSSL) && ! defined(QAT_OPENSSL_PROVIDER) const ENGINE_CMD_DEFN qat_cmd_defns[] = { { QAT_CMD_ENABLE_EXTERNAL_POLLING, "ENABLE_EXTERNAL_POLLING", "Enables the external polling interface to the engine.", ENGINE_CMD_FLAG_NO_INPUT}, { QAT_CMD_POLL, "POLL", "Polls the engine for any completed requests", ENGINE_CMD_FLAG_NO_INPUT}, #ifdef QAT_HW { QAT_CMD_SET_INSTANCE_FOR_THREAD, "SET_INSTANCE_FOR_THREAD", "Set instance to be used by this thread", ENGINE_CMD_FLAG_NUMERIC}, { QAT_CMD_GET_NUM_OP_RETRIES, "GET_NUM_OP_RETRIES", "Get number of retries", ENGINE_CMD_FLAG_NO_INPUT}, { QAT_CMD_SET_MAX_RETRY_COUNT, "SET_MAX_RETRY_COUNT", "Set maximum retry count", ENGINE_CMD_FLAG_NUMERIC}, { QAT_CMD_SET_INTERNAL_POLL_INTERVAL, "SET_INTERNAL_POLL_INTERVAL", "Set internal polling interval", ENGINE_CMD_FLAG_NUMERIC}, # ifndef __FreeBSD__ { QAT_CMD_GET_EXTERNAL_POLLING_FD, "GET_EXTERNAL_POLLING_FD", "Returns non blocking fd for crypto engine", ENGINE_CMD_FLAG_NO_INPUT}, { QAT_CMD_ENABLE_EVENT_DRIVEN_POLLING_MODE, "ENABLE_EVENT_DRIVEN_POLLING_MODE", "Set event driven polling mode", ENGINE_CMD_FLAG_NO_INPUT}, # endif { QAT_CMD_GET_NUM_CRYPTO_INSTANCES, "GET_NUM_CRYPTO_INSTANCES", "Get the number of crypto instances", ENGINE_CMD_FLAG_NO_INPUT}, # ifndef __FreeBSD__ { QAT_CMD_DISABLE_EVENT_DRIVEN_POLLING_MODE, "DISABLE_EVENT_DRIVEN_POLLING_MODE", "Unset event driven polling mode", ENGINE_CMD_FLAG_NO_INPUT}, # endif { QAT_CMD_SET_EPOLL_TIMEOUT, "SET_EPOLL_TIMEOUT", "Set epoll_wait timeout", ENGINE_CMD_FLAG_NUMERIC}, { QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD, "SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD", "Set QAT small packet threshold", ENGINE_CMD_FLAG_STRING}, { QAT_CMD_ENABLE_INLINE_POLLING, "ENABLE_INLINE_POLLING", "Enables the inline polling mode.", ENGINE_CMD_FLAG_NO_INPUT}, #endif { QAT_CMD_ENABLE_HEURISTIC_POLLING, "ENABLE_HEURISTIC_POLLING", "Enable the heuristic polling mode", ENGINE_CMD_FLAG_NO_INPUT}, { QAT_CMD_GET_NUM_REQUESTS_IN_FLIGHT, "GET_NUM_REQUESTS_IN_FLIGHT", "Get the number of in-flight requests", ENGINE_CMD_FLAG_NUMERIC}, { QAT_CMD_INIT_ENGINE, "INIT_ENGINE", "Initializes the engine if not already initialized", ENGINE_CMD_FLAG_NO_INPUT}, #ifdef QAT_HW { QAT_CMD_SET_CONFIGURATION_SECTION_NAME, "SET_CONFIGURATION_SECTION_NAME", "Set the configuration section to use in QAT driver configuration file", ENGINE_CMD_FLAG_STRING}, { QAT_CMD_ENABLE_SW_FALLBACK, "ENABLE_SW_FALLBACK", "Enables the fallback to SW if the acceleration devices go offline", ENGINE_CMD_FLAG_NO_INPUT}, { QAT_CMD_HEARTBEAT_POLL, "HEARTBEAT_POLL", "Check the acceleration devices are still functioning", ENGINE_CMD_FLAG_NO_INPUT}, { QAT_CMD_DISABLE_QAT_OFFLOAD, "DISABLE_QAT_OFFLOAD", "Perform crypto operations on core", ENGINE_CMD_FLAG_NO_INPUT}, #endif #ifdef QAT_HW { QAT_CMD_HW_ALGO_BITMAP, "HW_ALGO_BITMAP", "Set the HW algorithm bitmap and reload the algorithm registration", ENGINE_CMD_FLAG_STRING }, #endif #ifdef QAT_SW { QAT_CMD_SW_ALGO_BITMAP, "SW_ALGO_BITMAP", "Set the SW algorithm bitmap and reload the algorithm registration", ENGINE_CMD_FLAG_STRING }, #endif {0, NULL, NULL, 0} }; #endif /* QAT_BORINGSSL */ /****************************************************************************** * function: * qat_engine_destroy(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * Qat engine destroy function, required by Openssl engine API. * Cleanup all the method structures here. * ******************************************************************************/ #if !defined(QAT_OPENSSL_PROVIDER) static int qat_engine_destroy(ENGINE *e) { DEBUG("---- Destroying Engine...\n\n"); # ifdef QAT_HW # ifndef QAT_BORINGSSL qat_free_DH_methods(); qat_free_DSA_methods(); # endif /* QAT_BORINGSSL */ # endif # if defined(QAT_SW) || defined(QAT_HW) qat_free_EC_methods(); qat_free_RSA_methods(); # ifndef QAT_BORINGSSL qat_free_digest_meth(); qat_free_ciphers(); # endif /* QAT_BORINGSSL */ # endif # ifdef ENABLE_QAT_SW_GCM vaesgcm_free_ipsec_mb_mgr(); # endif qat_hw_ecx_offload = 0; qat_ecx_coexist = 0; qat_hw_prf_offload = 0; qat_hw_hkdf_offload = 0; qat_sw_ecx_offload = 0; qat_sw_sm2_offload = 0; qat_hw_sm2_offload = 0; qat_sw_sm3_offload = 0; qat_sw_sm4_cbc_offload = 0; qat_sw_sm4_gcm_offload = 0; qat_sw_sm4_ccm_offload = 0; qat_hw_sm3_offload = 0; QAT_DEBUG_LOG_CLOSE(); ERR_unload_QAT_strings(); return 1; } #endif #if defined(QAT_SW) || defined(QAT_SW_IPSEC) int qat_sw_cpu_support(void) { unsigned int info[4] = {0, 0, 0, 0}; unsigned int *ebx, *ecx, *edx; ebx = &info[1]; ecx = &info[2]; edx = &info[3]; /* Is this an Intel CPU? */ __cpuid(info, 0x00, 0); if (*ebx != Genu || *ecx != ntel || *edx != ineI) return 0; __cpuid(info, 0x07, 0); unsigned int avx512f = 0; unsigned int avx2 = 0; unsigned int vaes = 0; unsigned int vpclmulqdq = 0; if (*ebx & (0x1 << AVX512F_BIT)) avx512f = 1; if (*ecx & (0x1 << VAES_BIT)) vaes = 1; if (*ecx & (0x1 << VPCLMULQDQ_BIT)) vpclmulqdq = 1; if (*ebx & (0x1 << AVX2_BIT)) avx2 = 1; if ((avx512f || avx2) && vaes && vpclmulqdq) { DEBUG("QAT_SW - Processor supported: AVX512F = %u, AVX2 = %u, VAES = %u, VPCLMULQDQ = %u\n", avx512f, avx2, vaes, vpclmulqdq); return 1; } else { fprintf(stderr, "\nQAT_SW - Processor unsupported: AVX512F = %u, AVX2 = %u, VAES = %u, VPCLMULQDQ = %u\n", avx512f, avx2, vaes, vpclmulqdq); return 0; } } #endif int qat_pthread_mutex_lock(void) { int ret = 0; ret = pthread_mutex_lock(&qat_engine_mutex); if (ret != 0) { WARN("pthread mutex lock failure\n"); } return ret; } int qat_pthread_mutex_unlock(void) { int ret = 0; ret = pthread_mutex_unlock(&qat_engine_mutex); if (ret != 0) { WARN("pthread mutex unlock failure\n"); } return ret; } int qat_engine_init(ENGINE *e) { qat_pthread_mutex_lock(); if (engine_inited) { qat_pthread_mutex_unlock(); return 1; } CRYPTO_INIT_QAT_LOG(); DEBUG("QAT Engine initialization:\n"); #ifdef QAT_HW if (qat_hw_offload) { if (!qat_hw_init(e)) { # ifdef ENABLE_QAT_FIPS fprintf(stderr, "QAT_HW initialization Failed\n"); qat_pthread_mutex_unlock(); return 0; # else # ifdef QAT_SW /* Co-Existence mode: Don't return failure when QAT HW initialization Failed. */ fallback_to_qat_sw = 1; WARN("QAT HW initialization Failed, switching to QAT SW.\n"); # else fprintf(stderr, "QAT HW initialization Failed.\n"); qat_pthread_mutex_unlock(); return 0; # endif # endif } } #endif #ifdef QAT_SW if (qat_sw_offload) { if (!qat_sw_init(e)) { # ifdef ENABLE_QAT_FIPS fprintf(stderr, "QAT_SW initialization Failed\n"); qat_pthread_mutex_unlock(); return 0; # else WARN("QAT SW initialization Failed, switching to OpenSSL.\n"); fallback_to_openssl = 1; # endif } } #endif engine_inited = 1; qat_pthread_mutex_unlock(); return 1; } int qat_engine_finish_int(ENGINE *e, int reset_globals) { int ret = 1; DEBUG("---- QAT Engine Finishing...\n\n"); DEBUG("RSA Priv retries: %d, HW requests: %lld, SW requests: %lld\n", num_rsa_priv_retry, num_rsa_hw_priv_reqs, num_rsa_sw_priv_reqs); DEBUG("RSA Pub retries: %d, HW requests: %lld, SW requests: %lld\n", num_rsa_pub_retry, num_rsa_hw_pub_reqs, num_rsa_sw_pub_reqs); DEBUG("ECDH keygen retries: %d, HW requests: %lld, SW requests: %lld\n", num_ecdh_keygen_retry, num_ecdh_hw_keygen_reqs, num_ecdh_sw_keygen_reqs); DEBUG("ECDH derive retries: %d, HW requests: %lld, SW requests: %lld\n", num_ecdh_derive_retry, num_ecdh_hw_derive_reqs, num_ecdh_sw_derive_reqs); DEBUG("ECX keygen retries: %d, HW requests: %lld, SW requests: %lld\n", num_ecx_keygen_retry, num_ecx_hw_keygen_reqs, num_ecx_sw_keygen_reqs); DEBUG("ECX derive retries: %d, HW requests: %lld, SW requests: %lld\n", num_ecx_derive_retry, num_ecx_hw_derive_reqs, num_ecx_sw_derive_reqs); DEBUG("ECDSA sign retries: %d, HW requests: %lld, SW requests: %lld\n", num_ecdsa_sign_retry, num_ecdsa_hw_sign_reqs, num_ecdsa_sw_sign_reqs); DEBUG("SM4-CBC retries: %d, HW requests: %lld, SW requests: %lld\n", num_sm4_cbc_cipher_retry, num_sm4_cbc_hw_cipher_reqs, num_sm4_cbc_sw_cipher_reqs); qat_pthread_mutex_lock(); #ifdef QAT_HW if (qat_hw_offload) ret = qat_hw_finish_int(e, reset_globals); #endif #ifdef QAT_SW if (qat_sw_offload) ret = qat_sw_finish_int(e, reset_globals); #endif engine_inited = 0; if (reset_globals == QAT_RESET_GLOBALS) { enable_external_polling = 0; enable_heuristic_polling = 0; qat_hw_offload = 0; qat_sw_offload = 0; fallback_to_openssl = 0; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) qat_openssl3_prf_fallback = 0; qat_openssl3_hkdf_fallback = 0; qat_openssl3_sm2_fallback = 0; qat_openssl3_sm3_fallback = 0; qat_openssl3_sha_fallback = 0; #endif fallback_to_qat_sw = 0; } qat_pthread_mutex_unlock(); CRYPTO_CLOSE_QAT_LOG(); return ret; } /****************************************************************************** * * function: * qat_engine_finish(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * Qat engine finish function with standard signature. * This is a wrapper for qat_engine_finish_int that always resets all the * global variables used to store the engine configuration. ******************************************************************************/ int qat_engine_finish(ENGINE *e) { return qat_engine_finish_int(e, QAT_RESET_GLOBALS); } /****************************************************************************** * function: * qat_engine_ctrl(ENGINE *e, int cmd, long i, * void *p, void (*f)(void)) * * @param e [IN] - OpenSSL engine pointer * @param cmd [IN] - Control Command * @param i [IN] - Unused * @param p [IN] - Parameters for the command * @param f [IN] - Callback function * * description: * Qat engine control functions. * Note: QAT_CMD_ENABLE_EXTERNAL_POLLING should be called at the following * point during startup: * ENGINE_load_qat * ENGINE_by_id * ---> ENGINE_ctrl_cmd(QAT_CMD_ENABLE_EXTERNAL_POLLING) * ENGINE_init ******************************************************************************/ #ifndef QAT_OPENSSL_PROVIDER int qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) { unsigned int retVal = 1; char *temp = NULL; uint64_t val = 0; #ifdef QAT_HW # ifndef __FreeBSD__ CpaStatus status = CPA_STATUS_SUCCESS; int flags = 0; int fd = 0; int fcntl_ret = -1; # endif #endif switch (cmd) { case QAT_CMD_POLL: BREAK_IF(!engine_inited, "POLL failed as engine is not initialized\n"); BREAK_IF(!enable_external_polling, "POLL failed as external polling is not enabled\n"); BREAK_IF(p == NULL, "POLL failed as the input parameter was NULL\n"); #ifdef QAT_HW if (qat_hw_offload && !fallback_to_qat_sw) { BREAK_IF(qat_instance_handles == NULL, "POLL failed as no instances are available\n"); *(int *)p = (int)poll_instances(); } #endif #ifdef QAT_SW if (qat_sw_offload) *(int *)p = qat_sw_poll(); #endif break; case QAT_CMD_ENABLE_EXTERNAL_POLLING: BREAK_IF(engine_inited, \ "ENABLE_EXTERNAL_POLLING failed as the engine is already initialized\n"); DEBUG("Enabled external polling\n"); enable_external_polling = 1; #ifdef QAT_HW enable_inline_polling = 0; #endif break; #ifdef QAT_HW case QAT_CMD_ENABLE_INLINE_POLLING: BREAK_IF(engine_inited, \ "ENABLE_INLINE_POLLING failed as the engine is already initialized\n"); DEBUG("Enabled inline polling\n"); enable_inline_polling = 1; enable_external_polling = 0; break; # ifndef __FreeBSD__ case QAT_CMD_GET_EXTERNAL_POLLING_FD: BREAK_IF(!enable_event_driven_polling || !enable_external_polling, \ "GET_EXTERNAL_POLLING_FD failed as this engine message is only supported \ when running in Event Driven Mode with External Polling enabled\n"); BREAK_IF(!engine_inited, \ "GET_EXTERNAL_POLLING_FD failed as the engine is not initialized\n"); BREAK_IF(qat_instance_handles == NULL, \ "GET_EXTERNAL_POLLING_FD failed as no instances are available\n"); BREAK_IF(p == NULL, "GET_EXTERNAL_POLLING_FD failed as the input parameter was NULL\n"); BREAK_IF(i >= qat_num_instances, \ "GET_EXTERNAL_POLLING_FD failed as the instance does not exist\n"); /* Get the file descriptor for the instance */ status = icp_sal_CyGetFileDescriptor(qat_instance_handles[i], &fd); BREAK_IF(CPA_STATUS_FAIL == status, \ "GET_EXTERNAL_POLLING_FD failed as there was an error retrieving the fd\n"); /* Make the file descriptor non-blocking */ flags = qat_fcntl(fd, F_GETFL, 0); fcntl_ret = qat_fcntl(fd, F_SETFL, flags | O_NONBLOCK); BREAK_IF(fcntl_ret == -1, \ "GET_EXTERNAL_POLLING_FD failed as there was an error in setting the fd as NONBLOCKING\n"); DEBUG("External polling FD for instance[%ld] = %d\n", i, fd); *(int *)p = fd; break; case QAT_CMD_ENABLE_EVENT_DRIVEN_POLLING_MODE: DEBUG("Enabled event driven polling mode\n"); BREAK_IF(engine_inited, \ "ENABLE_EVENT_DRIVEN_POLLING_MODE failed as the engine is already initialized\n"); enable_event_driven_polling = 1; break; case QAT_CMD_DISABLE_EVENT_DRIVEN_POLLING_MODE: DEBUG("Disabled event driven polling mode\n"); BREAK_IF(engine_inited, \ "DISABLE_EVENT_DRIVEN_POLLING_MODE failed as the engine is already initialized\n"); enable_event_driven_polling = 0; break; # endif /* qatPerformOpRetries and qat_pkt_threshold_table_set_threshold undefined */ #ifndef QAT_BORINGSSL case QAT_CMD_SET_INSTANCE_FOR_THREAD: BREAK_IF(!engine_inited, \ "SET_INSTANCE_FOR_THREAD failed as the engine is not initialized\n"); BREAK_IF(qat_instance_handles == NULL, \ "SET_INSTANCE_FOR_THREAD failed as no instances are available\n"); DEBUG("Set instance for thread = %ld\n", i); retVal = qat_set_instance_for_thread(i); break; case QAT_CMD_GET_NUM_OP_RETRIES: BREAK_IF(p == NULL, "GET_NUM_OP_RETRIES failed as the input parameter was NULL\n"); BREAK_IF(!engine_inited, "GET_NUM_OP_RETRIES failed as the engine is not initialized\n"); *(int *)p = qatPerformOpRetries; break; case QAT_CMD_SET_MAX_RETRY_COUNT: BREAK_IF(i < -1 || i > 100000, "The Message retry count value is out of range, using default value\n"); DEBUG("Set max retry counter = %ld\n", i); qat_max_retry_count = (int)i; break; #endif case QAT_CMD_SET_INTERNAL_POLL_INTERVAL: BREAK_IF(i < 1 || i > 1000000, "The polling interval value is out of range, using default value\n"); DEBUG("Set internal poll interval = %ld ns\n", i); qat_poll_interval = (useconds_t) i; break; #ifndef QAT_BORINGSSL case QAT_CMD_SET_EPOLL_TIMEOUT: BREAK_IF(i < 1 || i > 10000, "The epoll timeout value is out of range, using default value\n") DEBUG("Set epoll_wait timeout = %ld ms\n", i); qat_epoll_timeout = (int) i; break; case QAT_CMD_GET_NUM_CRYPTO_INSTANCES: BREAK_IF(p == NULL, \ "GET_NUM_CRYPTO_INSTANCES failed as the input parameter was NULL\n"); BREAK_IF(!engine_inited, \ "GET_NUM_CRYPTO_INSTANCES failed as the engine is not initialized\n"); BREAK_IF(qat_instance_handles == NULL, \ "GET_NUM_CRYPTO_INSTANCES failed as no instances are available\n"); DEBUG("Get number of crypto instances = %d\n", qat_num_instances); *(int *)p = qat_num_instances; break; #endif /* QAT_BORINGSSL */ #endif #ifndef QAT_BORINGSSL case QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD: # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (p != NULL) { char *token; char str_p[QAT_MAX_INPUT_STRING_LENGTH]; char *itr = str_p; strncpy(str_p, (const char *)p, QAT_MAX_INPUT_STRING_LENGTH - 1); str_p[QAT_MAX_INPUT_STRING_LENGTH - 1] = '\0'; while ((token = strsep(&itr, ","))) { char *name_token = strsep(&token,":"); char *value_token = strsep(&token,":"); if (name_token && value_token) { retVal = qat_pkt_threshold_table_set_threshold( name_token, atoi(value_token)); } else { WARN("Invalid name_token or value_token\n"); retVal = 0; } } } else { WARN("Invalid p parameter\n"); retVal = 0; } # else WARN("QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD is not supported\n"); retVal = 0; # endif break; #endif /* QAT_BORINGSSL */ case QAT_CMD_ENABLE_HEURISTIC_POLLING: BREAK_IF(engine_inited, "ENABLE_HEURISTIC_POLLING failed as the engine is already initialized\n"); BREAK_IF(!enable_external_polling, "ENABLE_HEURISTIC_POLLING failed as external polling is not enabled\n"); DEBUG("Enabled heuristic polling\n"); enable_heuristic_polling = 1; break; case QAT_CMD_GET_NUM_REQUESTS_IN_FLIGHT: BREAK_IF(p == NULL, "GET_NUM_REQUESTS_IN_FLIGHT failed as the input parameter was NULL\n"); if (i == GET_NUM_ASYM_REQUESTS_IN_FLIGHT) { *(int **)p = &num_asym_requests_in_flight; } else if (i == GET_NUM_KDF_REQUESTS_IN_FLIGHT) { *(int **)p = &num_kdf_requests_in_flight; } else if (i == GET_NUM_CIPHER_PIPELINE_REQUESTS_IN_FLIGHT) { *(int **)p = &num_cipher_pipeline_requests_in_flight; } else if (i == GET_NUM_ASYM_MB_ITEMS_IN_QUEUE) { *(int **)p = &num_asym_mb_items_in_queue; } else if (i == GET_NUM_KDF_MB_ITEMS_IN_QUEUE) { *(int **)p = &num_kdf_mb_items_in_queue; } else if (i == GET_NUM_SYM_MB_ITEMS_IN_QUEUE) { *(int **)p = &num_cipher_mb_items_in_queue; } else { WARN("Invalid i parameter\n"); retVal = 0; } break; case QAT_CMD_INIT_ENGINE: DEBUG("Init engine\n"); if ((retVal = qat_engine_init(e)) == 0) { WARN("Failure initializing engine\n"); } break; #ifdef QAT_HW case QAT_CMD_SET_CONFIGURATION_SECTION_NAME: BREAK_IF(engine_inited, \ "QAT_CMD_SET_CONFIGURATION_SECTION_NAME failed as the engine is already initialized\n"); if (p) { retVal = validate_configuration_section_name(p); if (retVal) { strncpy(qat_config_section_name, p, QAT_CONFIG_SECTION_NAME_SIZE - 1); qat_config_section_name[QAT_CONFIG_SECTION_NAME_SIZE - 1] = '\0'; } else { WARN("Section name is NULL or invalid length\n"); retVal = 0; } } else { WARN("Invalid p parameter\n"); retVal = 0; } break; case QAT_CMD_ENABLE_SW_FALLBACK: DEBUG("Enabled SW Fallback\n"); BREAK_IF(engine_inited, \ "ENABLE_SW_FALLBACK failed as the engine is already initialized\n"); enable_sw_fallback = 1; CRYPTO_QAT_LOG("SW Fallback enabled - %s\n", __func__); break; case QAT_CMD_HEARTBEAT_POLL: BREAK_IF(!engine_inited, "HEARTBEAT_POLL failed as engine is not initialized\n"); BREAK_IF(!enable_external_polling, "HEARTBEAT_POLL failed as external polling is not enabled\n"); BREAK_IF(p == NULL, "HEARTBEAT_POLL failed as the input parameter was NULL\n"); if (qat_instance_handles != NULL) { *(int *)p = (int)poll_heartbeat(); CRYPTO_QAT_LOG("QAT Engine Heartbeat Poll - %s\n", __func__); } else if (!fallback_to_qat_sw) { WARN("HEARTBEAT_POLL failed as no instances are available\n"); retVal = 0; } break; case QAT_CMD_DISABLE_QAT_OFFLOAD: DEBUG("Disabled qat offload\n"); BREAK_IF(!engine_inited, \ "DISABLE_QAT_OFFLOAD failed as the engine is not initialized\n"); disable_qat_offload = 1; CRYPTO_QAT_LOG("QAT Engine Offload disabled - %s\n", __func__); break; #endif #ifdef QAT_HW case QAT_CMD_HW_ALGO_BITMAP: BREAK_IF(NULL == p, "The CMD HW_ALGO_BITMAP needs a string input.\n"); val = strtoul(p, &temp, 0); BREAK_IF(errno == ERANGE || temp == p || *temp != '\0', "The hardware enable mask is invalid.\n"); BREAK_IF(val > 0xFFFFF, "The hardware enable mask is out of the range.\n"); DEBUG("QAT_CMD_HW_ALGO_BITMAP = 0x%lx\n", val); qat_hw_algo_enable_mask = val; qat_reload_algo = 1; BREAK_IF(!bind_qat(e, engine_qat_id), "QAT Engine bind failed\n"); qat_reload_algo = 0; break; #endif #if defined(QAT_SW) || defined(QAT_SW_IPSEC) case QAT_CMD_SW_ALGO_BITMAP: BREAK_IF(NULL == p, "The CMD SW_ALGO_BITMAP needs a string input.\n"); val = strtoul(p, &temp, 0); BREAK_IF(errno == ERANGE || temp == p || *temp != '\0', "The software enable mask is invalid.\n"); BREAK_IF(val > 0xFFFFF, "The software enable mask is out of the range.\n"); DEBUG("QAT_CMD_SW_ALGO_BITMAP = 0x%lx\n", val); qat_sw_algo_enable_mask = val; qat_reload_algo = 1; BREAK_IF(!bind_qat(e, engine_qat_id), "QAT Engine bind failed\n"); qat_reload_algo = 0; break; #endif default: WARN("CTRL command not implemented\n"); retVal = 0; break; } if (!retVal) { QATerr(QAT_F_QAT_ENGINE_CTRL, QAT_R_ENGINE_CTRL_CMD_FAILURE); } return retVal; } #endif /* QAT_OPENSSL_PROVIDER */ #ifdef ENABLE_QAT_HW_KPT EVP_PKEY *qat_engine_load_privkey(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data) { EVP_PKEY *pkey = NULL; CpaStatus status = CPA_STATUS_SUCCESS; CpaCyCapabilitiesInfo CapInfo; int instNum = 0; DEBUG("Begin qat_engine_load_privkey\n"); if (access(key_id, F_OK)) { WARN("File %s does not exist\n", key_id); goto error; } /* Query KPT capability */ for (instNum = 0; instNum < qat_num_instances; instNum++) { status = cpaCyQueryCapabilities(qat_instance_handles[instNum], &CapInfo); if (CPA_STATUS_SUCCESS != status || CPA_FALSE == CapInfo.kptSupported) { WARN("KPT is not supported on device %d\n", qat_instance_details[instNum].qat_instance_info.physInstId.packageId); goto error; } } pkey = qat_hw_kpt_load_privkey(e, key_id); if (pkey == NULL) { WARN("qat_hw_kpt_load_privkey failed\n"); goto error; } kpt_enabled = 1; DEBUG("Finish qat_engine_load_privkey\n"); return pkey; error: WARN("Error in qat_engine_load_privkey\n"); return NULL; } #endif /****************************************************************************** * function: * bind_qat(ENGINE *e, * const char *id) * * @param e [IN] - OpenSSL engine pointer * @param id [IN] - engine id * * description: * Connect Qat engine to OpenSSL engine library ******************************************************************************/ int bind_qat(ENGINE *e, const char *id) { int ret = 0; #ifdef QAT_HW char *config_section = NULL; #ifdef ENABLE_QAT_HW_KPT Cpa32U dev_count = 0; # endif #endif QAT_DEBUG_LOG_INIT(); WARN("QAT Warnings enabled.\n"); DEBUG("QAT Debug enabled.\n"); WARN("%s - %s \n", id, engine_qat_name); /* Ensure the QAT error handling is set up */ ERR_load_QAT_strings(); /* For QAT_HW, Check if the QAT_HW device is available */ #ifdef QAT_HW # ifdef ENABLE_QAT_HW_KPT if (icp_adf_get_numDevices(&dev_count) == CPA_STATUS_SUCCESS) { if (dev_count > 0) { qat_hw_offload = 1; DEBUG("%d QAT HW device available\n", dev_count); } } # else if (icp_sal_userIsQatAvailable() == CPA_TRUE) { qat_hw_offload = 1; DEBUG("QAT HW device available\n"); } # endif if (!qat_hw_offload) { # ifndef QAT_SW # ifdef QAT_BORINGSSL fprintf(stderr, "QAT_HW device not available & QAT_SW not enabled. Exiting!\n"); return ret; # else fprintf(stderr, "QAT_HW device not available & QAT_SW not enabled. Using OpenSSL_SW!\n"); # endif # endif } #endif #if defined(QAT_SW) || defined(QAT_SW_IPSEC) /* For QAT_SW, check if we are running only on Intel CPU & * has the instruction set needed */ qat_sw_offload = qat_sw_cpu_support(); #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_offload && !vaesgcm_init_ipsec_mb_mgr()) { fprintf(stderr, "QAT_SW IPSec_mb manager iInitialization failed\n"); return ret; } #endif #ifndef QAT_OPENSSL_PROVIDER if (id && (strcmp(id, engine_qat_id) != 0)) { WARN("ENGINE_id defined already! %s - %s\n", id, engine_qat_id); return ret; } if (!ENGINE_set_id(e, engine_qat_id)) { fprintf(stderr, "ENGINE_set_id failed\n"); return ret; } if (!ENGINE_set_name(e, engine_qat_name)) { fprintf(stderr, "ENGINE_set_name failed\n"); return ret; } if (qat_hw_offload) { # ifdef ENABLE_QAT_HW_DSA if (!ENGINE_set_DSA(e, qat_get_DSA_methods())) { WARN("ENGINE_set_DSA QAT HW failed\n"); return ret; } # endif # ifdef ENABLE_QAT_HW_DH if (!ENGINE_set_DH(e, qat_get_DH_methods())) { WARN("ENGINE_set_DH QAT HW failed\n"); return ret; } # endif } # if defined(QAT_HW) || defined(QAT_SW) if (!ENGINE_set_RSA(e, qat_get_RSA_methods())) { WARN("ENGINE_set_RSA QAT HW failed\n"); return ret; } if (!ENGINE_set_EC(e, qat_get_EC_methods())) { WARN("ENGINE_set_EC failed\n"); return ret; } if (!ENGINE_set_pkey_meths(e, qat_pkey_methods)) { WARN("ENGINE_set_pkey_meths failed\n"); return ret; } # ifndef QAT_BORINGSSL qat_create_digest_meth(); if (!ENGINE_set_digests(e, qat_digest_methods)) { WARN("ENGINE_set_digests failed\n"); return ret; } /* Create static structures for ciphers now * as this function will be called by a single thread. */ qat_create_ciphers(); if (!ENGINE_set_ciphers(e, qat_ciphers)) { WARN("ENGINE_set_ciphers failed\n"); return ret; } # endif /* QAT_BORINGSSL */ ret = 1; ret &= ENGINE_set_destroy_function(e, qat_engine_destroy); ret &= ENGINE_set_init_function(e, qat_engine_init); ret &= ENGINE_set_ctrl_function(e, qat_engine_ctrl); ret &= ENGINE_set_finish_function(e, qat_engine_finish); #ifdef ENABLE_QAT_HW_KPT ret &= ENGINE_set_load_privkey_function(e, qat_engine_load_privkey); #endif ret &= ENGINE_set_cmd_defns(e, qat_cmd_defns); if (ret == 0) { fprintf(stderr, "Engine failed to register init, finish or destroy functions\n"); return ret; } # endif #endif /* QAT_OPENSSL_PROVIDER */ #ifdef QAT_OPENSSL_PROVIDER /* Set the corresponding algorithms offload for provider */ if (qat_hw_offload) { # ifdef ENABLE_QAT_HW_RSA qat_hw_rsa_offload = 1; INFO("QAT_HW RSA for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_ECDSA qat_hw_ecdsa_offload = 1; INFO("QAT_HW ECDSA for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_ECDH qat_hw_ecdh_offload = 1; INFO("QAT_HW ECDH for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_DSA qat_hw_dsa_offload = 1; INFO("QAT_HW DSA for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_DH qat_hw_dh_offload = 1; INFO("QAT_HW DH for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_ECX qat_hw_ecx_offload = 1; INFO("QAT_HW ECX25519 for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_ECX qat_hw_ecx_448_offload = 1; INFO("QAT_HW ECX448 for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_PRF qat_hw_prf_offload = 1; INFO("QAT_HW PRF for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_HKDF qat_hw_hkdf_offload = 1; INFO("QAT_HW HKDF for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_SHA3 qat_hw_sha_offload = 1; INFO("QAT_HW SHA3 for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_SM3 qat_hw_sm3_offload = 1; INFO("QAT_HW SM3 for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_HW_GCM if (!qat_sw_gcm_offload) { qat_hw_gcm_offload = 1; DEBUG("QAT_HW GCM for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_HW_CIPHERS qat_hw_aes_cbc_hmac_sha_offload = 1; INFO("QAT_HW CIPHERS for Provider Enabled\n"); # endif } if (qat_sw_offload) { # ifdef ENABLE_QAT_SW_RSA if (!qat_hw_rsa_offload && mbx_get_algo_info(MBX_ALGO_RSA_2K) && mbx_get_algo_info(MBX_ALGO_RSA_3K) && mbx_get_algo_info(MBX_ALGO_RSA_4K)) { qat_sw_rsa_offload = 1; INFO("QAT_SW RSA for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_SW_ECDSA if (!qat_hw_ecdsa_offload && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P384)) { qat_sw_ecdsa_offload = 1; INFO("QAT_SW ECDSA for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_SW_ECDH if (!qat_hw_ecdh_offload && mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P384)) { qat_sw_ecdh_offload = 1; INFO("QAT_SW ECDH for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_SW_ECX if (!qat_hw_ecx_offload && mbx_get_algo_info(MBX_ALGO_X25519)) { qat_sw_ecx_offload = 1; INFO("QAT_SW X25519 for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_SW_SM2 if (!qat_hw_sm2_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM2) && mbx_get_algo_info(MBX_ALGO_EC_SM2)) { qat_sw_sm2_offload = 1; INFO("QAT_SW SM2 for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_SW_GCM qat_sw_gcm_offload = 1; DEBUG("QAT_SW GCM for Provider Enabled\n"); # endif # if defined(ENABLE_QAT_FIPS) && defined (ENABLE_QAT_SW_SHA2) qat_sw_sha_offload = 1; INFO("QAT_SW SHA2 for Provider Enabled\n"); if(!sha_init_ipsec_mb_mgr()) { WARN("SHA IPSec_Mb Manager Initialization failed\n"); return 0; } # endif } /* Create static structures for ciphers now * as this function will be called by a single thread. */ qat_create_ciphers(); /* Initialize EVP_MD methods for supported digest algorithms. * This sets up the digest methods for both hardware and software digests. */ qat_create_digest_meth(); # ifndef QAT_DEBUG if (qat_sw_gcm_offload && !qat_hw_gcm_offload) INFO("QAT_SW GCM for Provider Enabled\n"); if (qat_hw_gcm_offload && !qat_sw_gcm_offload) INFO("QAT_HW GCM for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) INFO("QAT_SW SM4-GCM for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_SW_SM4_CCM if (qat_sw_sm4_ccm_offload) INFO("QAT_SW SM4-CCM for Provider Enabled\n"); # endif # if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) if (qat_sw_sm4_cbc_offload && !qat_hw_sm4_cbc_offload) INFO("QAT_SW SM4-CBC for Provider Enabled\n"); if (qat_hw_sm4_cbc_offload && !qat_sw_sm4_cbc_offload) INFO("QAT_HW SM4-CBC for Provider Enabled\n"); # endif # ifdef ENABLE_QAT_SW_SM3 if (qat_sw_sm3_offload) { INFO("QAT_SW SM3 for Provider Enabled\n"); } # endif # ifdef ENABLE_QAT_HW_CCM if (qat_hw_aes_ccm_offload) INFO("QAT_HW AES-CCM for Provider Enabled\n"); # endif #endif #ifndef QAT_BORINGSSL pthread_atfork(engine_finish_before_fork_handler, NULL, engine_init_child_at_fork_handler); #else /* QAT_BORINGSSL */ /* Set handler to ENGINE_unload_qat and ENGINE_load_qat */ pthread_atfork(ENGINE_unload_qat, NULL, ENGINE_load_qat); #endif /* QAT_BORINGSSL */ /* * If the QAT_SECTION_NAME environment variable is set, use that. * Similar setting made through engine ctrl command takes precedence * over this environment variable. It makes sense to use the environment * variable because the container orchestrators pass down this * configuration as environment variables. */ #ifdef QAT_HW # ifdef __GLIBC_PREREQ # if __GLIBC_PREREQ(2, 17) config_section = secure_getenv("QAT_SECTION_NAME"); # else config_section = getenv("QAT_SECTION_NAME"); # endif # else config_section = getenv("QAT_SECTION_NAME"); # endif if (validate_configuration_section_name(config_section)) { strncpy(qat_config_section_name, config_section, QAT_CONFIG_SECTION_NAME_SIZE - 1); qat_config_section_name[QAT_CONFIG_SECTION_NAME_SIZE - 1] = '\0'; } #endif ret = 1; return ret; } #ifndef QAT_OPENSSL_PROVIDER #ifndef OPENSSL_NO_DYNAMIC_ENGINE IMPLEMENT_DYNAMIC_BIND_FN(bind_qat) IMPLEMENT_DYNAMIC_CHECK_FN() #endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */ /* initialize Qat Engine if OPENSSL_NO_DYNAMIC_ENGINE*/ #ifdef OPENSSL_NO_DYNAMIC_ENGINE static ENGINE *engine_qat(void) { ENGINE *ret = NULL; DEBUG("- Starting\n"); /* For boringssl enabled, no API like ENGINE_add to add a new engine to * engine list, so just return existing global engine pointer */ if (ENGINE_QAT_PTR_GET()) { return ENGINE_QAT_PTR_GET(); } ret = ENGINE_new(); /* qat_engine_ptr points the new engine */ ENGINE_QAT_PTR_SET(ret); if (!ret) { fprintf(stderr, "Failed to create Engine\n"); QATerr(QAT_F_ENGINE_QAT, QAT_R_QAT_CREATE_ENGINE_FAILURE); return NULL; } if (!bind_qat(ret, engine_qat_id)) { fprintf(stderr, "Qat Engine bind failed\n"); ENGINE_free(ret); ENGINE_QAT_PTR_RESET(); return NULL; } return ret; } void ENGINE_load_qat(void) { ENGINE *toadd; int error = 0; char error_string[QAT_MAX_ERROR_STRING] = { 0 }; QAT_DEBUG_LOG_INIT(); DEBUG("- Starting\n"); toadd = engine_qat(); if (toadd == NULL) { error = ERR_peek_error(); ERR_error_string_n(error, error_string, QAT_MAX_ERROR_STRING); WARN("Error reported by engine load: %s\n", error_string); return; } DEBUG("adding engine\n"); /* For boringssl enabled, no API like ENGINE_add to add a new engine to * engine list, so here ENGINE_add was redefined to do nothing. And also * not free the engine using ENGINE_free */ ENGINE_add(toadd); #ifndef QAT_BORINGSSL ENGINE_free(toadd); #endif /* QAT_BORINGSSL */ ERR_clear_error(); } #ifdef QAT_BORINGSSL void ENGINE_unload_qat(void) { ENGINE *todel; DEBUG("- Stopping\n"); todel = ENGINE_QAT_PTR_GET(); if (todel != NULL) { qat_engine_destroy(todel); qat_engine_finish(todel); ENGINE_free(todel); ENGINE_QAT_PTR_RESET(); } } #endif /* QAT_BORINGSSL */ #endif /* QAT_OPENSSL_PROVIDER */ #endif qatengine-1.9.0/e_qat.h000066400000000000000000001016001500416242000147260ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file e_qat.h * * This file provides and interface for an OpenSSL QAT engine implementation * *****************************************************************************/ #ifndef E_QAT_H # define E_QAT_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include # include # include # include # include # include # ifdef QAT_BORINGSSL # include "qat_bssl.h" # include "qat_bssl_err.h" # else # include "qat_err.h" # include #endif /* QAT_BORINGSSL */ # ifdef QAT_HW # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_common.h" # include "qat_hw_usdm_inf.h" # endif # ifdef QAT_SW # include "qat_sw_queue.h" # include "qat_sw_freelist.h" # endif #include "qat_common.h" # ifndef ERR_R_RETRY # define ERR_R_RETRY 57 # endif # define likely(x) __builtin_expect (!!(x), 1) # define unlikely(x) __builtin_expect (!!(x), 0) # define XSTR(x) #x # define STR(x) XSTR(x) /* Macro used to handle errors in qat_engine_ctrl() */ # define BREAK_IF(cond, mesg) \ if (unlikely(cond)) { retVal = 0; WARN(mesg); break; } /* * Max Length (bytes) of error string in human readable format */ # define QAT_MAX_ERROR_STRING 256 /* * Different values passed in as param 3 for the message * QAT_CMD_GET_NUM_REQUESTS_IN_FLIGHT to retrieve the number of different kinds * of in-flight requests and number of items in queue for Multi-buffer */ # define GET_NUM_ASYM_REQUESTS_IN_FLIGHT 1 # define GET_NUM_KDF_REQUESTS_IN_FLIGHT 2 # define GET_NUM_CIPHER_PIPELINE_REQUESTS_IN_FLIGHT 3 # define GET_NUM_ASYM_MB_ITEMS_IN_QUEUE 4 # define GET_NUM_KDF_MB_ITEMS_IN_QUEUE 5 # define GET_NUM_SYM_MB_ITEMS_IN_QUEUE 6 /* Behavior of qat_engine_finish_int */ # define QAT_RETAIN_GLOBALS 0 # define QAT_RESET_GLOBALS 1 # define QAT_ATOMIC_INC(qat_int) \ (__sync_add_and_fetch(&(qat_int), 1)) # define QAT_ATOMIC_DEC(qat_int) \ (__sync_sub_and_fetch(&(qat_int), 1)) extern clock_t clock_id; # ifdef QAT_HW typedef struct { int qatAsymInstanceNumForThread; int qatSymInstanceNumForThread; #ifdef ENABLE_QAT_HW_KPT /* WPK index used in KPT scenario. */ int kpt_wpk_in_use; #endif unsigned int localOpsInFlight; } thread_local_variables_t; typedef struct { CpaInstanceInfo2 qat_instance_info; unsigned int qat_instance_started; } qat_instance_details_t; typedef struct { unsigned int qat_accel_present; unsigned int qat_accel_reset_status; } qat_accel_details_t; # define INSTANCE_TYPE_CRYPTO 1 # define QAT_INSTANCE_ASYM 8 # define QAT_INSTANCE_SYM 16 # define QAT_INSTANCE_ANY -1 # define QAT_INSTANCE_CONTIGUOUS 0 # define QAT_INSTANCE_SVM 1 # define QAT_RETRY_BACKOFF_MODULO_DIVISOR 8 # define QAT_INFINITE_MAX_NUM_RETRIES -1 # define QAT_INVALID_INSTANCE -1 # define QAT_INC_IN_FLIGHT_REQS(qat_int, tlv) \ do { \ if (qat_use_signals()) { \ QAT_ATOMIC_INC(qat_int); \ tlv->localOpsInFlight++; \ } \ } while(0) # define QAT_DEC_IN_FLIGHT_REQS(qat_int, tlv) \ do { \ if (qat_use_signals()) { \ tlv->localOpsInFlight--; \ QAT_ATOMIC_DEC(qat_int); \ } \ } while(0) # define QAT_MEM_FREE_BUFF(b, svm) \ do { \ if (b != NULL) { \ if (!svm) \ qaeCryptoMemFree(b); \ else \ OPENSSL_free(b); \ b = NULL; \ } \ } while(0) # define QAT_CLEANSE_FREE_BUFF(b,len) \ do { \ if (b != NULL) { \ OPENSSL_cleanse(b, len); \ OPENSSL_free(b); \ b = NULL; \ } \ } while(0) # define QAT_MEM_FREE_NONZERO_BUFF(b, svm) \ do { \ if (b != NULL) { \ if (!svm) \ qaeCryptoMemFreeNonZero(b); \ else \ OPENSSL_free(b); \ b = NULL; \ } \ } while(0) # define QAT_CLEANSE_FLATBUFF(b) \ OPENSSL_cleanse((b).pData, (b).dataLenInBytes) # define QAT_MEM_FREE_FLATBUFF(b, svm) \ do { \ if ((b).pData != NULL) { \ if (!svm) \ qaeCryptoMemFree((b).pData); \ else \ OPENSSL_free((b).pData); \ (b).pData = NULL; \ } \ } while(0) # define QAT_CLEANSE_MEMFREE_FLATBUFF(b, svm) \ do { \ if ((b).pData != NULL) { \ QAT_CLEANSE_FLATBUFF(b); \ QAT_MEM_FREE_FLATBUFF(b, svm); \ } \ } while(0) # define QAT_MEM_FREE_NONZERO_FLATBUFF(b, svm) \ do { \ if ((b).pData != NULL) { \ if (!svm) \ qaeCryptoMemFreeNonZero((b).pData); \ else \ OPENSSL_free((b).pData); \ (b).pData = NULL; \ } \ } while(0) # define QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(b, svm) \ do { \ if ((b).pData != NULL) { \ QAT_CLEANSE_FLATBUFF(b); \ QAT_MEM_FREE_NONZERO_FLATBUFF(b, svm); \ } \ } while(0) # define FLATBUFF_ALLOC_AND_CHAIN(b1, b2, len) \ do { \ (b1).pData = qaeCryptoMemAlloc(len, __FILE__, __LINE__); \ (b2).pData = (b1).pData; \ (b1).dataLenInBytes = len; \ (b2).dataLenInBytes = len; \ } while(0) #define FLATBUFF_ALLOC_AND_CHAIN_SVM(b1, b2, len) \ do { \ (b1).pData = OPENSSL_zalloc(len); \ (b2).pData = (b1).pData; \ (b1).dataLenInBytes = len; \ (b2).dataLenInBytes = len; \ } while(0) # define QAT_CONFIG_SECTION_NAME_SIZE 64 # define QAT_MAX_CRYPTO_INSTANCES 256 # define QAT_MAX_CRYPTO_ACCELERATORS 512 /* * The default interval in nanoseconds used for the internal polling thread */ # define QAT_POLL_PERIOD_IN_NS 10000 /* * The number of retries of the nanosleep if it gets interrupted during * waiting between polling. */ # define QAT_CRYPTO_NUM_POLLING_RETRIES 5 /* * The number of retries of the sigtimedwait if it gets interrupted during * waiting for a signal. */ # define QAT_CRYPTO_NUM_EVENT_RETRIES 2 /* * The number of seconds to wait for a response back after submitting a * request before raising an error. */ # define QAT_CRYPTO_RESPONSE_TIMEOUT 5 /* * The default timeout in milliseconds used for epoll_wait when event driven * polling mode is enabled. */ # define QAT_EPOLL_TIMEOUT_IN_MS 1000 /* * The default timeout in seconds used when waiting for events that requests * are in-flight. */ # define QAT_EVENT_TIMEOUT_IN_SEC 1 #endif #ifdef QAT_SW /* * Used to size the freelist and queue as it represents how many * requests can be in-flight at once. */ # ifndef MULTIBUFF_MAX_INFLIGHTS # define MULTIBUFF_MAX_INFLIGHTS 128 # endif /* * The maximum amount of iterations we will continue to submit * batches of requests for. This is to prevent getting stuck in * a continuous loop in the situation where requests are getting * submitted faster than they are getting processed. */ # define MULTIBUFF_MAX_SUBMISSIONS 4 /* * Additional define just for the prototype to force batching * of requests less than MULTIBUFF_BATCH. */ # ifndef MULTIBUFF_MIN_BATCH # define MULTIBUFF_MIN_BATCH 8 # endif /* * Number of multi-buffer requests to wait until are queued before * attempting to process them. */ # ifndef MULTIBUFF_MAX_BATCH # define MULTIBUFF_MAX_BATCH 8 # endif /* * Number of multi-buffer requests to submit to the crypto_mb library * for processing in one go. */ # define MULTIBUFF_BATCH 8 /* * SM3 can handle processing up to 16 requests while others can handle * up to 8 requests only */ # ifndef MULTIBUFF_SM3_BATCH # define MULTIBUFF_SM3_BATCH 16 # endif # ifndef MULTIBUFF_SM3_MIN_BATCH # define MULTIBUFF_SM3_MIN_BATCH 16 # endif # ifndef MULTIBUFF_SM3_MAX_BATCH # define MULTIBUFF_SM3_MAX_BATCH 16 # endif /* * SM4 can handle processing up to 16 requests while others can handle * up to 8 requests only */ # ifndef MULTIBUFF_SM4_BATCH # define MULTIBUFF_SM4_BATCH 16 # endif # ifndef MULTIBUFF_SM4_MIN_BATCH # define MULTIBUFF_SM4_MIN_BATCH 16 # endif # ifndef MULTIBUFF_SM4_MAX_BATCH # define MULTIBUFF_SM4_MAX_BATCH 16 # endif /* * Max number of multi-buffer Polling threads */ # define NUM_POLL_THREADS 128 /* Macro that does queue cleanup based on the algorithm * request in (x) */ # define QAT_SW_CLEANUP(x, opdata, ptr) \ opdata *req_##x = NULL; \ mb_queue_##x##_disable(ptr); \ if (ptr) { \ while ((req_##x = \ mb_queue_##x##_dequeue(ptr)) != NULL) { \ *req_##x->sts = -1; \ qat_wake_job(req_##x->job, 0); \ OPENSSL_free(req_##x); \ } \ mb_queue_##x##_cleanup(ptr); \ } #endif /* Qat engine id declaration */ extern const char *engine_qat_id; extern const char *engine_qat_name; extern unsigned int engine_inited; extern int fallback_to_openssl; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) extern int qat_openssl3_prf_fallback; extern int qat_openssl3_hkdf_fallback; extern int qat_openssl3_sha_fallback; #endif extern int qat_openssl3_sm3_fallback; extern int qat_openssl3_sm2_fallback; extern int fallback_to_qat_sw; /* QAT HW initialization fail, offload to QAT SW. */ extern int qat_hw_offload; extern int qat_sw_offload; extern int qat_hw_rsa_offload; extern int qat_hw_ecx_offload; extern int qat_hw_ecdh_offload; extern int qat_hw_ecdsa_offload; extern int qat_hw_prf_offload; extern int qat_hw_hkdf_offload; extern int qat_hw_gcm_offload; extern int qat_hw_chacha_poly_offload; extern int qat_hw_aes_cbc_hmac_sha_offload; extern int qat_hw_sm4_cbc_offload; extern int qat_sw_rsa_offload; extern int qat_sw_ecx_offload; extern int qat_sw_ecdh_offload; extern int qat_sw_ecdsa_offload; extern int qat_sw_gcm_offload; extern int qat_sw_sm2_offload; extern int qat_hw_sm2_offload; extern int qat_hw_sha_offload; extern int qat_hw_sm3_offload; # ifdef ENABLE_QAT_FIPS extern int qat_sw_sha_offload; # endif # ifdef QAT_OPENSSL_PROVIDER extern int qat_hw_dsa_offload; extern int qat_hw_dh_offload; extern int qat_hw_ecx_448_offload; # endif extern int qat_sw_sm3_offload; extern int qat_sw_sm4_cbc_offload; extern int qat_sw_sm4_gcm_offload; extern int qat_sw_sm4_ccm_offload; extern int qat_hw_aes_ccm_offload; extern int qat_hw_keep_polling; extern int qat_sw_keep_polling; extern int enable_external_polling; extern int enable_heuristic_polling; extern pthread_mutex_t qat_engine_mutex; extern pthread_t qat_polling_thread; extern sem_t hw_polling_thread_sem; extern int num_requests_in_flight; extern int num_asym_requests_in_flight; extern int num_kdf_requests_in_flight; extern int num_cipher_pipeline_requests_in_flight; extern int num_asym_mb_items_in_queue; extern int num_kdf_mb_items_in_queue; extern int num_cipher_mb_items_in_queue; extern sigset_t set; extern pthread_t qat_timer_poll_func_thread; extern int cleared_to_start; extern pthread_mutex_t qat_poll_mutex; extern pthread_cond_t qat_poll_condition; extern int qat_cond_wait_started; #ifdef ENABLE_QAT_FIPS extern int integrity_status; extern int qat_fips_service_indicator; #endif #define ALGO_ENABLE_MASK_RSA 0x00001 #define ALGO_ENABLE_MASK_DSA 0x00002 #define ALGO_ENABLE_MASK_DH 0x00004 #define ALGO_ENABLE_MASK_ECDSA 0x00008 #define ALGO_ENABLE_MASK_ECDH 0x00010 #define ALGO_ENABLE_MASK_ECX25519 0x00020 #define ALGO_ENABLE_MASK_ECX448 0x00040 #define ALGO_ENABLE_MASK_PRF 0x00080 #define ALGO_ENABLE_MASK_HKDF 0x00100 #define ALGO_ENABLE_MASK_SM2 0x00200 #define ALGO_ENABLE_MASK_AES_GCM 0x00400 #define ALGO_ENABLE_MASK_AES_CBC_HMAC_SHA 0x00800 #define ALGO_ENABLE_MASK_SM4_CBC 0x01000 #define ALGO_ENABLE_MASK_CHACHA_POLY 0x02000 #define ALGO_ENABLE_MASK_SHA3 0x04000 #define ALGO_ENABLE_MASK_SM3 0x08000 #define ALGO_ENABLE_MASK_SM4_GCM 0x10000 #define ALGO_ENABLE_MASK_SM4_CCM 0x20000 #define ALGO_ENABLE_MASK_AES_CCM 0x40000 extern int qat_reload_algo; extern uint64_t qat_hw_algo_enable_mask; extern uint64_t qat_sw_algo_enable_mask; extern int qat_rsa_coexist; extern int qat_ecdh_coexist; extern int qat_ecdsa_coexist; extern int qat_ecx_coexist; extern int qat_sm4_cbc_coexist; extern __thread unsigned int qat_sw_rsa_priv_req; extern __thread unsigned int qat_sw_rsa_pub_req; extern __thread unsigned int qat_sw_ecdsa_sign_req; extern __thread unsigned int qat_sw_ecdh_keygen_req; extern __thread unsigned int qat_sw_ecdh_derive_req; extern __thread unsigned int qat_sw_ecx_keygen_req; extern __thread unsigned int qat_sw_ecx_derive_req; extern __thread unsigned int qat_sw_sm4_cbc_cipher_req; extern __thread int num_rsa_priv_retry; extern __thread int num_rsa_pub_retry; extern __thread int num_ecdsa_sign_retry; extern __thread int num_ecdh_keygen_retry; extern __thread int num_ecdh_derive_retry; extern __thread int num_ecx_keygen_retry; extern __thread int num_ecx_derive_retry; extern __thread int num_sm4_cbc_cipher_retry; extern __thread unsigned long long num_rsa_hw_priv_reqs; extern __thread unsigned long long num_rsa_sw_priv_reqs; extern __thread unsigned long long num_rsa_hw_pub_reqs; extern __thread unsigned long long num_rsa_sw_pub_reqs; extern __thread unsigned long long num_ecdsa_hw_sign_reqs; extern __thread unsigned long long num_ecdsa_sw_sign_reqs; extern __thread unsigned long long num_ecdh_hw_keygen_reqs; extern __thread unsigned long long num_ecdh_sw_keygen_reqs; extern __thread unsigned long long num_ecdh_hw_derive_reqs; extern __thread unsigned long long num_ecdh_sw_derive_reqs; extern __thread unsigned long long num_ecx_hw_keygen_reqs; extern __thread unsigned long long num_ecx_sw_keygen_reqs; extern __thread unsigned long long num_ecx_hw_derive_reqs; extern __thread unsigned long long num_ecx_sw_derive_reqs; extern __thread unsigned long long num_sm4_cbc_hw_cipher_reqs; extern __thread unsigned long long num_sm4_cbc_sw_cipher_reqs; #define QAT_SW_SWITCH_MB8 8 #define QAT_SW_SWITCH_MB16 16 # ifdef QAT_HW extern char qat_config_section_name[QAT_CONFIG_SECTION_NAME_SIZE]; extern char *ICPConfigSectionName_libcrypto; extern int enable_inline_polling; extern int enable_event_driven_polling; extern int enable_instance_for_thread; extern int qatPerformOpRetries; extern int disable_qat_offload; extern int enable_sw_fallback; extern CpaInstanceHandle *qat_instance_handles; extern Cpa16U qat_num_instances; extern Cpa16U qat_asym_num_instance; extern Cpa16U qat_sym_num_instance; extern Cpa16U qat_svm_num_instance; extern Cpa16U qat_contig_num_instance; extern Cpa32U qat_num_devices; extern pthread_key_t thread_local_variables; extern pthread_mutex_t qat_instance_mutex; extern qat_instance_details_t qat_instance_details[QAT_MAX_CRYPTO_INSTANCES]; extern qat_accel_details_t qat_accel_details[QAT_MAX_CRYPTO_ACCELERATORS]; extern useconds_t qat_poll_interval; extern int qat_epoll_timeout; extern int qat_max_retry_count; extern unsigned int qat_map_sym_inst[QAT_MAX_CRYPTO_INSTANCES]; extern unsigned int qat_map_asym_inst[QAT_MAX_CRYPTO_INSTANCES]; extern unsigned int qat_map_svm_inst[QAT_MAX_CRYPTO_INSTANCES]; # ifdef ENABLE_QAT_HW_KPT # include "qat_hw_kpt.h" # include "cpa_cy_kpt.h" # define KPT_INVALID_WPK_IDX -1 extern int kpt_enabled; extern int kpt_inited; # endif # endif # ifdef QAT_SW /* RSA */ extern BIGNUM *e_check; extern mb_thread_data *mb_tlv; extern pthread_key_t mb_thread_key; typedef struct _mb_req_rates { int req_this_period; struct timespec previous_time; struct timespec current_time; } mb_req_rates; extern mb_req_rates mb_rsa2k_priv_req_rates; extern mb_req_rates mb_rsa2k_pub_req_rates; extern mb_req_rates mb_rsa3k_priv_req_rates; extern mb_req_rates mb_rsa3k_pub_req_rates; extern mb_req_rates mb_rsa4k_priv_req_rates; extern mb_req_rates mb_rsa4k_pub_req_rates; extern mb_req_rates mb_x25519_keygen_req_rates; extern mb_req_rates mb_x25519_derive_req_rates; extern mb_req_rates mb_ecdsap256_sign_req_rates; extern mb_req_rates mb_ecdsap256_sign_setup_req_rates; extern mb_req_rates mb_ecdsap256_sign_sig_req_rates; extern mb_req_rates mb_ecdsap256_verify_req_rates; extern mb_req_rates mb_ecdsap384_sign_req_rates; extern mb_req_rates mb_ecdsap384_sign_setup_req_rates; extern mb_req_rates mb_ecdsap384_sign_sig_req_rates; extern mb_req_rates mb_ecdsap384_verify_req_rates; extern mb_req_rates mb_ecdhp256_keygen_req_rates; extern mb_req_rates mb_ecdhp256_compute_req_rates; extern mb_req_rates mb_ecdhp384_keygen_req_rates; extern mb_req_rates mb_ecdhp384_compute_req_rates; extern mb_req_rates mb_sm2ecdh_keygen_req_rates; extern mb_req_rates mb_sm2ecdh_compute_req_rates; extern mb_req_rates mb_sm3_init_req_rates; extern mb_req_rates mb_sm3_update_req_rates; extern mb_req_rates mb_sm3_final_req_rates; # endif # define QAT_CMD_ENABLE_EXTERNAL_POLLING ENGINE_CMD_BASE # define QAT_CMD_POLL (ENGINE_CMD_BASE + 1) # define QAT_CMD_SET_INSTANCE_FOR_THREAD (ENGINE_CMD_BASE + 2) # define QAT_CMD_GET_NUM_OP_RETRIES (ENGINE_CMD_BASE + 3) # define QAT_CMD_SET_MAX_RETRY_COUNT (ENGINE_CMD_BASE + 4) # define QAT_CMD_SET_INTERNAL_POLL_INTERVAL (ENGINE_CMD_BASE + 5) # define QAT_CMD_GET_EXTERNAL_POLLING_FD (ENGINE_CMD_BASE + 6) # define QAT_CMD_ENABLE_EVENT_DRIVEN_POLLING_MODE (ENGINE_CMD_BASE + 7) # define QAT_CMD_GET_NUM_CRYPTO_INSTANCES (ENGINE_CMD_BASE + 8) # define QAT_CMD_DISABLE_EVENT_DRIVEN_POLLING_MODE (ENGINE_CMD_BASE + 9) # define QAT_CMD_SET_EPOLL_TIMEOUT (ENGINE_CMD_BASE + 10) # define QAT_CMD_SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD (ENGINE_CMD_BASE + 11) # define QAT_CMD_ENABLE_INLINE_POLLING (ENGINE_CMD_BASE + 12) # define QAT_CMD_ENABLE_HEURISTIC_POLLING (ENGINE_CMD_BASE + 13) # define QAT_CMD_GET_NUM_REQUESTS_IN_FLIGHT (ENGINE_CMD_BASE + 14) # define QAT_CMD_INIT_ENGINE (ENGINE_CMD_BASE + 15) # define QAT_CMD_SET_CONFIGURATION_SECTION_NAME (ENGINE_CMD_BASE + 16) # define QAT_CMD_ENABLE_SW_FALLBACK (ENGINE_CMD_BASE + 17) # define QAT_CMD_HEARTBEAT_POLL (ENGINE_CMD_BASE + 18) # define QAT_CMD_DISABLE_QAT_OFFLOAD (ENGINE_CMD_BASE + 19) # define QAT_CMD_HW_ALGO_BITMAP (ENGINE_CMD_BASE + 20) # define QAT_CMD_SW_ALGO_BITMAP (ENGINE_CMD_BASE + 21) #ifndef QAT_BORINGSSL #ifndef ENGINE_QAT_PTR_DEFINE # define ENGINE_QAT_PTR_RESET() # define ENGINE_QAT_PTR_SET(pt) # define ENGINE_QAT_PTR_GET() NULL #endif #endif /* QAT_BORINGSSL */ # ifdef QAT_HW extern CpaStatus icp_adf_get_numDevices(Cpa32U *); /****************************************************************************** * function: * qat_get_qat_offload_disabled(void) * * description: * This function indicates whether offloading to the QuickAssist hardware * has been disabled. If it has then we can still perform crypto oncore. * ******************************************************************************/ int qat_get_qat_offload_disabled(void); /****************************************************************************** * function: * qat_use_signals(void) * * description: * This function indicates whether pthread signals are being used for thread * synchronisation. If so, then a non-zero value is returned, else zero is * returned. * ******************************************************************************/ int qat_use_signals(void); /****************************************************************************** * function: * qat_get_sw_fallback_enabled(void) * * description: * Return the flag which indicates if QAT engine is enabled to fall back to * software calculation. * ******************************************************************************/ int qat_get_sw_fallback_enabled(void); /****************************************************************************** * function: * int validate_configuration_section_name(const char *name) * * description: * This function validates whether the section name has valid length and * address. If so, then one is returned else zero is returned. * ******************************************************************************/ int validate_configuration_section_name(const char *name); /****************************************************************************** * function: * is_instance_available(int inst_num) * * description: * Return whether the instance number passed in is a currently available * instance. Returns 1 if available, 0 otherwise. * ******************************************************************************/ int is_instance_available(int inst_num); /****************************************************************************** * function: * is_any_device_available(void) * * description: * Return whether any devices are currently available. * Returns 1 if at least one device is detected and up, 0 otherwise. * ******************************************************************************/ int is_any_device_available(void); /****************************************************************************** * function: * get_instance(int inst_type, int mem_type) * * description: * Return the next instance number to use for an operation. * ******************************************************************************/ int get_instance(int inst_type, int mem_type); /****************************************************************************** * function: * qat_check_create_local_variables(void) * * description: * This function checks whether local variables exist in the current thread. * If not, then it will attempt to create them. It returns NULL if the local * variables could not be created, otherwise it returns a pointer to the * local variables data structure. * ******************************************************************************/ thread_local_variables_t * qat_check_create_local_variables(void); /***************************************************************************** * * function: * qat_hw_init(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * qat_hw init function, associated with * Crypto memory setup and cpaStartInstance setups. ******************************************************************************/ int qat_hw_init(ENGINE *e); # endif /***************************************************************************** * * function: * bind_qat(ENGINE *e, const char *id) * * @param e [IN] - OpenSSL engine pointer * @param id [IN] - engine id pointer * * description: * bind function for registering algorithms that are supported in qatngine * and other qat_hw and qat_sw intializaton. * *****************************************************************************/ int bind_qat(ENGINE *e, const char *id); /****************************************************************************** * function: * qat_engine_init(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * Qat Engine initialization ******************************************************************************/ int qat_engine_init(ENGINE *e); /****************************************************************************** * function: * qat_engine_ctrl(ENGINE *e, int cmd, long i, * void *p, void (*f)(void)) * * @param e [IN] - OpenSSL engine pointer * @param cmd [IN] - Control Command * @param i [IN] - Unused * @param p [IN] - Parameters for the command * @param f [IN] - Callback function * * description: * Qat engine control functions. * Note: QAT_CMD_ENABLE_EXTERNAL_POLLING should be called at the following * point during startup: * ENGINE_load_qat * ENGINE_by_id * ---> ENGINE_ctrl_cmd(QAT_CMD_ENABLE_EXTERNAL_POLLING) * ENGINE_init ******************************************************************************/ int qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); /****************************************************************************** * function: * qat_hw_finish_int(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * Qat finish function associated with qat crypto memory free ******************************************************************************/ int qat_hw_finish_int(ENGINE *e, int reset_globals); /****************************************************************************** * function: * qat_engine_finish(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * Qat engine finish function. ******************************************************************************/ int qat_engine_finish(ENGINE *e); /****************************************************************************** * function: * qat_engine_finish_int(ENGINE *e, int reset_globals) * * @param e [IN] - OpenSSL engine pointer * @param reset_globals [IN] - Whether reset the global configuration variables * * description: * Internal Qat engine finish function. * The value of reset_globals should be either QAT_RESET_GLOBALS or * QAT_RETAIN_GLOBALS ******************************************************************************/ int qat_engine_finish_int(ENGINE *e, int reset_globals); #ifdef ENABLE_QAT_HW_KPT /****************************************************************************** * function: * qat_engine_load_privkey(ENGINE *e, const char *key_id, * UI_METHOD *ui_method, void *callback_data) * * @param e [IN] - OpenSSL engine pointer * @param key_id [IN] - String of Path to WPK file * @param ui_method [IN] - Unused * @param callback_data [IN] - Unused * * description: * Qat engine load private key function. * This function will be hooked by openssl and used to load WPK file * in KPT scenario. ******************************************************************************/ EVP_PKEY *qat_engine_load_privkey(ENGINE *e, const char *key_id, UI_METHOD *ui_method, void *callback_data); #endif /***************************************************************************** * function: * int qat_pthread_mutex_lock(void) * * description: * Wrapper function to pthread_mutex with return values checked. * ******************************************************************************/ int qat_pthread_mutex_lock(void); /***************************************************************************** * function: * int qat_pthread_mutex_unlock(void) * * description: * Wrapper function to pthread_mutex with return values checked. * ******************************************************************************/ int qat_pthread_mutex_unlock(void); # ifdef QAT_SW /***************************************************************************** * * function: * qat_sw_init(ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * QAT_SW init function, associated with memory setup. ******************************************************************************/ int qat_sw_init(ENGINE *e); /****************************************************************************** * function: * qat_sw_finish_int(ENGINE *e, int reset_globals) * * @param e [IN] - OpenSSL engine pointer * @param reset_globals [IN] - Whether reset the global configuration variables * * description: * Internal QAT_SW finish function. * The value of reset_globals should be either QAT_RESET_GLOBALS or * QAT_RETAIN_GLOBALS ******************************************************************************/ int qat_sw_finish_int(ENGINE *e, int reset_globals); /****************************************************************************** * function: * mb_check_thread_local(void) * * description: * Check if the thread has thread local pointer created using the key * if not thread local memory polling thread will be created and stored on the * Heap. ******************************************************************************/ mb_thread_data *mb_check_thread_local(void); # endif /****************************************************************************** * function: * qat_sw_cpu_support(void) * * description: * Checks if we are running on Intel CPU and has the instruction set needed * for crypto_mb and ipsec_mb (QAT_SW) offload. ******************************************************************************/ # if defined(QAT_SW) || defined(QAT_SW_IPSEC) int qat_sw_cpu_support(void); # endif # ifdef QAT_OPENSSL_PROVIDER # if OPENSSL_VERSION_NUMBER < 0x30200000 static __inline__ int CRYPTO_UP_REF(int *val, int *ret, ossl_unused void *lock) { *ret = __atomic_fetch_add(val, 1, __ATOMIC_RELAXED) + 1; return 1; } static __inline__ int CRYPTO_DOWN_REF(int *val, int *ret, ossl_unused void *lock) { *ret = __atomic_fetch_sub(val, 1, __ATOMIC_RELAXED) - 1; if (*ret == 0) __atomic_thread_fence(__ATOMIC_ACQUIRE); return 1; } # else static __inline__ int QAT_CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { *ret = __atomic_fetch_add(&refcnt->val, 1, __ATOMIC_RELAXED) + 1; return 1; } static __inline__ int QAT_CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { *ret = __atomic_fetch_sub(&refcnt->val, 1, __ATOMIC_RELAXED) - 1; if (*ret == 0) __atomic_thread_fence(__ATOMIC_ACQUIRE); return 1; } # endif # endif #endif /* E_QAT_H */ qatengine-1.9.0/fips/000077500000000000000000000000001500416242000144275ustar00rootroot00000000000000qatengine-1.9.0/fips/driver_install.sh000077500000000000000000000023221500416242000200060ustar00rootroot00000000000000#!/bin/bash # Script to install driver modules during the RPM installation set -e if ( lsmod | grep qat >/dev/null ); then echo "QAT driver already installed and removing existing modules ......." if (lsmod | grep usdm >/dev/null); then rmmod usdm_drv rmmod qat_4xxx rmmod intel_qat echo "Removed existing driver" elif (lsmod | grep intel_qat >/dev/null); then rmmod qat_4xxx rmmod intel_qat echo "Removed existing driver" fi else echo "Shutdown qat services" cd /usr/lib64/build ./qat_service shutdown fi if [ $? -ne 0 ]; then sudo insmod /usr/lib64/build/intel_qat.ko fi sudo modprobe authenc sudo modprobe mdev sudo modprobe uio cp -rf /usr/lib64/build/qat_4xxx.bin /lib/firmware/ cp -rf /usr/lib64/build/qat_4xxx_mmp.bin /lib/firmware/ echo "Installing QAT Kernel Modules" sudo insmod /usr/lib64/build/intel_qat.ko sudo insmod /usr/lib64/build/usdm_drv.ko sudo insmod /usr/lib64/build/qat_4xxx.ko for(( i=0; i< 8; i++ )) do cp -rf /usr/lib64/build/4xxx_dev0.conf /etc/4xxx_dev$i.conf done cp -rf /usr/lib64/build/4xxx_dev* /etc/ cp /usr/lib64/build/adf_ctl /usr/local/bin cp /usr/lib64/build/adf_ctl /usr/bin cd /usr/lib64/build sudo adf_ctl restart qatengine-1.9.0/fips/qatprovider-fips.spec000066400000000000000000000176141500416242000206130ustar00rootroot00000000000000%undefine __cmake_in_source_build %global _lto_cflags %{nil} %global debug_package %{nil} # Dependent Library Versions %global major 1 %global minor 3 %global rev 0 %global ipsec intel-ipsec-mb %global ipsecver %{major}.%{minor} %global ipsecfull %{ipsec}-%{ipsecver} %global fullversion %{major}.%{minor}.%{rev} %global ippcp_major 11 %global ippcp_minor 6 %global ippcp cryptography-primitives %global ippcpver ippcp_2021.7.1 %global ippcpfull %{ippcp}-%{ippcpver} %global ippcpfullversion %{ippcp_major}.%{ippcp_minor} %global qatdriver QAT20.l.1.0.40-00004 %global openssl_lib_path /root/openssl_install %global openssl_src_path /root/openssl Name: qatprovider-fips Version: 1.3.1 Release: 1%{?dist} Summary: Intel QuickAssist Technology(QAT) OpenSSL Provider License: BSD-3-Clause AND OpenSSL Source0: https://github.com/intel/QAT_Engine/archive/v%{version}/%{name}-%{version}.tar.gz Source1: https://github.com/intel/%{ippcp}/archive/refs/tags/%{ippcpver}.tar.gz#/%{ippcp}-%{ippcpver}.tar.gz Source2: https://github.com/intel/%{ipsec}/archive/v%{ipsecver}.tar.gz#/%{ipsecfull}.tar.gz Source3: https://downloadmirror.intel.com/781387/QAT20.L.1.0.40-00004.tar.gz Source4: driver_install.tar.gz BuildRequires: autoconf BuildRequires: automake BuildRequires: make BuildRequires: gcc BuildRequires: libtool BuildRequires: cmake >= 3.10 BuildRequires: nasm >= 2.14 BuildRequires: gcc-c++ >= 8.2 %description This package provides the Intel QuickAssist Technology OpenSSL Provider (an OpenSSL Plug-In Provider) which provides cryptographic acceleration for both hardware and optimized software using Intel QuickAssist Technology enabled Intel platforms. %prep %setup -b 1 %setup -b 2 %setup -b 3 %setup -b 4 %build cd %{_builddir}/%{qatdriver} unset ICP_ROOT unset ICP_BUILD_OUTPUT %configure make clean %make_build make install rm -rf /QAT/* cp -rf quickassist /QAT/ cp -rf build /QAT/ cp -rf /QAT/build/intel_qat.ko %{openssl_lib_path}/lib64/ossl-modules/ cp -rf /QAT/build/usdm_drv.ko %{openssl_lib_path}/lib64/ossl-modules/ cp -rf /QAT/build/qat_4xxx.ko %{openssl_lib_path}/lib64/ossl-modules/ cp -rf /QAT/build/qat_4xxx.bin %{openssl_lib_path}/lib64/ossl-modules/ cp -rf /QAT/build/qat_4xxx_mmp.bin %{openssl_lib_path}/lib64/ossl-modules/ cp -rf /QAT/build/libusdm_drv_s.so %{openssl_lib_path}/lib64/ossl-modules/ cp -rf /QAT/build/libqat_s.so %{openssl_lib_path}/lib64/ossl-modules/ cp -rf %{openssl_lib_path}/4xxx_dev0.conf /etc/ cp -rf %{openssl_lib_path}/4xxx_dev1.conf /etc/ adf_ctl restart cd %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb cmake . -B"build" -DOPENSSL_INCLUDE_DIR=%{openssl_src_path}/include -DOPENSSL_LIBRARIES=%{openssl_lib_path} -DOPENSSL_ROOT_DIR=%{openssl_src_path} cd build make clean make -j make install install -d %{buildroot}/%{_includedir}/crypto_mb cp -rf %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb/include/crypto_mb/*.h /%{buildroot}/%{_includedir}/crypto_mb/ install -d %{buildroot}/%{_libdir} cp %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb/build/bin/libcrypto_mb.so.%{ippcpfullversion} %{buildroot}/%{_libdir} cd %{buildroot}/%{_libdir} ln -s libcrypto_mb.so.%{ippcpfullversion} libcrypto_mb.so.%{ippcp_major} ln -s libcrypto_mb.so.%{ippcpfullversion} libcrypto_mb.so cd %{_builddir}/%{ipsecfull} cd lib make EXTRA_CFLAGS='%{optflags}' %{?_smp_mflags} install -d %{buildroot}/%{_includedir} install -m 0644 %{_builddir}/%{ipsecfull}/lib/intel-ipsec-mb.h %{buildroot}/%{_includedir} cp %{buildroot}/%{_includedir}/intel-ipsec-mb.h /usr/include/ install -s -m 0755 %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{fullversion} %{buildroot}/%{_libdir} cd %{buildroot}/%{_libdir} ln -s libIPSec_MB.so.%{fullversion} libIPSec_MB.so.%{major} ln -s libIPSec_MB.so.%{fullversion} libIPSec_MB.so export OPENSSL_ENGINES="/root/openssl_install/lib64/ossl-modules" export OPENSSL_ROOT="/root/openssl" export SYS_OPENSSL_PATH="/root/openssl_install" export LD_LIBRARY_PATH="/root/openssl_install/lib64" export OPENSSL_LIB="/root/openssl_install" export QAT_HW_ENABLED="1" export QAT_SW_ENABLED="1" cd /root/rpmbuild/BUILD/%{name}-%{version} autoreconf -ivf cp -rf %{buildroot}/%{_libdir}/libcrypto_mb.so.%{ippcpfullversion} %{openssl_lib_path}/lib64/ossl-modules/ cp -rf %{buildroot}/%{_libdir}/libcrypto_mb.so %{openssl_lib_path}/lib64/ossl-modules/ cp -rf %{buildroot}/%{_libdir}/libIPSec_MB.so.%{fullversion} %{openssl_lib_path}/lib64/ossl-modules/ cp -rf %{buildroot}/%{_libdir}/libIPSec_MB.so %{openssl_lib_path}/lib64/ossl-modules/ ./configure --with-openssl_install_dir=%{openssl_lib_path} --with-qat_hw_dir=/QAT --enable-qat_provider --enable-qat_hw_gcm --enable-qat_hw_hkdf --enable-qat_hw_sha3 --enable-qat_fips --enable-qat_sw --enable-qat_small_pkt_offload --enable-qat_insecure_algorithms --disable-qat_sw_sm2 --disable-qat_hw_ciphers make clean %make_build %make_install cp -rf %{buildroot}/%{openssl_lib_path}/lib64/ossl-modules/qatprovider.so %{openssl_lib_path}/lib64/ossl-modules/ make intkat mv %{openssl_lib_path}/lib64/ossl-modules/qatprovider.so %{buildroot}/%{openssl_lib_path}/lib64/ossl-modules/ install -d %{buildroot}/%{_libdir} install -d %{buildroot}/%{_libdir}/build cp %{_libdir}/libusdm_drv_s.so %{buildroot}/%{_libdir} cp %{_libdir}/libqat_s.so %{buildroot}/%{_libdir} cp -rf /QAT/build/qat_4xxx.bin %{buildroot}/%{_libdir}/build cp -rf /QAT/build/qat_4xxx_mmp.bin %{buildroot}/%{_libdir}/build cp -rf /QAT/build/intel_qat.ko %{buildroot}/%{_libdir}/build cp -rf /QAT/build/usdm_drv.ko %{buildroot}/%{_libdir}/build cp -rf /QAT/build/qat_4xxx.ko %{buildroot}/%{_libdir}/build cp -rf /QAT/build/4xxx_dev0.conf %{buildroot}/%{_libdir}/build cp -rf %{openssl_lib_path}/4xxx_dev0.conf %{buildroot}/%{_libdir}/build cp -rf /QAT/build/adf_ctl %{buildroot}/%{_libdir}/build cp -rf /QAT/build/qat_service %{buildroot}/%{_libdir}/build cp %{_builddir}/driver_install/driver_install.sh %{buildroot}/%{_libdir} install -d %{buildroot}/%{_libdir}/ossl-modules cp %{buildroot}/%{openssl_lib_path}/lib64/ossl-modules/qatprovider.so %{buildroot}/%{_libdir}/ossl-modules/ cp %{buildroot}/%{openssl_lib_path}/lib64/ossl-modules/qatprovider.la %{buildroot}/%{_libdir}/ossl-modules/ %post echo "RPM is getting installed" if (lspci | grep Co- >/dev/null ) then ./%{_libdir}/driver_install.sh fi %clean rm -rf %{buildroot} %files %exclude %{openssl_lib_path}/lib64/ossl-modules/ %exclude /usr/lib %defattr(-,root,root,-) %dir %attr(0755,root,root) %{openssl_lib_path}/lib64/ossl-modules/ %dir %attr(0755,root,root) /usr %{_libdir}/ossl-modules/qatprovider.so %{_libdir}/ossl-modules/qatprovider.la %{_libdir}/libusdm_drv_s.so %{_libdir}/libqat_s.so %{_libdir}/build %{_libdir}/driver_install.sh %exclude %dir %{openssl_lib_path}/lib64/ossl-modules/ %license LICENSE %{_libdir}/libcrypto_mb.so.%{ippcpfullversion} %{_libdir}/libcrypto_mb.so.%{ippcp_major} %{_libdir}/libcrypto_mb.so %{_libdir}/libIPSec_MB.so.%{fullversion} %{_libdir}/libIPSec_MB.so.%{major} %{_libdir}/libIPSec_MB.so %dir /usr/include/crypto_mb %{_includedir}/crypto_mb/cpu_features.h %{_includedir}/crypto_mb/defs.h %{_includedir}/crypto_mb/ec_nistp256.h %{_includedir}/crypto_mb/ec_nistp384.h %{_includedir}/crypto_mb/ec_nistp521.h %{_includedir}/crypto_mb/ec_sm2.h %{_includedir}/crypto_mb/ed25519.h %{_includedir}/crypto_mb/exp.h %{_includedir}/crypto_mb/rsa.h %{_includedir}/crypto_mb/sm3.h %{_includedir}/crypto_mb/sm4.h %{_includedir}/crypto_mb/status.h %{_includedir}/crypto_mb/version.h %{_includedir}/crypto_mb/x25519.h %{_includedir}/intel-ipsec-mb.h %{_includedir}/crypto_mb/sm4_ccm.h %{_includedir}/crypto_mb/sm4_gcm.h %changelog * Mon Aug 21 2023 Yogaraj Alamenda - 1.3.1-1 - Update to v1.3.1 * Wed Aug 09 2023 Yogaraj Alamenda - 1.3.0-1 - Update to v1.3.0 * Wed Jun 14 2023 Ponnam Srinivas - 1.2.0-1 - Initial Version of RPM for QAT Provider with FIPS Support. qatengine-1.9.0/fips_install.sh000077500000000000000000000064541500416242000165250ustar00rootroot00000000000000#!/bin/sh ./autogen.sh if [ "$QAT_HW_ENABLED" = "1" ] && [ "$QAT_SW_ENABLED" = "1" ] then cp -f /usr/lib64/build/qat_4xxx.ko $OPENSSL_ENGINES/ cp -f /usr/lib64/build/usdm_drv.ko $OPENSSL_ENGINES/ cp -f /usr/lib64/build/intel_qat.ko $OPENSSL_ENGINES/ cp -f /usr/lib64/libusdm_drv_s.so $OPENSSL_ENGINES/ cp -f /usr/lib64/libqat_s.so $OPENSSL_ENGINES/ cp -f /lib/firmware/qat_4xxx.bin $OPENSSL_ENGINES/ cp -f /lib/firmware/qat_4xxx_mmp.bin $OPENSSL_ENGINES/ cp -f /usr/lib64/libIPSec_MB.so $OPENSSL_ENGINES/ cp -f /usr/lib64/libcrypto_mb.so $OPENSSL_ENGINES/ ./configure --with-qat_hw_dir=$ICP_ROOT --with-openssl_install_dir=$OPENSSL_LIB --enable-qat_sw --enable-qat_provider --enable-qat_hw_sha3 --enable-qat_hw_gcm --enable-qat_hw_hkdf --enable-qat_fips --enable-qat_insecure_algorithms --disable-qat_sw_sm2 --disable-qat_hw_ciphers make clean make -j 30 make install make intkat cp -f $OPENSSL_ENGINES/qatprovider.so /usr/lib64/ossl-modules/ echo "==================================================================================" echo "* Note: * Before running the script, Please ensure below files are available in below paths. * If not, Please Copy them Manually. * qat_4xxx.ko, usdm_drv.ko, intel_qat.ko files to '/usr/lib64/build/' * qat_4xxx.bin, qat_4xxx_mmp.bin to '/lib/firmware/' * libusdm_drv_s.so, libqat_s.so, libIPSec_MB.so, libcrypto_mb.so files to '/usr/lib64/' * export 'SYS_OPENSSL_PATH' as openssl install path which contains bin. * eg. SYS_OPENSSL_PATH=/root/openssl_install/ " else if [ "$QAT_HW_ENABLED" = "1" ] then cp -f /usr/lib64/build/qat_4xxx.ko $OPENSSL_ENGINES/ cp -f /usr/lib64/build/usdm_drv.ko $OPENSSL_ENGINES/ cp -f /usr/lib64/build/intel_qat.ko $OPENSSL_ENGINES/ cp -f /usr/lib64/libusdm_drv_s.so $OPENSSL_ENGINES/ cp -f /usr/lib64/libqat_s.so $OPENSSL_ENGINES/ cp -f /lib/firmware/qat_4xxx.bin $OPENSSL_ENGINES/ cp -f /lib/firmware/qat_4xxx_mmp.bin $OPENSSL_ENGINES/ ./configure --with-qat_hw_dir=$ICP_ROOT --with-openssl_install_dir=$OPENSSL_LIB --enable-qat_provider --enable-qat_hw_sha3 --enable-qat_hw_gcm --enable-qat_hw_hkdf --enable-qat_fips --enable-qat_insecure_algorithms --disable-qat_hw_ciphers else cp -f /usr/lib64/libIPSec_MB.so $OPENSSL_ENGINES/ cp -f /usr/lib64/libcrypto_mb.so $OPENSSL_ENGINES/ ./configure --with-openssl_install_dir=$OPENSSL_LIB --enable-qat_sw --enable-qat_provider --enable-qat_fips --disable-qat_sw_sm2 fi make clean make -j 30 make install make intkat cp -f $OPENSSL_ENGINES/qatprovider.so /usr/lib64/ossl-modules/ echo "==================================================================================" if [ "$QAT_HW_ENABLED" = "1" ] then echo "* Note: * Before running the script, Please ensure below files are available in below paths. * If not, Please Copy them Manually. * qat_4xxx.ko, usdm_drv.ko, intel_qat.ko files to '/usr/lib64/build/' * libusdm_drv_s.so, libqat_s.so to '/usr/lib64/' * qat_4xxx.bin, qat_4xxx_mmp.bin to '/lib/firmware/' * export 'SYS_OPENSSL_PATH' as openssl install path which contains bin. * eg. SYS_OPENSSL_PATH=/root/openssl_install/ " else echo "* Note: * Before running the script, Please ensure below files are available in below path. * If not, Please Copy them Manually. * libIPSec_MB.so, libcrypto_mb.so files to '/usr/lib64/' * export 'SYS_OPENSSL_PATH' as openssl install path which contains bin. * eg. SYS_OPENSSL_PATH=/root/openssl_install/ " fi fi qatengine-1.9.0/intkat.sh000077500000000000000000000153431500416242000153250ustar00rootroot00000000000000#!/bin/sh $SYS_OPENSSL_PATH/bin/openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem if [ "$QAT_HW_ENABLED" = "1" ] && [ "$QAT_SW_ENABLED" = "1" ] then $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/qatprovider.so &> qat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/intel_qat.ko &> intel_qat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/libusdm_drv_s.so &> usdm_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/libqat_s.so &> libqat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/qat_4xxx.ko &> qat_4xxx_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/usdm_drv.ko &> usdm_drv_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/qat_4xxx.bin &> qat_4xxx_bin_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/qat_4xxx_mmp.bin &> qat_4xxx_mmp_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/libIPSec_MB.so &> ipsec_mb_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/libcrypto_mb.so &> libcrypto_mb_signature.bin $SYS_OPENSSL_PATH/bin/openssl ec -in private-key.pem -text -noout &> ec_key.txt sed -n 7,14p ec_key.txt &> pub_key.txt objcopy --add-section .qat_sig=qat_signature.bin --set-section-flags .qat_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .iqat_sig=intel_qat_signature.bin --set-section-flags .iqat_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .usdm_sig=usdm_signature.bin --set-section-flags .usdm_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .libqat_sig=libqat_signature.bin --set-section-flags .libqat_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .qat_4xxx_sig=qat_4xxx_signature.bin --set-section-flags .qat_4xxx_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .usdm_drv_sig=usdm_drv_signature.bin --set-section-flags .usdm_drv_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .qat_4xxx_bin_sig=qat_4xxx_bin_signature.bin --set-section-flags .qat_4xxx_bin_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .qat_4xxx_mmp_sig=qat_4xxx_mmp_signature.bin --set-section-flags .qat_4xxx_mmp_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .ipsec_mb_sig=ipsec_mb_signature.bin --set-section-flags .ipsec_mb_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .libcrypto_mb_sig=libcrypto_mb_signature.bin --set-section-flags .libcrypto_mb_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .pub_key=pub_key.txt --set-section-flags .pub_key=noload,readonly $OPENSSL_ENGINES/qatprovider.so rm -f qat_signature.bin rm -f intel_qat_signature.bin rm -f usdm_signature.bin rm -f libqat_signature.bin rm -f qat_4xxx_signature.bin rm -f usdm_drv_signature.bin rm -f qat_4xxx_bin_signature.bin rm -f qat_4xxx_mmp_signature.bin rm -f ipsec_mb_signature.bin rm -f libcrypto_mb_signature.bin rm -f pub_key.txt rm -f ec_key.txt rm -f private-key.pem else if [ "$QAT_HW_ENABLED" = "1" ] then $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/qatprovider.so &> qat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/intel_qat.ko &> intel_qat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/libusdm_drv_s.so &> usdm_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/libqat_s.so &> libqat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/qat_4xxx.ko &> qat_4xxx_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/usdm_drv.ko &> usdm_drv_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/qat_4xxx.bin &> qat_4xxx_bin_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha3-256 -sign private-key.pem $OPENSSL_ENGINES/qat_4xxx_mmp.bin &> qat_4xxx_mmp_signature.bin else $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/qatprovider.so &> qat_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/libIPSec_MB.so &> ipsec_mb_signature.bin $SYS_OPENSSL_PATH/bin/openssl dgst -sha256 -sign private-key.pem $OPENSSL_ENGINES/libcrypto_mb.so &> libcrypto_mb_signature.bin fi $SYS_OPENSSL_PATH/bin/openssl ec -in private-key.pem -text -noout &> ec_key.txt sed -n 7,14p ec_key.txt &> pub_key.txt objcopy --add-section .qat_sig=qat_signature.bin --set-section-flags .qat_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so if [ "$QAT_HW_ENABLED" = "1" ] then objcopy --add-section .iqat_sig=intel_qat_signature.bin --set-section-flags .iqat_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .usdm_sig=usdm_signature.bin --set-section-flags .usdm_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .libqat_sig=libqat_signature.bin --set-section-flags .libqat_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .qat_4xxx_sig=qat_4xxx_signature.bin --set-section-flags .qat_4xxx_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .usdm_drv_sig=usdm_drv_signature.bin --set-section-flags .usdm_drv_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .qat_4xxx_bin_sig=qat_4xxx_bin_signature.bin --set-section-flags .qat_4xxx_bin_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .qat_4xxx_mmp_sig=qat_4xxx_mmp_signature.bin --set-section-flags .qat_4xxx_mmp_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so else objcopy --add-section .ipsec_mb_sig=ipsec_mb_signature.bin --set-section-flags .ipsec_mb_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so objcopy --add-section .libcrypto_mb_sig=libcrypto_mb_signature.bin --set-section-flags .libcrypto_mb_sig=noload,readonly $OPENSSL_ENGINES/qatprovider.so fi objcopy --add-section .pub_key=pub_key.txt --set-section-flags .pub_key=noload,readonly $OPENSSL_ENGINES/qatprovider.so rm -f qat_signature.bin if [ "$QAT_HW_ENABLED" = "1" ] then rm -f intel_qat_signature.bin rm -f usdm_signature.bin rm -f libqat_signature.bin rm -f qat_4xxx_signature.bin rm -f usdm_drv_signature.bin rm -f qat_4xxx_bin_signature.bin rm -f qat_4xxx_mmp_signature.bin else rm -f ipsec_mb_signature.bin rm -f libcrypto_mb_signature.bin fi rm -f pub_key.txt rm -f ec_key.txt rm -f private-key.pem fi qatengine-1.9.0/kpt/000077500000000000000000000000001500416242000142645ustar00rootroot00000000000000qatengine-1.9.0/kpt/apps/000077500000000000000000000000001500416242000152275ustar00rootroot00000000000000qatengine-1.9.0/kpt/apps/kpt_dev_pp.c000066400000000000000000000273471500416242000175430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include "cpa.h" #include "cpa_cy_kpt.h" #include "cpa_cy_im.h" #include "icp_sal_user.h" #include "icp_sal_poll.h" #include "qae_mem.h" #include "include/qae_mem_utils.h" #include "kpt_dev_pp.h" #define DEVCREDENTIAL_PUBKET_MODN (384) #define DEVCREDENTIAL_PUBKET_MODE (8) #ifndef BYTE_ALIGNMENT_64 #define BYTE_ALIGNMENT_64 (64) #endif #define QAT_MAX_CRYPTO_INSTANCES (256) #define QAT_MAX_CRYPTO_ACCELERATORS (512) typedef struct { CpaInstanceInfo2 qat_instance_info; unsigned int qat_instance_started; } qat_instance_details_t; typedef struct { unsigned int qat_accel_present; unsigned int qat_accel_reset_status; } qat_accel_details_t; static pthread_t gPollingThread; static int gPollingCy = 0; kpt_per_part_context kpt_per_part_context_ptr[MAX_SOCKET] = {{{0}}}; int cpu_socket_num = 0; static void hex_log(Cpa8U *pData, Cpa32U numBytes, const char* caption) { int i = 0; if (NULL == pData) { return; } if (caption != NULL) { log_print("\n=== %s ===\n", caption); } for (i = 0; i < numBytes; i++) { log_print("%02X ", pData[i]); if (!((i + 1) % 16)) { log_print("\n"); } } log_print("\n"); } const char *log_level_str(int level) { const char *level_str; switch (level) { case LOG_ERR: level_str = "ERR"; break; case LOG_DEBUG: level_str = "DEBUG"; break; default: level_str = "UNKNOW"; break; }; return level_str; } int xlog(int level, const char *fmt, ...) { char out_buff[256] = {0}; int nsize; const char *level_str = NULL; va_list ap; va_start(ap, fmt); nsize = vsnprintf(out_buff, sizeof(out_buff) -1, fmt, ap); va_end(ap); if (nsize > 0) { if (level == LOG_PRINT) { return printf("%s", out_buff); } else { level_str = log_level_str(level); return printf("[%s] %s\n", level_str, out_buff); } } return -1; } /* * This function polls a crypto instance. * */ void *sal_polling(CpaInstanceHandle cyInstHandle) { gPollingCy = 1; while (gPollingCy) { icp_sal_CyPollInstance(cyInstHandle, 0); } pthread_join(gPollingThread, NULL); } /* * This function checks the instance info. If the instance is * required to be polled then it starts a polling thread. */ void kptCyStartPolling(CpaInstanceHandle cyInstHandle) { CpaInstanceInfo2 info2 = {0}; CpaStatus status = CPA_STATUS_SUCCESS; status = cpaCyInstanceGetInfo2(cyInstHandle, &info2); if ((status == CPA_STATUS_SUCCESS) && (info2.isPolled == CPA_TRUE)) { /* Start thread to poll instance */ pthread_create(&gPollingThread, NULL, sal_polling, cyInstHandle); } } /* * This function stops the polling of a crypto instance. */ void kptCyStopPolling(void) { gPollingCy = 0; } static void copy_per_part_context(CpaCyKptValidationKey *DevCredential) { memcpy(kpt_per_part_context_ptr[cpu_socket_num].sig, \ DevCredential->signature, \ KPT_PER_PART_SIG_LEN); kpt_per_part_context_ptr[cpu_socket_num].len_sig = KPT_PER_PART_SIG_LEN; memcpy(kpt_per_part_context_ptr[cpu_socket_num].pub_n, \ DevCredential->publicKey.modulusN.pData, \ DevCredential->publicKey.modulusN.dataLenInBytes); kpt_per_part_context_ptr[cpu_socket_num].len_pub_n = KPT_PER_PART_KEY_N_LEN; memcpy(kpt_per_part_context_ptr[cpu_socket_num].pub_e, \ DevCredential->publicKey.publicExponentE.pData, \ DevCredential->publicKey.publicExponentE.dataLenInBytes); kpt_per_part_context_ptr[cpu_socket_num].len_pub_e = KPT_PER_PART_KEY_E_LEN; cpu_socket_num++; } static int lookup_and_store(CpaCyKptValidationKey *DevCredential) { int ret = 0; int i = 0; if (!cpu_socket_num) { copy_per_part_context(DevCredential); return cpu_socket_num; } for (; i < cpu_socket_num; i++){ /* return if the same signature */ ret = memcmp(DevCredential->signature, \ kpt_per_part_context_ptr[i].sig, \ KPT_PER_PART_SIG_LEN); if (!ret) { return 0; } } copy_per_part_context(DevCredential); return cpu_socket_num; } static CpaStatus kpt_get_op_perform(int instNum, CpaInstanceHandle cyInstHandle) { CpaStatus status = CPA_STATUS_SUCCESS; CpaCyKptKeyManagementStatus kptStatus = CPA_CY_KPT_SUCCESS; Cpa32U node = 0; CpaInstanceInfo2 instanceInfo2; CpaCyKptValidationKey DevCredential; status = cpaCyInstanceGetInfo2(cyInstHandle, &instanceInfo2); if (status == CPA_STATUS_SUCCESS) { node = instanceInfo2.nodeAffinity; } else { return status; } DevCredential.publicKey.modulusN.pData = (Cpa8U *) qaeMemAllocNUMA(DEVCREDENTIAL_PUBKET_MODN, node, BYTE_ALIGNMENT_64); if (NULL == DevCredential.publicKey.modulusN.pData) { return CPA_STATUS_RESOURCE; } DevCredential.publicKey.modulusN.dataLenInBytes = DEVCREDENTIAL_PUBKET_MODN; DevCredential.publicKey.publicExponentE.pData = (Cpa8U *) qaeMemAllocNUMA(DEVCREDENTIAL_PUBKET_MODE, node, BYTE_ALIGNMENT_64); if (NULL == DevCredential.publicKey.publicExponentE.pData) { return CPA_STATUS_RESOURCE; } DevCredential.publicKey.publicExponentE.dataLenInBytes = DEVCREDENTIAL_PUBKET_MODE; status = cpaCyKptQueryDeviceCredentials(cyInstHandle, &DevCredential, &kptStatus); if (lookup_and_store(&DevCredential)) { log_print("-->Found new per-part key, total number: %d\n", cpu_socket_num); } return status; } int kpt_get_per_part_key(void) { CpaStatus status = CPA_STATUS_SUCCESS; Cpa16U qat_num_instances = 0; CpaInstanceHandle *qat_instance_handles = NULL; int instNum = 0; qat_instance_details_t qat_instance_details[QAT_MAX_CRYPTO_INSTANCES] = {{{0}}}; Cpa16U package_id = 0; CpaCyCapabilitiesInfo CapInfo; status = qaeMemInit(); if (CPA_STATUS_SUCCESS != status) { log_err("Failed to initialise memory driver\n"); return (int)status; } status = icp_sal_userStartMultiProcess("SHIM", CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { log_err("Failed to start user process SHIM\n"); qaeMemDestroy(); return (int)status; } /* Get the number of available instances */ status = cpaCyGetNumInstances(&qat_num_instances); if (CPA_STATUS_SUCCESS != status) { log_err("cpaCyGetNumInstances failed, status=%d\n", status); return (int)status; } if (!qat_num_instances) { log_err("No crypto instances found\n"); return -1; } printf("Found %d Cy instances\n", qat_num_instances); /* Allocate memory for the instance handle array */ qat_instance_handles = (CpaInstanceHandle *) malloc(((int)qat_num_instances) * sizeof(CpaInstanceHandle)); memset(qat_instance_handles, 0, ((int)qat_num_instances) * sizeof(CpaInstanceHandle)); /* Get the Cy instances */ status = cpaCyGetInstances(qat_num_instances, qat_instance_handles); if (CPA_STATUS_SUCCESS != status) { log_err("cpaCyGetInstances failed, status=%d\n", status); return (int)status; } /* Set translation function and start each instance */ for (instNum = 0; instNum < qat_num_instances; instNum++) { /* Retrieve CpaInstanceInfo2 structure for that instance */ status = cpaCyInstanceGetInfo2(qat_instance_handles[instNum], &qat_instance_details[instNum].qat_instance_info); if (CPA_STATUS_SUCCESS != status ) { log_err("cpaCyInstanceGetInfo2 failed. status = %d\n", status); return (int)status; } status = cpaCyQueryCapabilities(qat_instance_handles[instNum], &CapInfo); if (CPA_STATUS_SUCCESS != status ) { log_err("cpaCyQueryCapabilities failed. status = %d\n", status); return (int)status; } if ( CPA_FALSE == CapInfo.kptSupported || CPA_TRUE == CapInfo.symSupported) { log_print("Skiped Instance No: %d Located on Device: %d" "(non-kpt or sym instance)\n", instNum, package_id); qat_instance_details[instNum].qat_instance_started = 0; continue; } package_id = qat_instance_details[instNum].qat_instance_info.physInstId.packageId; /* Set the address translation function */ status = cpaCySetAddressTranslation(qat_instance_handles[instNum], qaeVirtToPhysNUMA); if (CPA_STATUS_SUCCESS != status) { log_err("cpaCySetAddressTranslation failed, status=%d\n", status); return (int)status; } /* Start the instances */ status = cpaCyStartInstance(qat_instance_handles[instNum]); if (CPA_STATUS_SUCCESS != status) { log_err("cpaCyStartInstance failed, status=%d\n", status); return (int)status; } qat_instance_details[instNum].qat_instance_started = 1; log_print("Started Instance No: %d Located on Device: %d\n", instNum, package_id); kptCyStartPolling(qat_instance_handles[instNum]); if (CPA_STATUS_SUCCESS != status) return (int)status; status = kpt_get_op_perform(instNum, qat_instance_handles[instNum]); kptCyStopPolling(); if (qat_instance_details[instNum].qat_instance_started) { status = cpaCyStopInstance(qat_instance_handles[instNum]); if (CPA_STATUS_SUCCESS != status) { log_err("cpaCyStopInstance failed, status=%d\n", status); } qat_instance_details[instNum].qat_instance_started = 0; } } free(qat_instance_handles); icp_sal_userStop(); qaeMemDestroy(); return (int)status; } qatengine-1.9.0/kpt/apps/kpt_dev_pp.h000066400000000000000000000053551500416242000175430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #ifndef __KPT_DEV_PP_H__ #define __KPT_DEV_PP_H__ #include #include #include #define MAX_SOCKET (32) #define KPT_PER_PART_KEY_N_LEN (384) #define KPT_PER_PART_KEY_E_LEN (8) #define KPT_PER_PART_SIG_LEN (384) typedef struct { unsigned char pub_n[KPT_PER_PART_KEY_N_LEN]; int len_pub_n; unsigned char pub_e[KPT_PER_PART_KEY_E_LEN]; int len_pub_e; unsigned char sig[KPT_PER_PART_SIG_LEN]; int len_sig; } kpt_per_part_context; extern kpt_per_part_context kpt_per_part_context_ptr[MAX_SOCKET]; extern int cpu_socket_num; extern int kpt_get_per_part_key(void); enum log_level { LOG_ERR = 0, LOG_DEBUG, LOG_PRINT }; const char *log_level_str(int level); int xlog(int level, const char *fmt, ...); #define log_err(fmt, ...) xlog(LOG_ERR, fmt, ##__VA_ARGS__) #define log_debug(fmt, ...) xlog(LOG_DEBUG, fmt, ##__VA_ARGS__) #define log_print(fmt, ...) xlog(LOG_PRINT, fmt, ##__VA_ARGS__) #endif qatengine-1.9.0/kpt/apps/kpt_ecc_key.c000066400000000000000000000345511500416242000176630ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /************************KPT ECC PRIVATE KEY ASN.1 Coding Format*************** * * Intel_KPT_ECC_KEY DEFINITIONS AUTOMATIC TAGS ::= BEGIN * KPTECCKEY ::= SEQUENCE { * version INTEGER { kptECCKeyVersion(1) } (kptECCKeyVersion), * privateKey OCTET STRING, --(xg||yg||n||q||a||b||d)'||Auth * curveName [0] OBJECT IDENTIFIER OPTIONAL, * publicKey [1] BIT STRING OPTIONAL, * wrappingMetadata metadata * } * * metadata ::= SEQUENCE { * aesNonce OCTET STRING (SIZE(12)), * wrappingAlg OBJECT IDENTIFIER ( id-aes256-GCM ), * encryptedSWK eSWKs * } * * eSWKs ::= SEQUENCE OF eSWK * * eSWK ::= SEQUENCE { * devSig OCTET STRING, * secSWK OCTET STRING * } * * id-aes256-GCM OBJECT IDENTIFIER ::= { aes 46 } * * id-aes-gcm OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) * organization(1) gov(101) csor(3) * nistAlgorithm(4) 1 } * END * **************************************************************************/ #include #include #include #include "kpt_key.h" #include "kpt_swk.h" #include "kpt_dev_pp.h" #define KPT_ECC_KEY_VERSION (0x1) #define EC_SIZE_BYTES_P256 (32) #define EC_SIZE_BYTES_P384 (48) #define EC_SIZE_BYTES_P521 (72) #define EC_SIZE_BYTES_QW4 (32) #define EC_SIZE_BYTES_QW8 (64) #define EC_SIZE_BYTES_QW9 (72) #define KPT_ECDSA_P256_AAD_LEN (10) #define KPT_ECDSA_P384_AAD_LEN (7) #define KPT_ECDSA_P521_AAD_LEN (7) typedef struct kpt_ecc_key_st { long version; ASN1_OCTET_STRING *privateKey; ASN1_OBJECT *curveName; ASN1_BIT_STRING *publicKey; WRAPPINGMETADATA *wrappingMetadata; } KPTECCKEY; DECLARE_ASN1_FUNCTIONS(KPTECCKEY) ASN1_SEQUENCE(KPTECCKEY) = { ASN1_SIMPLE(KPTECCKEY, version, LONG), ASN1_SIMPLE(KPTECCKEY, privateKey, ASN1_OCTET_STRING), ASN1_EXP_OPT(KPTECCKEY, curveName, ASN1_OBJECT, 0), ASN1_EXP_OPT(KPTECCKEY, publicKey, ASN1_BIT_STRING, 1), ASN1_SIMPLE(KPTECCKEY, wrappingMetadata, WRAPPINGMETADATA) }ASN1_SEQUENCE_END(KPTECCKEY) IMPLEMENT_ASN1_FUNCTIONS(KPTECCKEY) /** ***************************************************************************** * Curve OID DER(OID) * secp256r1 1.2.840.10045.3.1.7 06 08 2A 86 48 CE 3D 03 01 07 * secp384r1 1.3.132.0.34 06 05 2B 81 04 00 22 * secp521r1 1.3.132.0.35 06 05 2B 81 04 00 23 *****************************************************************************/ #define NID_SECP256R1 415 #define NID_SECP384R1 715 #define NID_SECP521R1 716 static unsigned char secp256_oid[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }; static unsigned char secp384_oid[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22 }; static unsigned char secp521_oid[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23 }; /* EC Key in ECDSA needs to be 8-bytes aligned */ static int ecc_get_key_size(int len_d) { if (len_d <= EC_SIZE_BYTES_P256) len_d = EC_SIZE_BYTES_P256; else if (len_d <= EC_SIZE_BYTES_P384) len_d = EC_SIZE_BYTES_P384; else if (len_d <= EC_SIZE_BYTES_P521) len_d = EC_SIZE_BYTES_P521; else len_d = -1; return len_d; } static void hex_log(unsigned char *pData, unsigned int numBytes, const char* caption) { int i = 0; if (NULL == pData) { return; } if (caption != NULL) { log_print("\n=== %s ===\n", caption); } for (i = 0; i < numBytes; i++) { log_print("%02X ", pData[i]); if (!((i + 1) % 16)) log_print("\n"); } log_print("\n"); } static int eckey_get_private_key(EC_KEY *eckey, unsigned char *buf_k, int *len_key) { const BIGNUM *bn_d = NULL; unsigned char *buf_d = NULL; int len_d = 0, ret = -1; int key_size = 0; if (NULL == eckey || NULL == buf_k) { goto err; } if ((bn_d = EC_KEY_get0_private_key(eckey)) == NULL) { goto err; } len_d = (unsigned int) BN_num_bytes(bn_d); if ((buf_d = malloc(len_d)) == NULL) { goto err; } if (BN_bn2bin(bn_d, buf_d) == -1) { goto err; } /* Key size needs to be 8-bytes aligned */ key_size = ecc_get_key_size(len_d); *len_key = key_size; /* KPT WPK only needs private d field */ memcpy(buf_k + key_size - len_d, buf_d, len_d); ret = 0; err: if (buf_d) { free(buf_d); } return ret; } static unsigned char * ecc_get_aad(int nid, int *aad_len){ unsigned char *aad = NULL; switch (nid){ case NID_SECP256R1: { aad = secp256_oid; *aad_len = KPT_ECDSA_P256_AAD_LEN; break; } case NID_SECP384R1: { aad = secp384_oid; *aad_len = KPT_ECDSA_P384_AAD_LEN; break; } case NID_SECP521R1: { aad = secp521_oid; *aad_len = KPT_ECDSA_P521_AAD_LEN; break; } default: { log_print("Unknown ECC curve\n"); } break; } return aad; } int kpt_ecc_wpk_gen(unsigned char *cpk_file, unsigned char *wpk_file) { EC_KEY *eckey = NULL; const EC_GROUP *group; const BIGNUM *cofactor = NULL; BIO *in = NULL, *out = NULL; KPTECCKEY *key = NULL; EC_POINT *pub_key = NULL; ASN1_OBJECT *enc_algo_id = NULL; ESWK *eSWK = NULL; int pub_len = 0; unsigned char *pub = NULL; WRAPPINGMETADATA *metadata = NULL; unsigned char ck[MAX_ECC_KEY_SIZE]; unsigned char pk[MAX_ECC_KEY_SIZE]; unsigned char swk[AES_GCM_256_KEY_SIZE]; unsigned char *iv = NULL, *epk = NULL, *dev_sig = NULL, *eswk = NULL; unsigned char *aad; int aad_len = 0; memset(ck, 0, MAX_ECC_KEY_SIZE); memset(pk, 0, MAX_ECC_KEY_SIZE); int ck_len = 0, pk_len = 0; int nid = 0; int ret = 0, i = 0; iv = OPENSSL_malloc(AES_GCM_IV_SIZE); if (!iv) { goto err; } in = BIO_new(BIO_s_file()); if (BIO_read_filename(in, cpk_file) <= 0) { goto err; } eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (NULL == eckey) { goto err; } group = EC_KEY_get0_group(eckey); if (NULL == group) { goto err; } /* Get Private Key */ eckey_get_private_key(eckey, ck, &ck_len); hex_log(ck, ck_len, "ck"); /* Get SWK and IV */ RAND_bytes(iv, AES_GCM_IV_SIZE); RAND_bytes(swk, sizeof(swk)); hex_log(swk, sizeof(swk), "swk"); hex_log(iv, AES_GCM_IV_SIZE, "iv"); /* Get AAD */ nid = EC_GROUP_get_curve_name(group); if (!(aad = ecc_get_aad(nid, &aad_len))) { goto err; } hex_log(aad, aad_len, "aad"); /* Wrap Private Key with SWK */ ret = wrap_key_with_gcm256(ck, ck_len, pk, &pk_len, swk, iv, AES_GCM_IV_SIZE, aad, aad_len); if (ret) { goto err; } hex_log(pk, pk_len,"wrapped ecc key"); log_print("wpk length %d\n\n", pk_len); key = KPTECCKEY_new(); if (!key) { goto err; } metadata = key->wrappingMetadata; if (NULL == metadata) { goto err; } enc_algo_id = OBJ_txt2obj("aes-256-gcm", 0); metadata->wrappingAlg = enc_algo_id; ASN1_STRING_set0(metadata->aesNonce, iv, AES_GCM_IV_SIZE); /* Generate eSWK sequence */ /* get instance->query per-part key */ ret = kpt_get_per_part_key(); if (ret) { goto err; } for (i = 0; i < cpu_socket_num; i++){ eSWK = ESWK_new(); eswk = OPENSSL_zalloc(KPT_PER_PART_KEY_N_LEN); if (!eswk) { goto err; } dev_sig = OPENSSL_zalloc(KPT_PER_PART_SIG_LEN); if (!dev_sig) { goto err; } hex_log(kpt_per_part_context_ptr[i].pub_n, KPT_PER_PART_KEY_N_LEN, "Per Part key N:"); hex_log(kpt_per_part_context_ptr[i].pub_e, KPT_PER_PART_KEY_E_LEN, "Per Part key E"); hex_log(kpt_per_part_context_ptr[i].sig, KPT_PER_PART_SIG_LEN, "signature"); ret = encrypt_swk_with_per_part_key(swk, eswk, \ kpt_per_part_context_ptr[i].pub_n, \ kpt_per_part_context_ptr[i].len_pub_n, \ kpt_per_part_context_ptr[i].pub_e, \ kpt_per_part_context_ptr[i].len_pub_e); if (!ret) { goto err; } hex_log(eswk, KPT_PER_PART_KEY_N_LEN, "Encrypted SWK of KPT2"); memcpy(dev_sig, kpt_per_part_context_ptr[i].sig, \ kpt_per_part_context_ptr[i].len_sig); ASN1_STRING_set0(eSWK->secSWK, eswk, KPT_PER_PART_KEY_N_LEN); ASN1_STRING_set0(eSWK->devSig, dev_sig, KPT_PER_PART_SIG_LEN); sk_ESWK_push(metadata->eSWKs, eSWK); log_print("The eswk counter is %d \n", sk_ESWK_num(metadata->eSWKs)); } key->version = (long)KPT_ECC_KEY_VERSION; epk = OPENSSL_malloc(pk_len); if (!epk) { goto err; } memcpy(epk, pk, pk_len); ASN1_STRING_set0(key->privateKey, epk, pk_len); key->curveName = OBJ_nid2obj(EC_GROUP_get_curve_name(group)); pub_key = (EC_POINT *)EC_KEY_get0_public_key(eckey); if (pub_key) { key->publicKey = ASN1_BIT_STRING_new(); if (!key->publicKey) { goto err; } key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; pub_len = EC_KEY_key2buf(eckey, EC_KEY_get_conv_form(eckey), &pub, NULL); ASN1_STRING_set0(key->publicKey, pub, pub_len); } out = BIO_new(BIO_s_file()); if (NULL == out) { goto err; } BIO_write_filename(out, wpk_file); PEM_ASN1_write_bio((i2d_of_void *)i2d_KPTECCKEY, "KPT ECC KEY", out, key, NULL, NULL, 0, NULL, NULL); BIO_flush(out); BIO_free(out); err: if (eckey) EC_KEY_free(eckey); if (key) KPTECCKEY_free(key); if (iv) OPENSSL_free(iv); return ret; } int kpt_ecc_wpk_parse(kpt_ecc_wpk *ecc_wpk, unsigned char *wpk_file) { KPTECCKEY *kpteckey = NULL; BIO *in = NULL; char *name = NULL, *header = NULL; unsigned char *data = 0; const unsigned char *p = NULL; long version = 0; long len; int ret = 0, i = 0; unsigned char eswk[KPT_PER_PART_KEY_N_LEN] ; WRAPPINGMETADATA *metadata = NULL; in = BIO_new(BIO_s_file()); if (BIO_read_filename(in, wpk_file) <= 0) { goto err; } ret = PEM_read_bio(in, &name, &header, &data, &len); p = data; d2i_KPTECCKEY(&kpteckey, &p, len); if (!kpteckey) { goto err; } ecc_wpk->version = kpteckey->version; ecc_wpk->wpk_size = ASN1_STRING_length(kpteckey->privateKey); memcpy(ecc_wpk->wpk, ASN1_STRING_get0_data(kpteckey->privateKey), ecc_wpk->wpk_size); metadata = kpteckey->wrappingMetadata; ecc_wpk->wrapping_alg_nid = OBJ_obj2nid(metadata->wrappingAlg); for (i = 0; i < sk_ESWK_num(metadata->eSWKs); i++ ) { ESWK *eSWK = sk_ESWK_value(metadata->eSWKs, i); (ecc_wpk->swkSec_size)[i] = ASN1_STRING_length(eSWK->secSWK); memcpy((ecc_wpk->swkSec)[i], ASN1_STRING_get0_data(eSWK->secSWK), (ecc_wpk->swkSec_size)[i]); (ecc_wpk->swkPub_size)[i] = ASN1_STRING_length(eSWK->devSig); memcpy((ecc_wpk->swkPub)[i], ASN1_STRING_get0_data(eSWK->devSig), (ecc_wpk->swkPub_size)[i]); } ecc_wpk->curve_nid = OBJ_obj2nid(kpteckey->curveName); ecc_wpk->pub_key_size = ASN1_STRING_length(kpteckey->publicKey); memcpy(ecc_wpk->pub_key, ASN1_STRING_get0_data(kpteckey->publicKey), ecc_wpk->pub_key_size); log_print("\n=========================\n"); log_print("WPK version: %ld\n", ecc_wpk->version); hex_log(ecc_wpk->wpk, ecc_wpk->wpk_size, "EC WPK"); log_print("EC Curve NID: %d\n", ecc_wpk->curve_nid); hex_log(ecc_wpk->pub_key, ecc_wpk->pub_key_size, "EC Public Key"); hex_log((unsigned char *)ASN1_STRING_get0_data(metadata->aesNonce), ASN1_STRING_length(metadata->aesNonce), "IV"); log_print("\nWrapping Algorithm NID: %d\n", ecc_wpk->wrapping_alg_nid); for (i = 0; i < sk_ESWK_num(metadata->eSWKs); i++ ) { log_print("\nESWK %d\n", i); hex_log((ecc_wpk->swkSec)[i], (ecc_wpk->swkSec_size)[i], "Sec SWK"); hex_log((ecc_wpk->swkPub)[i], (ecc_wpk->swkPub_size)[i], "Dev sig"); } log_print("=========================\n\n"); err: if (kpteckey) { KPTECCKEY_free(kpteckey); } return ret; } qatengine-1.9.0/kpt/apps/kpt_key.h000066400000000000000000000067331500416242000170570ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #ifndef __KPT_KEY_H__ #define __KPT_KEY_H__ #define MAX_ECC_KEY_SIZE (1024) #define MAX_ESWK_SIZE (512) #define MAX_KPT_RSA_KEY_TYPE1_SIZE (2064) #define MAX_KPT_RSA_KEY_TYPE2_SIZE (3600) #define MAX_KPT_RSA_KEY_N_SIZE (1024) #define MAX_KPT_RSA_KEY_E_SIZE (1024) #define MAX_CPU_SOCKET (32) typedef enum kpt_gen_s { KPT_GEN1 = 1, KPT_GEN2 } kpt_gen_t; typedef struct kpt_ecc_wpk_st { long version; unsigned char swkSec[MAX_CPU_SOCKET][MAX_ESWK_SIZE]; unsigned char swkPub[MAX_CPU_SOCKET][MAX_ESWK_SIZE]; unsigned char wpk[MAX_ECC_KEY_SIZE]; unsigned char pub_key[MAX_ECC_KEY_SIZE]; int swkSec_size[MAX_CPU_SOCKET]; int swkPub_size[MAX_CPU_SOCKET]; int wpk_size; int pub_key_size; int curve_nid; /* optional NID for named curve */ int wrapping_alg_nid; } kpt_ecc_wpk; typedef struct kpt_rsa_wpk_st { long version; long size; unsigned char swkSec[MAX_CPU_SOCKET][MAX_ESWK_SIZE]; unsigned char swkPub[MAX_CPU_SOCKET][MAX_ESWK_SIZE]; unsigned char wpk_type1[MAX_KPT_RSA_KEY_TYPE1_SIZE]; unsigned char wpk_type2[MAX_KPT_RSA_KEY_TYPE2_SIZE]; unsigned char n[MAX_KPT_RSA_KEY_N_SIZE]; unsigned char e[MAX_KPT_RSA_KEY_E_SIZE]; int swkSec_size[MAX_CPU_SOCKET]; int swkPub_size[MAX_CPU_SOCKET]; int wpk_type1_size; int wpk_type2_size; int n_size; int e_size; int rsa_nid; int wrapping_alg_nid; } kpt_rsa_wpk; int kpt_ecc_wpk_gen(unsigned char *cpk_file, unsigned char *wpk_file); int kpt_ecc_wpk_parse(kpt_ecc_wpk *ecc_wpk, unsigned char *wpk_file); int kpt_rsa_wpk_gen(unsigned char *cpk_file, unsigned char *wpk_file); int kpt_rsa_wpk_parse(kpt_rsa_wpk *rsa_wpk, unsigned char *wpk_file); #endif qatengine-1.9.0/kpt/apps/kpt_rsa_key.c000066400000000000000000000465411500416242000177200ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /************************KPT RSA PRIVATE KEY ASN.1 Coding Format*************** * * Intel_KPT_RSA_Key DEFINITIONS AUTOMATIC TAGS ::= BEGIN * KPTRSAKEY ::= SEQUENCE { * version INTEGER { kptRSAKeyVersion(1) } (kptRSAKeyVersion), * privateKeyType1 OCTET STRING, --(d||n)'||auth * privateKeyType2 OCTET STRING, --(p||q||dp||dq||qinv||e)'||auth * size INTEGER, * kptRSADsi ASN1_OBJECT, * publicKey rsa_public_key, * wrappingMetadata metadata * } * * rsa_public_key ::= SEQUENCE { * n INTEGER, * e INTEGER * } * * metadata ::= SEQUENCE { * aesNonce OCTET STRING (SIZE(12)), * wrappingAlg OBJECT IDENTIFIER ( id-aes256-GCM ), * encryptedSWK eSWKs * } * * eSWKs ::= SEQUENCE OF eSWK * * eSWK ::= SEQUENCE { * devSig OCTET STRING, * secSWK OCTET STRING * } * * id-aes256-GCM OBJECT IDENTIFIER ::= { aes 46 } * * id-aes-gcm OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) * organization(1) gov(101) csor(3) * nistAlgorithm(4) 1 } * END * **************************************************************************/ #include #include #include #include "kpt_key.h" #include "kpt_swk.h" #include "kpt_dev_pp.h" typedef struct rsa_public_key { ASN1_INTEGER *n; ASN1_INTEGER *e; } RSAPUBLICKEY; DECLARE_ASN1_FUNCTIONS(RSAPUBLICKEY) typedef struct kpt_rsa_key { long version; ASN1_OCTET_STRING *privateKeyType1; ASN1_OCTET_STRING *privateKeyType2; long size; ASN1_OBJECT *kptRSADsi; RSAPUBLICKEY *publicKey; WRAPPINGMETADATA *wrappingMetadata; } KPTRSAKEY; DECLARE_ASN1_FUNCTIONS(KPTRSAKEY) ASN1_SEQUENCE(RSAPUBLICKEY) = { ASN1_SIMPLE(RSAPUBLICKEY, n, ASN1_INTEGER), ASN1_SIMPLE(RSAPUBLICKEY, e, ASN1_INTEGER) }ASN1_SEQUENCE_END(RSAPUBLICKEY) IMPLEMENT_ASN1_FUNCTIONS(RSAPUBLICKEY) ASN1_SEQUENCE(KPTRSAKEY) = { ASN1_SIMPLE(KPTRSAKEY, version, LONG), ASN1_SIMPLE(KPTRSAKEY, privateKeyType1, ASN1_OCTET_STRING), ASN1_SIMPLE(KPTRSAKEY, privateKeyType2, ASN1_OCTET_STRING), ASN1_SIMPLE(KPTRSAKEY, size, LONG), ASN1_SIMPLE(KPTRSAKEY, kptRSADsi, ASN1_OBJECT), ASN1_SIMPLE(KPTRSAKEY, publicKey, RSAPUBLICKEY), ASN1_SIMPLE(KPTRSAKEY, wrappingMetadata, WRAPPINGMETADATA), }ASN1_SEQUENCE_END(KPTRSAKEY) IMPLEMENT_ASN1_FUNCTIONS(KPTRSAKEY) /** ***************************************************************************** * Object OID DER(OID) * OBJ_pkcs1 1.2.840.113549.1.1 06 08 2A 86 48 86 F7 0D 01 01 *****************************************************************************/ static unsigned char rsa_oid[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01 }; #define RSA_512_KEY_SIZE_IN_BYTE (64) #define RSA_1024_KEY_SIZE_IN_BYTE (128) #define RSA_2048_KEY_SIZE_IN_BYTE (256) #define RSA_3072_KEY_SIZE_IN_BYTE (384) #define RSA_4096_KEY_SIZE_IN_BYTE (512) #define RSA_8192_KEY_SIZE_IN_BYTE (1024) #define KPT_RSA_TYPE1_KEY_SIZE(x) (x * 2) #define KPT_RSA_TYPE2_KEY_SIZE(x) (x * 7) #define KPT_RSA_KEY_VERSION (0x1) #define MAX(x, y) (x > y) ? x : y static void hex_log(unsigned char *pData, unsigned int numBytes, const char* caption) { int i = 0; if (NULL == pData) { return; } if (caption != NULL) { log_print("\n=== %s ===\n", caption); } for (i = 0; i < numBytes; i++) { log_print("%02x ", pData[i]); if (!((i + 1) % 16)) log_print("\n"); } log_print("\n"); } static int rsa_get_key_size(int len_n) { if (len_n <= RSA_512_KEY_SIZE_IN_BYTE) return RSA_512_KEY_SIZE_IN_BYTE; if (len_n <= RSA_1024_KEY_SIZE_IN_BYTE) return RSA_1024_KEY_SIZE_IN_BYTE; if (len_n <= RSA_2048_KEY_SIZE_IN_BYTE) return RSA_2048_KEY_SIZE_IN_BYTE; if (len_n <= RSA_3072_KEY_SIZE_IN_BYTE) return RSA_3072_KEY_SIZE_IN_BYTE; if (len_n <= RSA_4096_KEY_SIZE_IN_BYTE) return RSA_4096_KEY_SIZE_IN_BYTE; if (len_n <= RSA_8192_KEY_SIZE_IN_BYTE) return RSA_8192_KEY_SIZE_IN_BYTE; } static int generate_type1_wpk(const BIGNUM *n, const BIGNUM *d, int key_size, unsigned char *key_type1, unsigned char *swk, unsigned char *iv) { unsigned char *buf = NULL, *src_buf = NULL, *tmp_buf = NULL; unsigned int len_n, len_d; int ret = -1, size_tmp = 0; if (n == NULL || d == NULL || key_type1 == NULL || swk == NULL || iv == NULL) { goto err; } if ((buf = malloc(key_size)) == NULL) { goto err; } if ((src_buf = malloc(KPT_RSA_TYPE1_KEY_SIZE(key_size))) == NULL) { goto err; } memset(src_buf, 0, KPT_RSA_TYPE1_KEY_SIZE(key_size)); len_n = BN_num_bytes(n); len_d = BN_num_bytes(d); tmp_buf = src_buf; memset(src_buf, 0, KPT_RSA_TYPE1_KEY_SIZE(key_size)); tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(d, buf); memcpy(tmp_buf - len_d, buf, len_d); tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(n, buf); memcpy(tmp_buf - len_n, buf, len_n); ret = wrap_key_with_gcm256(src_buf, KPT_RSA_TYPE1_KEY_SIZE(key_size), key_type1, &size_tmp, swk, iv, AES_GCM_IV_SIZE, rsa_oid, sizeof(rsa_oid)); err: if (buf) { free(buf); } if (src_buf) { free(src_buf); } return ret; } static int generate_type2_wpk(const BIGNUM *p, const BIGNUM *q, const BIGNUM *dp, const BIGNUM *dq, const BIGNUM *qinv, const BIGNUM *e, int key_size, unsigned char *key_type2, unsigned char *swk, unsigned char *iv) { unsigned char *buf = NULL, *buf_e = NULL, *src_buf = NULL, *tmp_buf = NULL; unsigned int len_p, len_q, len_dp, len_dq, len_qinv, len_e; int ret = -1, size_tmp = 0; if (!p || !dp || !dq || !qinv || !e || !key_type2 || !swk || !iv) { goto err; } if ((buf = malloc(key_size)) == NULL) { goto err; } if ((buf_e = malloc(key_size * 2)) == NULL) { goto err; } if ((src_buf = malloc(KPT_RSA_TYPE2_KEY_SIZE(key_size))) == NULL) { goto err; } memset(src_buf, 0, KPT_RSA_TYPE2_KEY_SIZE(key_size)); len_p = BN_num_bytes(p); len_q = BN_num_bytes(q); len_dp = BN_num_bytes(dp); len_dq = BN_num_bytes(dq); len_qinv = BN_num_bytes(qinv); len_e = BN_num_bytes(e); tmp_buf = src_buf; tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(p, buf); memcpy(tmp_buf - len_p, buf, len_p); tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(q, buf); memcpy(tmp_buf - len_q, buf, len_q); tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(dp, buf); memcpy(tmp_buf - len_dp, buf, len_dp); tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(dq, buf); memcpy(tmp_buf - len_dq, buf, len_dq); tmp_buf += key_size; memset(buf, 0, key_size); BN_bn2bin(qinv, buf); memcpy(tmp_buf - len_qinv, buf, len_qinv); /* sizeof(e) is twice of sizeof(p) */ tmp_buf += key_size * 2; memset(buf_e, 0, key_size * 2); BN_bn2bin(e, buf_e); memcpy(tmp_buf - len_e, buf_e, len_e); ret = wrap_key_with_gcm256(src_buf, KPT_RSA_TYPE2_KEY_SIZE(key_size), key_type2, &size_tmp, swk, iv, AES_GCM_IV_SIZE, rsa_oid, sizeof(rsa_oid)); err: if (buf) { free(buf); } if (buf_e) { free(buf_e); } if (src_buf) { free(src_buf); } return ret; } static int build_kpt_wpk(RSA *rsa, unsigned char **rsa_key_type1, unsigned char **rsa_key_type2, unsigned int *rsa_key_size, unsigned int *rsa_size_type1, unsigned int *rsa_size_type2, unsigned char *swk, unsigned char *iv) { const BIGNUM *p = NULL, *q = NULL, *dp = NULL, *dq = NULL, *qinv = NULL; const BIGNUM *n = NULL, *e = NULL, *d = NULL; unsigned int len_n = 0; unsigned char *key_type1 = NULL, *key_type2 = NULL; int ret = -1, key_size = 0; int size_type1 = 0, size_type2 = 0; if (!rsa || !rsa_key_type1 || !rsa_key_type2 || !rsa_key_size || !rsa_size_type1 || !rsa_size_type2 || !swk || !iv) { return -1; } RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dp, &dq, &qinv); RSA_get0_key(rsa, &n, &e, &d); len_n = (unsigned int) BN_num_bytes(n); key_size = rsa_get_key_size(len_n); if (key_size > 0) { size_type1 = KPT_RSA_TYPE1_KEY_SIZE(key_size) + AES_GCM_TAG_SIZE; size_type2 = KPT_RSA_TYPE2_KEY_SIZE(key_size/2) + AES_GCM_TAG_SIZE; if ((key_type1 = OPENSSL_malloc(size_type1)) == NULL) { goto err; } if ((key_type2 = OPENSSL_malloc(size_type2)) == NULL) { goto err; } ret = generate_type1_wpk(n, d, key_size, key_type1, swk, iv); if (ret < 0) { goto err; } ret = generate_type2_wpk(p, q, dp, dq, qinv, e, key_size/2, key_type2, swk, iv); if (ret < 0) { goto err; } } *rsa_key_type1 = key_type1; *rsa_key_type2 = key_type2; *rsa_key_size = key_size; *rsa_size_type1 = size_type1; *rsa_size_type2 = size_type2; return ret; err: if (key_type1) { OPENSSL_free(key_type1); } if (key_type2) { OPENSSL_free(key_type2); } return -1; } static void build_rsa_public_key(RSA *rsa, RSAPUBLICKEY *pub_key) { const BIGNUM *n = NULL, *e = NULL, *d = NULL; RSA_get0_key(rsa, &n, &e, &d); BN_to_ASN1_INTEGER(n, pub_key->n); BN_to_ASN1_INTEGER(e, pub_key->e); } int kpt_rsa_wpk_gen(unsigned char *cpk_file, unsigned char *wpk_file) { RSA *rsa = NULL; EVP_PKEY *pkey = NULL; KPTRSAKEY *key = NULL; BIO *in = NULL; BIO *out = NULL; WRAPPINGMETADATA *metadata = NULL; RSAPUBLICKEY *pub_key = NULL; ASN1_OBJECT *enc_algo_id = NULL; ESWK *eSWK = NULL; unsigned char swk[AES_GCM_256_KEY_SIZE]; unsigned char *key_type1 = NULL, *key_type2 = NULL; unsigned int key_size = 0, size_type1 = 0, size_type2 = 0; unsigned char *iv = NULL, *dev_sig = NULL, *eswk = NULL; int ret = 0, i = 0; if ((in = BIO_new(BIO_s_file())) == NULL) { log_err(" - BIO new failed\n"); ret = -1; goto err; } if (!(BIO_read_filename(in,cpk_file))) { log_err(" - Read clear private key file %s failed\n", cpk_file); ret = -1; goto err; } /* read private key */ if ((pkey = PEM_read_bio_PrivateKey(in,NULL,NULL,NULL)) == NULL) { log_err(" - Read Private Key error\n"); ret = -1; goto err; } BIO_free(in); in = NULL; if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) { log_err(" - Get RSA Private Key error\n"); ret = -1; goto err; } if ((iv = OPENSSL_malloc(AES_GCM_IV_SIZE)) == NULL) { ret = -1; goto err; } RAND_bytes(iv, AES_GCM_IV_SIZE); if ((key = KPTRSAKEY_new()) == NULL) { ret = -1; goto err; } if ((metadata = key->wrappingMetadata) == NULL) { ret = -1; goto err; } enc_algo_id = OBJ_txt2obj("aes-256-gcm", 0); metadata->wrappingAlg = enc_algo_id; RAND_bytes(swk, sizeof(swk)); /* get instance->query per-part key */ ret = kpt_get_per_part_key(); if (ret != 0) { ret = -1; goto err; } for (i = 0; i < cpu_socket_num; i++){ if ((eSWK = ESWK_new()) == NULL) { ret = -1; goto err; } if ((eswk = OPENSSL_zalloc(KPT_PER_PART_KEY_N_LEN)) == NULL) { ret = -1; goto err; } if ((dev_sig = OPENSSL_zalloc(KPT_PER_PART_SIG_LEN)) == NULL) { ret = -1; goto err; } hex_log(kpt_per_part_context_ptr[i].pub_n, KPT_PER_PART_KEY_N_LEN, "Per Part key N:"); hex_log(kpt_per_part_context_ptr[i].pub_e, KPT_PER_PART_KEY_E_LEN, "Per Part key E"); hex_log(kpt_per_part_context_ptr[i].sig, KPT_PER_PART_SIG_LEN, "signature"); ret = encrypt_swk_with_per_part_key(swk, eswk, \ kpt_per_part_context_ptr[i].pub_n, \ kpt_per_part_context_ptr[i].len_pub_n, \ kpt_per_part_context_ptr[i].pub_e, \ kpt_per_part_context_ptr[i].len_pub_e); if (ret <= 0) { ret = -1; goto err; } hex_log(eswk, KPT_PER_PART_KEY_N_LEN, "Encrypted SWK of KPT2"); memcpy(dev_sig, kpt_per_part_context_ptr[i].sig, \ kpt_per_part_context_ptr[i].len_sig); ASN1_STRING_set0(eSWK->secSWK, eswk, KPT_PER_PART_KEY_N_LEN); ASN1_STRING_set0(eSWK->devSig, dev_sig, KPT_PER_PART_SIG_LEN); sk_ESWK_push(metadata->eSWKs, eSWK); log_print("The eswk counter is %d \n", sk_ESWK_num(metadata->eSWKs)); } ASN1_STRING_set0(metadata->aesNonce, iv, AES_GCM_IV_SIZE); pub_key = key->publicKey; if (!pub_key) { ret = -1; goto err; } build_rsa_public_key(rsa, pub_key); ret = build_kpt_wpk(rsa, &key_type1, &key_type2, &key_size, &size_type1, &size_type2, swk, iv); if (ret < 0) { ret = -1; goto err; } hex_log(key_type1, size_type1, "type1"); hex_log(key_type2, size_type2, "type2"); key->version = (long)KPT_RSA_KEY_VERSION; ASN1_STRING_set0(key->privateKeyType1, key_type1, size_type1); ASN1_STRING_set0(key->privateKeyType2, key_type2, size_type2); key->size = (long)key_size; key->kptRSADsi = OBJ_nid2obj(NID_pkcs1); key->publicKey = pub_key; if ((out = BIO_new(BIO_s_file())) == NULL) { ret = -1; goto err; } BIO_write_filename(out, wpk_file); PEM_ASN1_write_bio((i2d_of_void *)i2d_KPTRSAKEY, "KPT RSA KEY", out, key, NULL, NULL, 0, NULL, NULL); BIO_flush(out); BIO_free(out); err: if (key) KPTRSAKEY_free(key); if (rsa) RSA_free(rsa); if (pkey) EVP_PKEY_free(pkey); return ret; } int kpt_rsa_wpk_parse(kpt_rsa_wpk *rsa_wpk, unsigned char *wpk_file) { KPTRSAKEY *kptrsakey = NULL; WRAPPINGMETADATA *metadata = NULL; RSAPUBLICKEY *pub = NULL; BIO *in = NULL; char *name = NULL, *header = NULL; unsigned char *data = NULL; const unsigned char *p = NULL; long len; int ret = 0; BIGNUM *n = NULL, *e = NULL; int i; in = BIO_new(BIO_s_file()); if (BIO_read_filename(in, wpk_file) <= 0) { goto err; } ret = PEM_read_bio(in, &name, &header, &data, &len); p = data; d2i_KPTRSAKEY(&kptrsakey, &p, len); if (!kptrsakey) { goto err; } BIO_free(in); in = NULL; rsa_wpk->version = kptrsakey->version; rsa_wpk->size = kptrsakey->size; rsa_wpk->rsa_nid = OBJ_obj2nid(kptrsakey->kptRSADsi); metadata = kptrsakey->wrappingMetadata; rsa_wpk->wrapping_alg_nid = OBJ_obj2nid(metadata->wrappingAlg); for (i = 0; i < sk_ESWK_num(metadata->eSWKs); i++ ) { ESWK *eSWK = sk_ESWK_value(metadata->eSWKs, i); (rsa_wpk->swkSec_size)[i] = ASN1_STRING_length(eSWK->secSWK); memcpy((rsa_wpk->swkSec)[i], ASN1_STRING_get0_data(eSWK->secSWK), (rsa_wpk->swkSec_size)[i]); (rsa_wpk->swkPub_size)[i] = ASN1_STRING_length(eSWK->devSig); memcpy((rsa_wpk->swkPub)[i], ASN1_STRING_get0_data(eSWK->devSig), (rsa_wpk->swkPub_size)[i]); } rsa_wpk->wpk_type1_size = ASN1_STRING_length(kptrsakey->privateKeyType1); memcpy(rsa_wpk->wpk_type1, ASN1_STRING_get0_data(kptrsakey->privateKeyType1), rsa_wpk->wpk_type1_size); rsa_wpk->wpk_type2_size = ASN1_STRING_length(kptrsakey->privateKeyType2); memcpy(rsa_wpk->wpk_type2, ASN1_STRING_get0_data(kptrsakey->privateKeyType2), rsa_wpk->wpk_type2_size); n = ASN1_INTEGER_to_BN(kptrsakey->publicKey->n, NULL); e = ASN1_INTEGER_to_BN(kptrsakey->publicKey->e, NULL); rsa_wpk->n_size = BN_num_bytes(n); rsa_wpk->e_size = BN_num_bytes(e); BN_bn2bin(n, rsa_wpk->n); BN_bn2bin(e, rsa_wpk->e); log_print("\n=========================\n"); log_print("WPK version: %ld\n", rsa_wpk->version); hex_log(rsa_wpk->wpk_type1, rsa_wpk->wpk_type1_size, "RSA WPK TYPE1"); hex_log(rsa_wpk->wpk_type2, rsa_wpk->wpk_type2_size, "RSA WPK TYPE2"); log_print("\nWPK Size: %ld\n", rsa_wpk->size); log_print("\nRSA NID: %d\n", rsa_wpk->rsa_nid); hex_log(rsa_wpk->n, rsa_wpk->n_size, "RSA Public Key - N"); hex_log(rsa_wpk->e, rsa_wpk->e_size, "RSA Public Key - E"); hex_log((unsigned char *)ASN1_STRING_get0_data(metadata->aesNonce), ASN1_STRING_length(metadata->aesNonce), "IV"); log_print("\nWrapping Algorithm NID: %d\n", rsa_wpk->wrapping_alg_nid); for (i = 0; i < sk_ESWK_num(metadata->eSWKs); i++ ) { log_print("\nESWK %d\n", i); hex_log((rsa_wpk->swkSec)[i], (rsa_wpk->swkSec_size)[i], "Sec SWK"); hex_log((rsa_wpk->swkPub)[i], (rsa_wpk->swkPub_size)[i], "Dev sig"); } log_print("=========================\n\n"); return 0; err: if (in) { BIO_free(in); in = NULL; } return -1; } qatengine-1.9.0/kpt/apps/kpt_swk.c000066400000000000000000000123541500416242000170620ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include "kpt_swk.h" #ifdef KPT1 #include "kpttool.h" #endif #define MAX_KPT_PRIVATE_KEY_SIZE (4096) ASN1_SEQUENCE(ESWK) = { ASN1_SIMPLE(ESWK, devSig, ASN1_OCTET_STRING), ASN1_SIMPLE(ESWK, secSWK, ASN1_OCTET_STRING) } ASN1_SEQUENCE_END(ESWK) IMPLEMENT_ASN1_FUNCTIONS(ESWK) ASN1_SEQUENCE(WRAPPINGMETADATA) = { ASN1_SIMPLE(WRAPPINGMETADATA, aesNonce, ASN1_OCTET_STRING), ASN1_SIMPLE(WRAPPINGMETADATA, wrappingAlg, ASN1_OBJECT), ASN1_SEQUENCE_OF(WRAPPINGMETADATA, eSWKs, ESWK) }ASN1_SEQUENCE_END(WRAPPINGMETADATA) IMPLEMENT_ASN1_FUNCTIONS(WRAPPINGMETADATA) int wrap_key_with_gcm256(unsigned char *ck, int ck_len, unsigned char *pk, int *pk_len, unsigned char *swk, unsigned char *iv, int iv_len, unsigned char *aad, int aad_len) { unsigned char out_buf[MAX_KPT_PRIVATE_KEY_SIZE]; int out_len = 0; if ((!ck) || (!pk) || (!swk) || (!iv)) { return -1; } if (AES_GCM_IV_SIZE != iv_len) { return -1; } EVP_CIPHER_CTX *ctx; ctx = EVP_CIPHER_CTX_new(); /* Set cipher type and mode */ EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); /* Set IV length if default 96 bits is not appropriate */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len, NULL); /* Initialise key and IV */ EVP_EncryptInit_ex(ctx, NULL, NULL, swk, iv); /* Zero or more calls to specify any AAD */ if (aad && aad_len > 0) { EVP_EncryptUpdate(ctx, NULL, &out_len, aad, aad_len); } /* Encrypt plaintext */ EVP_EncryptUpdate(ctx, out_buf, &out_len, ck, ck_len); memcpy(pk, out_buf, out_len); *pk_len = out_len; /* Finalise: note get no out_put for GCM */ EVP_EncryptFinal_ex(ctx, out_buf, &out_len); /* Get tag */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_GCM_TAG_SIZE, out_buf); /* Pad the gcm tag*/ memcpy(pk + *pk_len, out_buf, AES_GCM_TAG_SIZE); *pk_len += AES_GCM_TAG_SIZE; EVP_CIPHER_CTX_free(ctx); return 0; } int encrypt_swk_with_per_part_key(unsigned char *swk, unsigned char *eswk, unsigned char *n, int n_len, unsigned char *e, int e_len) { int ret = -1; BIGNUM *bn = NULL; BIGNUM *be = NULL; EVP_PKEY_CTX *ctx = NULL; size_t eswk_len = RSA3K_ENCRYPTION_OUTPUT_SIZE; unsigned char dataOut[1024] = {0}; EVP_PKEY *pubKey = NULL; RSA *rsa = NULL; if (!swk || !eswk || !n || !e) { return -1; } if ((pubKey = EVP_PKEY_new()) == NULL) { goto err; } if ((rsa = RSA_new()) == NULL) { goto err; } bn = BN_bin2bn(n, n_len, NULL); be = BN_bin2bn(e, e_len, NULL); RSA_set0_key(rsa, bn, be, NULL); EVP_PKEY_assign_RSA(pubKey, rsa); ctx = EVP_PKEY_CTX_new(pubKey, NULL); if (ctx) { if (EVP_PKEY_encrypt_init(ctx) > 0) { EVP_PKEY_CTX_ctrl_str(ctx, "rsa_padding_mode", "oaep"); EVP_PKEY_CTX_ctrl_str(ctx, "rsa_oaep_md", "sha256"); EVP_PKEY_CTX_ctrl_str(ctx, "rsa_mgf1_md", "sha256"); ret = EVP_PKEY_encrypt(ctx, eswk, &eswk_len, swk, AES_GCM_256_KEY_SIZE); } } err: if (ctx) { EVP_PKEY_CTX_free(ctx); } if (pubKey) { EVP_PKEY_free(pubKey); } return ret; } qatengine-1.9.0/kpt/apps/kpt_swk.h000066400000000000000000000060251500416242000170650ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #ifndef __KPT_SWK_H__ #define __KPT_SWK_H__ #include #include #include #define MAX_KPT1_PUB_LEN (2048) #define MAX_KPT1_PRIV_LEN (2048) typedef struct e_swk{ ASN1_OCTET_STRING *devSig; ASN1_OCTET_STRING *secSWK; } ESWK; DEFINE_STACK_OF(ESWK) DECLARE_ASN1_FUNCTIONS(ESWK) typedef struct wrapping_metadata { ASN1_OCTET_STRING *aesNonce; ASN1_OBJECT *wrappingAlg; STACK_OF(ESWK) *eSWKs; } WRAPPINGMETADATA; DECLARE_ASN1_FUNCTIONS(WRAPPINGMETADATA) #define AES_GCM_256_KEY_SIZE (32) #define AES_GCM_IV_SIZE (12) #define AES_GCM_TAG_SIZE (16) #define RSA3K_ENCRYPTION_OUTPUT_SIZE (384) int wrap_key_with_gcm256(unsigned char *ck, int ck_len, unsigned char *pk, int *pk_len, unsigned char *swk, unsigned char *iv, int iv_len, unsigned char *aad, int aad_len); int encrypt_swk_with_per_part_key(unsigned char *swk, unsigned char *eswk, unsigned char *n, int n_len, unsigned char *e, int e_len); int seal_swk_with_ptt_srk(unsigned char *swk, unsigned char *priv, unsigned int *priv_len, unsigned char *pub, unsigned int *pub_len); #endif qatengine-1.9.0/kpt/apps/main.c000066400000000000000000000117021500416242000163200ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include "kpt_key.h" #include "kpt_dev_pp.h" void tool_usage(void) { log_print("kpttool generate or parse wpk\n"); log_print("Usage of kpttool:\n"); log_print("kpttool -act [gen|par] -alg [rsa|ecc] -in [|] -out \n"); log_print(" -act (action): gen (generate wpk (wrap private key)), par (parse wpk (wrap private key))\n"); log_print(" -alg (algorithm): rsa (-in rsa private key file), ecc (-in ecc private key)\n"); log_print(" -in: -act gen input cpk (customer private key) file\n"); log_print(" -act par input wpk (wrap private key) file\n"); log_print(" -out: -act gen output wpk (wrap private key) file\n"); log_print("e.g. kpttool -act gen -alg ecc -in ec_secp256r1_private.key -out ec_secp256r1_wpk.key\n"); log_print("e.g. kpttool -act par -alg ecc -in ec_secp256r1_wpk.key\n"); log_print("e.g. kpttool -act gen -alg rsa -in rsa_2k_private.key -out rsa_2k_wpk.key\n"); log_print("e.g. kpttool -act par -alg rsa -in rsa_2k_wpk.key\n"); } int main(int argc, char** argv) { unsigned char *input_file = NULL; unsigned char *output_file = NULL; unsigned char *action = NULL; unsigned char *algo = NULL; int ret = 0; argc--; argv++; while (argc >= 1) { if (strcmp(*argv, "-act") == 0) { if (--argc < 1) { tool_usage(); return 0; } action = *(++argv); } else if (strcmp(*argv, "-alg") == 0) { if (--argc < 1) { tool_usage(); return 0; } algo = *(++argv); } else if (strcmp(*argv, "-in") == 0) { if (--argc < 1) { tool_usage(); return 0; } input_file = *(++argv); } else if (strcmp(*argv, "-out") == 0) { if (--argc < 1) { tool_usage(); return 0; } output_file = *(++argv); } else { tool_usage(); return 0; } argc--; argv++; } if (!action || !algo) { tool_usage(); exit(1); } log_print("input file %s \n",input_file); log_print("output file %s \n",output_file); log_print("alg %s \n",algo); log_print("action %s \n",action); if (strcmp(algo, "ecc") == 0) { if (strcmp(action, "gen") == 0) { ret = kpt_ecc_wpk_gen(input_file, output_file); } else if (strcmp(action, "par") == 0) { kpt_ecc_wpk ecc_wpk; ret = kpt_ecc_wpk_parse(&ecc_wpk, input_file); } else { tool_usage(); } } else if (strcmp(algo, "rsa") == 0) { if (strcmp(action, "gen") == 0) { ret = kpt_rsa_wpk_gen(input_file, output_file); } else if (strcmp(action, "par") == 0) { kpt_rsa_wpk rsa_wpk; ret = kpt_rsa_wpk_parse(&rsa_wpk, input_file); } else { tool_usage(); } } else { tool_usage(); } return ret; } qatengine-1.9.0/kpt/lib/000077500000000000000000000000001500416242000150325ustar00rootroot00000000000000qatengine-1.9.0/kpt/lib/KPT_Library.PNG000066400000000000000000001033121500416242000175220ustar00rootroot00000000000000‰PNG  IHDRÖ.3)³sRGB®ĪégAMA± üa pHYsttŽfx†_IDATx^ķ½`ĒyžżŁqŠćüćŲ‰ć$NāŽāŲNwĒ%±cIV±dĖ–dY¶ŗdÉź½÷BŠjTļ½R"%‘%н,`ÆĮH ‚ €›o~³7ĄŽawö€;ŽóŹ?“Ü}w¶Ļ3ļĢ»s’Ÿ‘Éd2™L›IXe2™L&‹Ń$¬2™L&“ÅhV™L&“Éb4 «L&“Éd1š„U&“Éd²MĀ*“Éd2YŒ&a•Éd2™,F“°Źd2™L£IXe2™L&‹Ń$¬2™L&“ÅhV™L&“Éb4 «L&“Éd1š„U&“Éd²MĀ*“Éd2YŒ&a•Éd2™,F“°Źd2™L£IXe2™L&‹Ń$¬2™L&“ÅhV™L&“Éb“X…µµµÕ466 !„ECSSSRÅā±X…u]E„¹ż©Łęś‡„BˆĀēĘGf›²EĖ“*Å*¬«×Všc®™e~zžL!„¢ą9ō’™ff™„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…"~vŃ,sĮ½KĶ]£*ĢŁw/‰ō$¬%Ģa—Ī1G^5מ9;r½¢›ßŽ0ß,©h4{÷uš'Ęoˆō$¬%Ģ}£+M]C›ymFMŹņƒ/žmN¶ČósŠ……uķ9¶“n]hNøe”ż»ž‹ż•Ÿ_6ǜ:|‘łŻ "×?°Ģ4ķi7Ūė÷š3ļXé#HXóČĢ4·>·Ę¼āŵ¦²¦Å,­l4Ē^??eŻPsŁĆĖĶźMMfyU£ŗćž×ėžXåžį'm1W>²Āu‰Fłņ|?÷īfóšUęWWĶ‹ōÉŹæēÕ ³aŪ3{łN+®C’ Ņ {mfé“/̜»"{y²Ē}Ž}&ļ³ŽóĪ&sēĖėĢļoZŠ£~ć^ž6¢Ü<šŚzóņ䡟gäžW+]ĆéĄ RŸ„ėŸ\e^²~Ćl½YĢ=iÖ„ ’£®)3ēŻ³“ǰ‚„5³IX-ø½Ü%9P ļR÷ĄšR½S¶=åÅ C4{Ƀ˃±ŠäæŁ–e¤łSÉEµtń»čže]ÉFĒŲņ|ūŠ^ņĄrsį}ĖĢ)Ćõx€!“°RY\`·cߌ©„×IC§(weslüI+žˆ3ģĒ>9ęsF.qĒ‚/Ēɵ —Ė‹Ę9\óųJגå:ŃmFŌĀ6¼€G\¼Č¼Š\ Ž-ür‡į:š’_œÜ'žD·Q׀cĘחwøw*=¢vąļqwŻ1^¾~žšDE¹Ął^p_šœōĄ^ƒōо/xaŻk…•(lņ z±t‡92­7#›°ņÜūku¬įÄæō¼„#lÜ+ž)®~ŒµsÆ/Žx¶€JŸu\g¶Æ¶a’nĢ/āżāčŽ&qiųókSĘI)AEt_œ“9ņ}ń»@—p‡½€½¹Į=,ēüx8_ä¼Ć\?’|šü“‘¾ép/č2ēxŲ†÷÷DūĢGÕˆĻūä AŒ}°ūäyJægŲkTeV4°øĻŁĘйę¼Ć48^ŸYÓ뱇‘°f¶’Vfŗ=h­•­Ŗwó½£+]ÄŠŠž‘QH?zZµėN¢u|ė³k\—åš'Üķ/®ėńņ¾d+<ųq6ŚcżüÕõ¦©µĆU€D•5Ķf¤”Ó"“°’8Ą±n±Q6/“_ĪĖt‚}éčś©±ėčā”Ė>GyjüƮʑzt\•GihŁēü€ćd[’¹~Cń‘*ēIwĒıóo`L‡Ź_늌.µ m%ā Ø”ųʐä&*A^jŹį\Öln²Ē³ĮüśźŌnE*U" Ź£Āąīhls÷ Ę]Ļæ¹~ą/9• BŹs kā¹Ž[źZpż¦Éb<Ü«5ö|æņēk’×u 9w’‰¢¶Ļ…°°2†Š°4ķépĻ׍OÆN©03 +Ļ »ń6²ćŽń pmżqϱOf”‘óį'ø\n«ŅķHĢ”Eu¦Ž–Iyˆ÷ņѱU.bņŪ\kŸ™†ęvוĖ{.”"qīėŅ…ˆóćsž\ēšū@“īj®ó֝{Ķiʞ=4,č2ÅŃŗ†®g‘ē–ļ±Ēw’˜JwæxgżūÅõę¦”™~| ÉDtµīܯꎓėĄóĄ{Ą5b¬Óū#¤ˆ:Ē0gÅN×5Ėu§‹—e<“\óķõ÷ĀˆķŹäõE6ŃćÜH<ß$ČćoĪmŲFšŁJ^X•%öaāeGŠxų© xyQĀ­U’ŲY5n=ŻĘTīTDŒŃømmyŪvķķ‘“óJR©œėģvų̲5]Ńt;ń¢5ڊ…¤‹š‹™IXF,“pEB$ćŽrēKĖ—ćą<ØLŲVŲ—–²©˜²|©čČ<%qV1āŗÕnKŁl7Ͻ»©«+‰ ·Į¶śŁQŠ?6D†ģD®(!l+›É¶āeŸA²E§y}FMJ¤K+ß'œPęn[6Į»-ŃēŹ:² Ś5MdĄ½äųøŸ4&xų“{Ǿ޵ē…LPį_kÆ ÜkĘ®čįšŪ[ī¢,ęŅ }!]XéĀ[°¦Ž=§Ü×p_&a„‚œfg”Ł”ĻNŲä®/ā‰ųĻ]¹Ė] /Ō7YŃ꣤2_÷«C$÷¹sę™CTé¢äüIäįąY÷Źõ¤ —uėķž‰¾ĀĖ9.zJŽ =ėžŽA¶k¼į†ļģ’Ź ±«Ü cXĄ2Įżąœ·ŌķéJÜ!)ˆś‚å*Ļ RžAŽcwv•v¢źpy48Pž)ž[¢ę'ģ{ŠŅ˜ B7VĘ~)Ļ]?{-«ķ³‡ņlņβŽ÷ĘßĻ”Ķs€ąónŃk©7‡kĻ~yļø¾4 .µ1×¼·hWšŁJ^Xyłyį""–Ńm…°šŠŅBLļöĀŹCÕʋn,ŗgŒC¬ÓŻ3BX—²½V_ö„¶eKy“ØiEÆŚŲäĊ–hx»¾+/ Ń0/ /#‘Ėaö„āEååŗł™5fŗ­€|bņć¶¢¤kŠõųāŒ½$ÜĖL×+žTX¼toĪécåšłķ|…–IXyi}¤IäG'—ƒķ¶¼ D¬£2!źõŪyaå:P! ׎ī¬YĖvŗ ”¦»Śo×Wؘ®+•&½œ÷˜ó"šC4®_&8Fž*üńó¶»kEY”‰@!pTøt¤AÖū­°ņŁŹ3ąöœŲ'¾™„•{Ćr<ž¼IśYkÆ+eÓ w…gVÖ!8#^Xėžiī3ĻžļŖF(ßü ¦ˆ÷’† ׏gįALč ‹¦ē“ŪŹŻsECóÆć¹FØ9…é=IQŠHäżęYó‰;^X)‡Ø•²5ž_>9įZPŸ°Ż VÜ|YģŃ繦JF½æ¶¬ć3®;"ɵfÖ{aåŁYjė ź®=ū»öńUī|iä=mŖįkĀ=åå‹Ž_zßhl\õčŹõŠč¢įBƉżq'ēĆ9§ūƒ„5³•“°ņP“Łźv?¦C…t•­ØX©@/OKžšĀŠ"„ž„óPqš¢P.ŃĶŁwuĆé…u³m󒄷ćxČB¤BATĀŪõEX°-÷™VdxAčBJo³ŗ13U.¼Š®‘`”‚¦2„R göRdK^Ź$¬DT`Ō¤TTtrFOļžĆ + × ow÷Ø ×MĘ=óŃx "A č=@ųéś÷×~gE{Q2³”õQe„!r¤”EÅÉųjxbH×$YŌ°C_HV–Q‰Ž³ ań"Ė£„•ė‰ųrO‰ZҟĮŁs~Ć>ūįŹ9›°ņ|³Āč—{žw³«ų‰ÖĆŻ÷”Į0Ń,bJ†+ļ÷®~ß8HēY+„œ'Ń Ā^G£.}Ž“h.— Kčš%āć™ņĻ©VßŲL® ”'‚żūć`œ”Ę ļ]·ˆcų™:yĻAšlūÄ¢°°R¤OtĮ˜5÷‰c!b +§^ā=į¼yV)‡z…™ŗ'ż„!Ķ9óīqœĒĖy^õhĻo¢%¬™­¤…õ[”ŠeC+ ąp·ĻŚ-MÉŹ½:å!ģVūT!\Q¢ĀGę®b° Ņ~¹VZėQ#Q3• Ń&‘_Žaåe¦åK%C«łĄˆÖ}:œ/"Q üÓąŗ9^"7^~ļ?a%ós”‚ G>*m_9ńū²½°r殳‘Xśv¾"ēś9€LNZļT@œ7‘żØ©ĮµĆsć"P+6Qe„į>#wzåH”E4AT™aĜēƒ{5Ę>Ė\ó(a„āä9Ə(2]Xß¶÷„sFX¹’~y6au÷#āÜh!\ÜÓōo$éÖ„»“żŃ•ĢŸtg§7b=+BĘ3Ļų|ŗp"¬ˆĒÉs‹˜…×GĮµ@ųyü»ī ~=­»ŁCĪ+ū#™Šeœ«ļAb!żyā[`¢O[¬'¦ńVīkųšēD–3ėg.Ūy,”Aā¹¼Ć<ųÓØ„{8ݟ2|– ²ĻžÜ#ź±p)aĶl%+¬<@TüTv ‘Ē6Zō0ę@Ė—‡hķ„Š€~.ĀźD„¹Ż•Owœ_žMXéŽi£*œ'ŽŚŲµ¼ÆĀJ…I«“óˆzįĀP Q/I#ŪūSXżu„k0ģ†sĒ_?6˜MXiUĒ!¬Tņ<ģß_‡(øīdQF•†nNĘõø®A“4Ū]/*=ŗ‚¹×ŒÆō[ßLĀŹžh`Ł0äAęu”°ŅSs­<9zTؐ9N*yŗ©©Œ9Ÿ‹ąĖĻ&¬$ÄE ė]ö=Ė$¬<³ “t߇žū Ć,S]Ī4Ó×ó¼ņSVT/N|’‰€rü3˜"¬2hyē8ÆpŅž_Ęūõ,yx¶¹ž”V®m”°¾•ŽÉ$¬ač~5µŚŻwŽaL/3 Q:“FŠ›Ā>x†ł ĮƗ°f¶’V¢"’`šŠ (tł„”‚b=-Ķš .¹+Y˜TšŒ÷ģć—gÖr÷ ó2†č—÷WXIbÉöĀ]o Ęoq­ė2²ŠYža„Ū)źŲ(‹„|Ø0–¶°ŅZ'ćń×#[QŃ}UF„éĮ׫Ü}ēųˆXžæĮu­ŗ„&ūŒ„Ē?ūK&aiH¢Be愕ˆ’Ģuöé£,’Ū¢Ęūø¾Œ1ř³GM”Āų§ū<Ģ'Ļr¶‰,čž§›•ż’¬åżsÖūĘXµĒL#ĘgČ{aåzÓŠŽ|ž,īSød4·°<ņ&øL‚ćó,2A=IŠĮ>Ø#Htōė$¬™­d…•Ź„DZń3–ģp/I.ĖĻžI >C5,¬¼t¼Ųéåßõ2]?f[ŚĆ腕J+ŖRF€J*ö+l+Ü/ļ‹°2īSAņ‡Żėʶ‘Hx›tųdˆsa^UŹWŽD ”§°Ņ½Ģv$ˆ…³~=¼¤žYŗżņĮV¢ŸB·^.Vo|³pmƒ«Xé¦ŃęĆžŪ}rb£‚Øo6ūJoĀŹ3ź§1¤kŃą¾†…•óžĀZēĆ»A5eqČ~„ņ&Lžņ!¬|®‚0q­ˆyų”…ļKÓļŸ—Ms>Œ‹ž\‰^zDžžĶ(?ĒĪ3Ą}ā0üx~XXyžÓ1¤1JO=@>‰Ž÷”ēvĒnŽ…Ü2æó!¬šČŲą:šģżŃ¾SQ>aøVA—x›ėšĖ%¬™­d…•ŹŒ‡…}*¤(šŖ$˜ŠĘ2/¬¢ņ¤\¢ÖpÖe…•JlĢōqææšvé ·ŁČ‰kKĀāČõĪ1yÕŽĖp7*_\ŃčöCw Æ¤Øl™1£kAås–kĮ3ƒ°„ŸŽ‘.Ū\² +‘Źõįśr_ĆĀJ„žāä-.b„Wsä8Żģ@ö¹įXéžNś8…•k€ØÓ ĻóČ>I˜9×^sßEMO’gł¼†!ēC¶kT2œ‡g–łŒézǟņˆb¹·ģ‡$/’$žńlræČ·7’¼°r¾®Œķ{ÜpēGćƒcąŁ6œ[Įu”AI=Āū@r“Eš<ńģó~Ņ;„čśL…•ūĮ3@£€\?#ĆSdųŅ“Ę5 {šśŒēēį'ėšĘžWŚ÷ ń¤·€ņxvĆ×Ā +ĆŌl†÷¤·ūQ(HXc‚Š ‹qÕžģ½Kˆˆ1A^*n/¬,#’åCz*¢WąÅāA„ŚŽÕ酕.fŗyŃ|ҧ¾wKŸÕ‡‘‡˜,ŁšrĘC£„1į%”„’@Ä©ĄČJd’›ģ¾}˟ŸbŠŹęŗ,q“t·øn8^6„,]X’Ø“ķ(Ÿs "š ™„• œ,l®׊ņézΟė°ÜF Tęa±9ˊe„•ŠŠ_ąąśńķpų:e!#шșūLv7ūę:s }×X8QʝÆõg?Tö>*įyyiRšYeq½€óäX)‡Yæ˜uČ7¦I’Ż%I7é×> fŚŹ&¬<tĮóLP6Ļ`øqĄ8ēČ:¬Ü#žīåĘķ-®!nšt «ĆĀźļG&aåÓ²taE`Ų?ēšØ}ężż§+›†-÷ž_Kŗé™ÕnQĻגI8ĀĻKō&Š ōĆ@œ#BƒxŠ ąßÜ[¢³¶‘>G¬|–Āūī†|ly¾€,ę'Ēoģ1Dı2ĢūŠVĪ.oöĻ2¾gö‰’< OæŻ»°śoÉĆĀJ£˜:‹kĀ:öGłü›sęļ4 |yŌ5 ēp/šēŚ;1Mž›kNc<żÓ¢wē™ū<×ܶ C‡š6…ˆ„5&H&¢BĄųä&ŹĒĆĆĶ Fėn2ĘLĀĀJ²Ć8ߌńB2žvŸmuG”zaåE!R#Ķž ‰J”Ļ x!éVIÆ ˆ ˆä˜ '¼œn0¶ēŲŅ÷G£€ķX‡0Ņ@X\DÕWāģ‹&I5|b„]a$­ l?yQ­łmšŲ3nuĆS«ÜzŽŸ.0ĪĒgPRI’IČē5D›©ŪĪvßéŅĶD·ūäüh¼p æōŠ į`<Zįįu@y\C*•pR•6ēc/»»OéåfŗęńU®[ŻŻ[{ŒÜ_ΉenāPōFdŹ'"\kz|ėžq©-µA7 Š­ “ųy~h¼ tœæ9„£,¢ķØ®ĆtøßT€TĪ$ŪEłpÆiHĶ]±Ė=ÓDžsįó Ž“Ę8¬ÓøīöŲ©dzTü3Ź7š'~į!Ž ŗŌ¢ōYˆįå³%ž¾õeāÉq‘Ø”Žøä8yF¹\¢”‘Æӏ²,׬j¢\®c”t‡rŻyžÖŚs  š(÷ÜæaĀc¬ćģ³Ä9„rž4N‰ł]ēt®<’öøžk7'÷k’ä»hz–xßü~ł“÷×_[zŚĀåńo†“Ųļ+S·tŻ?Ӕr>ė’ēG=A£Šč2||lǵ%b¦N¤!‡?ĻĻóšē×D&„ŃKDZįļ yśv…†„5&xˆšxĮüĆŲ]ž¾ +•5/åłr3UŽ^X}V°W mõ2–÷ /O9—ŠņšzDĢł„öåėĪ!ĀĻou­ŅĖēļŽ/¼.½åļI¹nÉķ3]ƒš±D]_öēĖņßŠ„umĆ^×[‘¾]o°}Ō1Bś9„_čˆ^©ˆiŌšŪ§”ēĮ—Ź”hą{Gæēč÷ē—eƗɟQė=ž8łÓß/¢J"0"*Y„Ė'("„˜ēĮō"ŹyS„÷u?°Ģm:?÷>Ųe™ĪٟėęęŚŅ-ß×nG®ÆæžŻŪµ +]Ņ<ž˜üö™žu×-Ó~ż½ūśõį垎ž‘Lēnü„Ét\™ĪĒļ»7Ņϧ‘°éšķE “.¬Q>">ˆ:é&cĢŽv¦J%ŸL²Ń>]pć×DT:üÉńŃ•Ź˜]ƒéSń &ģ›nn†H.{h…._Aņw7²hˆ®łd#—‰Gņ cxnx#m<3Ÿ¤ k1‡č k a-n~&˜×׍[‡²¬²8"Aŗ‚‰`éŗ#«šČnWƳHn‰źB,yĘ Ężøf$nq¬t!ŅŻŹ9Š[ ˆ’éŠßמ0äŠ å7Öż kĄĒęŒu’0mI÷”{¹šÜ»›]D|†#aĶ7d“’(•ķCų|BCŒ1W2 }² ‰$=H’F4ˆ)ßÉ1‘ūPtKŠ”Ę÷žļ,yžžnų–°·q½Į†Ø™ä©‚ć,w‰Yææy‹j£¶)ø¼»ÜCõ8ķHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ‘¢֓ožeŽøl¦"&¹8ؼp¦9[š%®2Y˜„U&+ėčL˜‡ßØ2_<Ū‰h_8śŚ2³“²1Y’L&j“°ŹdbÕĶę÷7-ˆĻLxį,s÷Ø ÓÜŚ‘,E&“ µIXe²±Ö¶óŲø ęĄ r’éÅcƟoÆkH– “É Į$¬2YٚMMę¤[FŠh:šˆ֙¶}É­e2Y!˜„U&+ #Ć7×±V­Źd…iV™¬ĄŒ±Öćoī}¬õ€ fš‘ÆT˜={5¶*“šIXe²3>½ydl•KLŠU8ī†łfŃZ­Źd…hV™¬mŻ–ĢQ+‚{ū‹ė­ŹdjV™¬Øõ±77DF­Ē\[¦L`™¬€MĀ*“Ø­ŻÜdN¼„g†šČQīÓ™LV˜&a•É Ō¢fc"ZU&°LVŲ&a•É Ų*C³1i–%™¬8LĀ*“°…gcb–„%[•É Ż$¬2Y³12|Q0ĖR»fY’É Ż$¬2Y³1š²Å¬Ś°;¹D&“²Å*¬uuufmE•"f/_gVÆ]¹N10jjj’*Å*¬«×Vš³n›e޽V!„(|N¼q–™U¶<©bńXģĀzĢ5¹’ä•B1”zÉL3SĀ*„Bă„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B^8ĖyÕ\sŌ5óĢ!ĻŽōB -V!ŠˆćnœoŹ×5˜m»öš[Ÿ]é#„Z$¬bæęgĶ2ŪČī€ ŗ—żņʹęž1ė͘é5ę¢ū—„ų6Ė9Ė–‹XfZöv˜­VX’p{y¤_ońr=²†—~łóüÄĶęÕiÕę×6ÆBō «(*Ź“‡-2QnŽøbn¤ē°Kē˜§ßŁhĘĶŁfĪ¹Ō ĖæyYQµŪģmļ4¼¶¾Ēvƒ‰;– Į±ÜŸåXÄq³·šĪ„1ӗģ0‡^tÓ%|Śmåęt{MælNķœwĻR3֖ńčø ®KŁ/?öśł¦±„Ż4·v˜ßß“ e!Dߐ°Š¢ā¤[šu[šMė¾NsK–®ŠßX±hhn7ū:ęµ™5ęĄ ‚ēč+f«6&…õõ”Ön KaEü6lk1mö|nzfµ=Ÿ`ł™w,6M{:L]C›¹üį=¶ óÄ[ŻÜlÆßk. EȔݓ§ŻEĆV!†„UgݹŲTļh5V̈ÖFśx޾¶Ģ‰VĶĪVóČŲŖ®īąb֑ÆT˜=m¦ŹŠ+Q»_~Ö]KL‡ cw[a¼ī‰U)Ū¤sūKė\7ņŅŹFs†dæ¼…õ”į‹Ģąµ.ś'’ņ¢?HXEQŃaŗ‹ĒōݦPŒĀzČ%³Ķ„łŪM»Š×mōżóP—o_„õ ‹f¹ėń {]ų»_^ŠĀzž½K]äĪu»ł%‚‰ų°Š¢¢ÆĀzØ¤Ć¬Øśn`ˆVĘ/_@ÄĀžé0ĪėĖüY–īG‚ė(?¶a<4œH•«°žu×b³¹vM¾+Ēɱp¾įåéĀJ’ĒīŽ;é>ītXǹłėŸQׄ徑ć®cØ|®¹’w¦ėOcĄ]óŠńū{Ē1óļšż‰:ī ė.ypy—°ɳ Ņ»ü6Łī„ «(*ś"¬$ēĢ\¶ĆTT7;Į‰ź ~ģĶ ę¶Ģńs·™Źšf×Ķŗø¢ĮÜój„9ꚲeņ¹Ėć7:ŸŪ÷ø1Ļeė͘5)É@D”ĆŸ_cf-Ūi*«[œļšMMfśŅ꜑Kŗ©rVŽ{ċėÜX1¾tq‡×÷EXoxjµY»¹ÉL^TėÄŌ/ ėi#ŹĶµO¬43ķ±r~ėkZĢ ūwŹNd8ųāYęR+Rlwēȹ®¶¾9g›¹ą¾„]Bõ««ē™9+vŚshr‰VŚF ‰[”?a~­õ]ę®%ėÆy|eŹ><Œ-SöL{]»!8ž‡ŽXļĘŻļ°āxā­ ĶÓļlråŗknĻ•Lg–ūū®½žÜæ­;÷šv{Mķ„3;ŪĢ&딇ˆś}žĀFų·Łg}²|xVø·Œóy•²ØE*VQTōEXĘM6Źk³¢uĻ«=„”b¬‘HlŲ[Ńīܽωc™t¹ŅmźĖ;āņ9fjyA…Ųvńŗw<[źZčāG„tĻ菮,[öÅ·§Tʔ’øó®cÉAX9†y«v¹nąŃÓ»“°<}V®ĆŽ}V šĢÉĆv-÷ĀŹ:ŗœ9ö†ę}n|šrIxbٽö¼ŅÅõ¾1•ö¼Ś¬OĀģjŚē®…掛ėöt 8 ī‰gļŲ} āģ?ń£kAä<É~N4‰ßµāM¹“Õu ŚĖS¶ø{IC€ėLłD¢Œ%sļ)ĮöćҌ-#¬ų°ė묰rÜĄ}šēųkŪxcÖVwŒųķ°ēœ_›ū7ĻÉø9[%®" «(*ś+¬÷F«­Ż:*ŻėŸ\墨sī^b^³Ń'.ĀBäęĖ»ŃF{emĆ^sÕ£+ĶomÄlGŌŽĢVŪH‰2žw³ū¤q!£$[Ł—™‹°R6‚…°m„ƏSX¹®”C„zŁCĖŻgŲ&ü-/āųÖ¼mN¬‰4}ō į䄨O·Ų ¶}iņꔮ lŚā:wĶÖŚė©ØUx$¬¢ØˆSXYĪxZśvšNY»rC÷˜&³ÕŪŹ»Ł ꋓ¶øŠ—.ư(ėņŖ K1äŪRĘ\½H„É&¬æ²•õr+žĒ}cÖwEÅaāV|†Žčęę89'¾ fŁļn\`Vśe6ŹOß&/¬œ w¤_7ą:Ķ]±Óu+O)Æė3ęīc–OZXŪ%Äą…uįŚśČ΋ކpğMXi¢Yŗ‰/±‚Ÿ¾ž.ł«[éöĶsAyé>¢4‘°Š¢"Naub–įs›ŃÓ«]…¹„nėīe•ūs6¹®E¶%ā;H*W¢ŸD…KWqeM‹Ū7‘•> Q”#Ķ&¬$ń°?Ę 3UÜq kŌē6D°óVīr×acŻ©${Q]øéۤㅕkĀqD +Ü9Šļu;Ż9ūqQŗŃéręų®MKlņĀ:Õ.sL²†€?¶ū%ĮÉļ7›°śkEEz4ī”˹”„Ż 0 NQ>¢ō°Š¢b°„•LR*kƽ°ć±DS;’cwTŚ$°¤w"xD¶t]RšÄ˜e×±ō"¬d¦"D„Lbą»TÓ,a%’äŗsī,óĀJ÷,ŁÕéŪ¤“«°uŅhĮļ‘qĮÄLšĮæÉ:NĻlĀŹżćÜŲž1ל…ut„»VdQ#ģéėqÜśę}īŗŻłņŗHQzHXEQ1XŠP"h«lE=”ĆxIE£l„NÅLv胯wĻīäa’®U*]r@>ÓšY§½ +IODKŒkņ£įuaāÖnī)"¬§[›ż0×0ĖŽ·~œח$­ōmŅÉUXi¼‰K·o™Kž=kłN·o’„ҳ…»„uu}¤°Ņ…ĻżįÜøV~y6a™¼V¢ō°Š¢"NaE8©ĄÓ#A2Gł£ÓVŸ¼‘“¶(÷gŌ8*°œŸy£¢¦‹QfyoĀzķ㫜?ŻŃQQ¤'Na„ –.MįķȂå#Žóń·‚č”D*¾ķäܧ-Žy›õˆ\…č^ē|ų¼…ļR«“Ÿø©œīė…•„(ĘPÓ?G¢ńý®±Ļ ē闇…•ÄØš6Ąµ$E”G¼ø¶Ēų6’ĀÄĶīüi1^/J «(*ĀĀŹ'n&Ÿ4¼(dVŹ Ņd<•īB>— å;SD¦©5˜åČo‡ąPĮ"¦ˆžt[2~а½=o›«ŌĻø½Ü<:vƒ‹TéĪÅń~č*'TĀ> Ī$¬œ“8Pi3¦ÉæżŗtĀĀzó3«S®…Ē‹M6aeˆ ß«’„Å9„²īōäĻÕQ&ß°RQ5c͜/Q&I[Lr ū"¬dV/²2׋OhŲĒÜ»ģżIķn/¬öfįšz÷ó{7מĀū–¹g€ózkī6w\~;7t9sķ[厛kå§z¤į@”ζ$£¹rķzüh| {~­KlŚ×ž0ĻLŲŌ#’„‹„Uaa„Ā\\ِŠ4_™Zķ"ÄlĀŹr¢0²E™Ķ‡qLD!Ā™`£Õš'LN€x1ūŚŌÅu.+–r¾ÅÄļʧV9””Ņž»r—™d’ļ@É„ېĻgŗŽ%ƒ°ž2l‘;O%Ū/Öxaå˜I˜źqM,4 ÜÄY„•īR„Œód<8|Žū6Z ŒŁĖw:a#‰aóē‹čøo_黜"¬¬£Ū—cEŲŲę© R^XI āčą˜ˆ¦Ix¢K™.kʶĆŪaŅ-OłlCBJʟćo—¹|ī„ …Éåuī9#šåøHź:ń–žŻē¢t‘°Š¢āŲė˜ŅM‹øņg vįŅõIa×5xg(”,Q>aAčHŗįS–Źq")‰o9™/¼ļkŸXå&“@42ö…1ū MD2ųż2YĀĀÄ ų‘ąĆTxD6Du¾LŽc=џ_Ī·¢DÓD·Ł*m2S9®Gä5±ŒžVķÄā.—q4$u_ĀŹy1 ć“;O+J\?‘Ÿœ‹śŽ–Łš8_]h¦$éČwµm:|J#"œ› ŗŸ3Ή(:}ĀVDį§K˜cęŲZĞOn¢öĒ|ĮĢöųėßa~#ˆ^YOä˶\²»y>üżDpłŽ—$.Ÿ.HXEŃA&&]|™ąGŠń£K˜hޱ“šų•&bĄx]zŻ‚X?¢fų‰ŹĄeŒ±NYü¾(?ż*p2„)‡}ćwī=K]×0]į29„?ß=L”LōŒXUœ­‹‘2™ŲS#ĒE+ūāŲ¼xĀłs]č „‹ŪŸ'9pģa’0ž|ł]Xæ?Ž‡ä«š±³}ŌżČ÷†† ƒI‹źz\;OWņŅŖ]ī<9VŻĻ¶ū£1µpßhøtłŪs7|£Ę~yö±VĘV×ד$·”Éd…bV™¬Ą¬®~oW&p&ˆVŸ~[c«2Y!š„U&+0sc­³·šƒ/š)ŖpźšEfŻę¦ä2™¬LĀ*“ ¹±Ö{–FŠźĻ¬ą>2¶Ź °L&+<“°Źdh‰„3½:ņ»ÖoYØL`™¬€MĀ*“Øń]ėy#S3„¼ [U“*“®IXe²µØŁ˜4Ė’LVų&a•É ŲÜlLÉ aͲ$“‡IXe²6?Ó!VTO¶Č¬ÆQ“*“ŗIXe²72„/ŗ™y\³,ÉdEa± kgg§éččBÄH{{‡™¹¤ÖT×¶D®B “+N‹UX7mŚdĘO)7c' !āäµ ĶŲ‰‹"× !ĘŖ5ė’*Å*¬«×Všß\3ĖpĮL!„¢ąłł„3Ķ̲åI‹ĒbÖc¬°śO„BˆBęŠK$¬B!DlHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„r¹d¶łżĶ Ģo®+3^ ÷]7V!,‡]:Ē\ņĄrsļčJóÄ[ĶSoo4½¹ĮÜ5ŖĀœ}÷÷SPQŪEq±-ēń·6˜'Ēo4Żæ,rŪ#.ŸcF¾Rįö“+—?¼Ā|q’ŽÄźŠGVøcŠ*Ūsį}ĖĢA žū6ģł5fĶę&3kłNóŪęGśQ,HXEIó3+"ēäEµ¦®”ĶģŻ×iŚ;¦½3`O[‡ŁR×j^›QcNøeadaˆ¼f[qHŲg×ćž~šÅ³{ų2|‘ٰ­„k?¶sŪ¦-‡±³¶šĆ­ §—• ‡^:ŪĢ_½Ė•MY­ö<£5e‹9ü²žķc ¼8i³Łg/Ų®¦}ęŒ;GśQ,HXEÉrŠ…³ĢՏ­4U[[œ5¶“›kźĶVĄFOÆ6o—m7ė¶4›¶öN·‘<ń֎ŕ؁F$`{ż^¦ū!?ųśz·Ÿ0;ۜųĶ_]ßcĒJC ½¬\`ĖŖ]Ł•5Ķ.:}t܆üįöņČķóĶUöÜŽ±×{ŌŌjsģõŠXEq#a%ĖIV$é~“šéÄfŲskĢÆÆž×µį=õ¶EęeÅķiėt;ĘF®D„įr<ˆŽÓļl4m¦|]ƒY¹q·×ĒßÜéÅŅõųŻöĀŚČõż%,¬3—ķt’ŽņB  «(IĮg¬Ņ-Zß¼ĻÜņ욌c‹G]3ĻL\Pk: ³u×^sŽ=K#ż~wć³bĆnÓ²·ĆŒxqėVEX—V6ęgäsˆ½\ ²}·īÜkÆ{‡¹ééÕ)bœMXŁėø.G^9× 2÷kĪ=¤QīEą³)öCF7Écœ?Ÿ*±Ļk_ijŚÜś+]ѵq!a% "Bķī=ķnl/Ź'KwøīÄåU»čųåDJ^VŁHīų›ƒ.F–Ÿu×bmķsQ‚ć·ÉÄ`+Ÿ!|ašģu oŽX‰ī3õėh8šŻ/‘Qä…÷u7NHÖ Än[JOŪO_RēöH‡»Ę³ +÷éŗ'W„”Ē9½:­Ś5v–ŲʁVDžØšˆ™,cʁkõüÜž›õˆ5ŸłäŅ“ D_°Š’„nH„•Źœäš(Ÿtč~¤2.[µ+%Bū„ ¦-ŗ>Ÿ~gSJåO·(•8ā0qamÖJ|0„•nX¾£%ŁŹsœåØkR#j/¬t÷¦“D„Ø:Ń{bU×ņ'ĘIaoĢŖIń?ār®“V»nōōš> +ݽ\gæÜ3üłµīœVnŲķ’›XĘøģf©īµĒĶų9IjédF#iƲ‘å 1$¬¢$! A Rö]·Q~fJ"7Ęʆ½ąŽ„¦ÖVü5ć‰7?³&—Qlٱ½lŻĪ•¼Ö{^­ˆVʩӅ&±ˆ.f’M*Ń;™½¾Ł„•æćŃL Éät×rż\ę—•ae¼›„„sG.‰„Ļoų *[£Jˆ¾"a% ćl^ÄČx%'ŹŻ&mvBA…ͧ3~]Āt+2ĪGÖ+ =“ö„ĢTÄuIEƒė—¦Ų…•†ĘĆc«\ƒOmH”"ze,–FƼ•»œX¦—§°2fīū×R²„ $¬¢$q‘¦*_*żē'nv]‚į Ÿæ#@7>µŚe‘RĮ3NJ·°÷įŪUšötøÉ÷żņtz}½˜+.DLqč)va„ė— c¢Å'Ęopׇn÷[žYc®xxEĘĢč8…•nś©åuĘĒfΊ]ęø “s©œ~NBā„U”,tGŅUIÅM„Ī·—Ÿ…ŠU|ÉƒĖŻ˜)¢JDJåβpL‚Ąöé™Āé)̧&t3”¦ŸF a-[½Ė1¤C"›ž+ßī2ē/ĀJ¢ć×|rC÷šw”»mNø¹{Ę%OœĀ ĆķõćŪW3cgouūē“(`šJī#©Ó‡hnd±#a% CGԊx"|tY6“ģs•²ż§Ėö„rGDč¦ā§G,™4‚m¶Ā@µ@Hbbl“iŠĆĮV„pćö=‘0ŹwŖlƒ°"t}Vą‡jėƒĘ׏d!ĘVń£k˜®÷‘ÆV¦$ Å-¬L…ČŲ9]ŅD®ōP6ēXŪ°×÷łŖGW¦”'DHXEÉsĢue®‚ęӌuÕĶ.²¬ŁŁź~õ†oWł¤ƒČ• ؐ™"‰łÉ~e¢U›²fū"JLFĄ¤ Ė„Ewæ;?½į©Õ‘ėū ćÄ|;Źyq~™ ŁĒw3 ƼU»œŃž.¬DdJÆŻŅŌõ >ˆń”ņ:×!Ņē„éKv8ųŞ ŪöøuˆSśŁ’n~fµYoÆ+=ĒۈÖŠŁ†īåØY’č^ęzń¹Sz/ž7ŚūŹ=äžq~ų®µ ›¹+wŗńW> o#DHX…°PĮ©‘ŌD…ģį»S*l¢„ūĘT:AˆRéźd¾Yürłqp„‰ń?ü3ż`9‘V°>žI (ӟW&ŲxD–噢q½|×ī™w,v ŗ‚łńr¶ēŗ'IĢüīüķ]ĀĘö”CyQ įewM³¬ēœĀ÷•æs,łøĘB€„Uˆ”ņ?ķ¶Eęé·7ŗ9pIń“Č‹fš¢ŃĮoŅņ«2DŹü’ p,[ø¶Ž5NčŖ•ø‰ż «}± Ė“ĻfĀćzł†H‹OI¢¾ÉĢßjęŒ;ÓՍø2–̤÷Ļæ»É<óĪ&—ŌÄ2fDāĻL?æ'D±#a¢H`†§ŗĘ೟\!¹ˆŸ|‹*/ŠŠ`¼™hžń\ĄülG$'1Ę9~ī6÷iRś˜­ū V!оŸu?2N$š#Dø½ży¾ ń‰ßd„k8|,üPŗ†ÄžŽ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*zå€ „ÅLŌ{-ņ‹„Ud䱋fšĒ^žfʎ{ÕņТȸļy‰ėP a9äā™fŚ„ĒMū“’g:¦ž„¢ˆh›öóĘøŃÖ!@Ā*2ā…51õOŒ™jo«¢h蘜+¬ÆJX‡ «Čˆ„UˆāEĀ:tHXEF$¬B/Ö”CĀ*2"a¢x‘°V‘ «ŋ„u萰ŠŒHX…(^$¬C‡„UdDĀ*Dń"a:$¬"#V!Š ėŠ!a‘° Q¼HX‡ «Čˆ„UˆāEĀ:tHXEF$¬B/Ö”CĀ*2"a¢x‘°V‘ «ŋ„u萰ŠŒHX…(^$¬C‡„UdDĀ*Dń"a:$¬"#Ö ¬ś½IlȊó™ń×©ė¦ż©I¬8Ź$¶=c[ī6föGƒåÓßoėĪ1‰Ś—RŁž¼ITßokN³¾ß]ĪÜOŚå÷õōļ³üp·’®2Ņ™óĻī˜Ūž6fÉŃ>bæAĀ:tHXEF$¬Ń$¶>föŁLģoÅšŸŗ×M{Ÿ·#LbĻ:“H“;q53?¬›ż&Ѽ$Ų®sIģŪŠ^o’½×$:š‚ņŹ’Ū–cÆwł÷M¢uCąĘżGv›“u¦ņ»ķŸuO:óæbm[|£|Ä~ƒ„u萰ŠŒHX£Il}")¬o‡„õ=Ę,ųŖIģžgEµĆ$vM4fŽg»·CX÷¬ Öķ|Ә•G³ā×6śż­IlŗĶ ^uPfĆTėk£Ü™t‘±Y{F‰ ń¶müģ6įuŽł_ŽĆļ3Žo_m ¬ė/öū Ö”CĀ*2"a&RXē|Ģ$jG‘ŖW³č;©Ūu «]_}æ,ßŪ½nĘ’sŻŹ‰D›`Lbõ ©Ū†ü{*ܾ]dåÓ֒BĀ:tHXEF$¬ŃōÖYkÅņĮ@°Z+ŒYś³ ;7¼]oĀ 6ŚLģŻˆė¦į©ė<ƒ-¬tm/ś®1ĖDĻžŹß³ų‚ˆŗĖļOķ9h×ųGEĶ3>`̲ÂķēüKźŗé4DVŲ(ž2`éĮöŗž]ŖŸĆ^7ʒWķ®»)ū¼żū1öų~×ō÷GlSšHX‡ «Čˆ„5šaū)cHJ"ŅlŪfĢŚÓmåžē=·Ė&¬e_č^OŅSxg0…uīĒMbó¶”Pœ‚ŸŲg·mµ €Ķ&Qópw“>óĆ&Q÷š]ßi;^„6½<+¼‰½[Üž]ĆĆ/Ÿż¶!1"8ÆŽĘąŲŲĒiĖ4KžĻś„F÷n {_1•›DĆ“ĄßõĢ5fŽgŗ}K ėŠ!a‘°F“"¬kĻ“‚±ÉŠĀī@¬füUä6Y…uɏ“‰LVX*ĪK]ēLaµQŖPŽ™.ī-#-÷Xį|#ĄŽędēa#T1ŗ„*+žfÉORĖ"ņ­ŗ&ęśÉ6bż×`łĢæ¶×ņÉ ¬ęeVČļ4fĶÉ&Qu•õ›”×0݊åēŗĖā“VŪģŪ ¾—=N3Ļ6t¼o‰#a:$¬"#Öhŗ„µee Ŗʖ»2‹*„…µę Ŗ£»ę’{ üײŚFÆ_Œ.c0…uŽēķĖw’Żęk©ĖgžūŌ(altŗó­ąųY>ߖݼ"ĆŖ+1õŪ̱ŃoÌą:‘tå—Æ<Ö6&vŁsZgĢā’µĖByŸ5‰Ę9¶<)W^Ō½Ü +×ߊŖŁxcŠeĢqŠ=Žo‰#a:$¬"#Öhŗ„•ˆaHtS}Ÿ(G—°ZAj*w⚨y0ųŽ•h ѱ幱°Ą„LaM‡±K„kę‡\²;+|]Ā:ķĻl$nω†CĆ“īØ}7ˆĘé*_üĆ`ŻĒŪž¶žĮ7Į³ž>Y¾ēCA„Ģu©{Õ®’H°]XXķśčqXÖ”CĀ*2"a¦KXwM°•ūŻ6rŚķÖ¬±^&QōĀŹvD{0>h‡īL—$Ō[ņĶ` +¢¹šæ¬Ųk#ƛŁś¤Ću½rs»…–fĖÆ³×¢!y|ļ±ėmd¾ń–ąœw½kĻ!9”ƼĻ ®żÓ—†ņŻz²¬Ėf»°šÅ?źŽ·č„u萰ŠŒHX£Ic]šŸ6ņJvŅ„¹4ÌFįˆu×;Į7¬+Ž 2\ˆ¹Ž.Ģ` +£õqŻŻL^į6źō桜ŗ°…Ņ}Ė›o dLļ^`Ļ»Ć6Į±~-«‚ɢƧI– ;KXsFĀ:tHXEF$¬ŃD +XA 2]ÉšŻŒ£śÉ JX÷?°ā—=Yōm7VjHŹ"šäóŸUæuŸÓ˜ņŲåw Ī?JXoQ“å:°/’“ę~¢§ŸŻ¢źöĆ÷ŖĢģ“ä§Įw°Ė±’>1ˆž‡öŪHXsFĀ:tHXEF$¬Ńdüu(ū7÷¹‰‹Ż ’ć­v9ĀjE*Öū†FX™6‘nZžclÓ%%„a#U÷éĖĀo:įt3.1CóR+hĢĀ“ĖžĒŹąĻLĀ:÷SAĘ/×Čuõ>d—g8ßæ²å­°~V„Ibā×wŚj’ f`ŖsBŻåßu léÖ^‘°V‘ kHŽ©Ÿčfr]•)ėßć¢­ÄŽ±š–óݦ]FiĶĆī““„Š“ä¦\˜ńW.ŅLŌOrc™‘>½a‰šGįĻÄĘ[ķ91тĀ…_³¢xošYŸŲŌ2{’Ų$ƒuS/F ę{‚s„ĮgHĢ#ÜĆ' ¼ĄīgÓ0{Ķ^ŽĮͤd’^óI0GńĢŠoŽr ųĒ]~Ķ'T–HAĀ:tHXEF$¬¢Xa%Ŗ'ZE‰€#żD>‘°V‘ «čD nģ“͘µ°ĖśŃķ-Œ„u萰ŠŒHXEŸ!YĖeG·ŗ1e³šŃ~"ļHX‡ «Čˆ„UōĘqėĘø¤#—¤õzbP°V‘ «č;$j}Äø©f}8b½,$¬C‡„UdDĀ*Dń"a:$¬"#V!Š ėŠ!a‘° Q¼HX‡ «Čˆ„UˆāEĀ:tHXEF$¬B/Ö”CĀ*2"a¢x‘°V‘ «ŋ„u萰ŠŒHX…(^$¬C‡„UdDĀ*Dń"a:$¬"#V!Š ėŠ!a‘°īß$śó›°¢h°V‘ ėžKóĘ9/}Ϭó% ģ~Š„uč(xa]c…õĘGf›ĖīƒĶÕĢ63§Ž6Ūgnł¹Ų˜ōŹęØĖ^7ēßņ¤Ł<åˆHQÜlq”™0ńsyÄ»-ņĖ5Ī6ó°°677›;w !bd܌*ײ>uŲ³qKm¤¢’466&U,‹UXe2Yü6µ¼Ī ėF”›ĘęöäR™LVØ&a•É Ü$¬2Yq™„U&+p“°ŹdÅeV™¬ĄMĀ*“—IXe²7 «LV\&a•É Ü$¬2Yq™„U&+p“°ŹdÅeV™¬ĄMĀ*“—IXe²7 «LV\&a•É Ü$¬2Yq™„U&+p“°ŹdÅeV™¬ĄMĀ*“—IXe²°D˜¶}folwĀzŚm妮¾-ҧ½Ć “É Ā$¬2YāųĘĢóčŲ*óH×<¶Ņ 믯žgīSŁc=¬Ś°Ūt¢Ī2™lČMĀ*“€uv&ĢÓoo4‡\<Ū‰h_8īĘf„V™LV&a•É Ä6nk1'ßŗ0R<3qŠ…³ĢƒÆÆ7{öv$K‘ÉdCmV™¬@Œ1Ög'lrb%¢Qüž&E«2Y”™„U&+ [_ÓlNQ)¢éhųŽW+;öĪäÖ2™¬LĀ*“ut&ĢSć7šC.É>ÖśŪę›Õ›’[Źd²B1 «LV`ĘXė)ĆEŠ©ēĄ f™_[ﲉe2Ya™„U&+0£k÷™w6ö:ÖzüĶ Ģņõ[•É Ń$¬2YŚ2„‡EG­īČW*]²“L&+<“°Źdh>jżŁE=£Öćn˜oVV)Z•É Õ$¬2YŚ†­Ńc­½^„hU&+`“°ŹdjQ³1żN³,ÉdoV™¬€ĶĶĘ4,˜‰±U¢UͲ$“¶IXe²¶šlL̲Ädū2™¬°MĀ*“ø1Ów,Nβ¤_°‘É Ż$¬2Y³1½9g›Ų–ä™LVČ«°nŪ¶ĶT®.BÄ̊„sMÅŖčuBˆ±iÓ¦¤ŠÅc± ė†Źf÷ōƘ}Ó>,„B<­ÓžÕ¬[6)©bńXĢĀŗÜäæ3Õ+„B8S?`…õݤŠÅc¶äųLĀ*„¢˜° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!„"F$¬B!DŒHX…Bˆ‘° !„1"aB!bDĀ*„BĈ„U!„ˆ «B#V!J‘iļ3fĘ’3fś_Śæ§{łō?7‰Ķw™ÄŽ×™’oŻĖ…9#a"Ģ“?3fĮ³ä'ʔ}>bżŸŲå_“ėlĢĀÆ[!²ž~ŻüÆŪ„`żŹæg·±"ŶŽwę‡ģņDų÷ĀģģŽ>Šiļ5fŃw­ÆŻēģŠöń,ų“Ųž‚ITßg̼Ļv/·b›Ų³Ī$ģ¦üæS·B䄄Uˆ0s?i»ĖL"±ĻFnwō\oÅ4Ń“ XæõQ+,Ÿń“hœƒY:ķzO»I“ļ²e.0fķŒ™õ‘ĄŁa&Ń¶Ķ Xźli’%:ŒYu\걤3ēc¶Ģ­&ŃŃlĢź“ģ²P$šĪŠ_ŪRķ~8¶UĒv/wĀZįÖIX…čV!ĀŲč-Ѳ<Ä-÷¤­ū¼Iģz'ĢŻsmtųm»<)^!AJ4-“Ńą³&±ķi“ØmĶ”×fE¬Į˜Mƃ.Ų_ "Ęś‰Ż4Ī5‰Ī=Į¾›ŹS×ķš`#џ¦O:sžÅī£Ž–±×ŠųvY/Āŗų‡öęŪrķĖ_žżīåV!Œ„Uˆ0™„uÖßBI¤ŗg1KNķŚ Ņʛń¤›xśŸ».eĘ,]™mÕVæe·yo°nś_tc…,ŃŗŽFœM.¢LYŒ‹śżEŃae+÷ż™ĻCĀ*D搰 &JXgžµ1UW¹.ÖD[I¬9%UŒ EXo“‚eE3¼ŽF·‰}µNō•—ŚeVXĆėaį7m•v?»Yž‹žė³ŃaåųfżmŠ•ĶŲ¬_ž.¬ˆłĢZßæ ł’ijYĄŲtø¼üf| äk‰3ĘģÖūrķ>ŅÆ)°Ģūr,$[łr¹/4^Üß?l×G—+ĆūŲr¢Ö 3V!ĀōV+«O“¢øŻ ^£ITœg+sé„o—MXg’£FķzŹ­¾×VöC,¬K~l÷µĘ$g3’ĖŻĖĆē±ä’lä|¤Iģļ"mרhœcLŹVج †Ė³Q8ćČ®¼%?q×ĪEß{7›DĶ£Éóµ0F½åī`œšu\×½›L¢~Ŗ1kNµ×飩åĪūŒ[—hYiÆÉ&±į:ūw{ÜĖĪq®{Üu½Ó‹°ņ˜Ōm=+cÅ^׆飓ŗ„ˆ «aĀĀJĘģŅm„½ÖŠU«Il¼)ˆ’¢¶Ė&¬ó’͊‘Ä>żyÄŗōgAC”uCIģ—‡Ī#±óM+|uų5/s¾īŗp-¶Œ“×"™øtc#.Qk^ąĆ±°}Ć +¬6ņœõ÷w7ŽĢņ–VŪQ.dzžņԆ˼Ļ~ō°-āĒ1ŁūāīĒ™čp]õ)ĒäxÆIŌ¾l×wŗ?µŠĮ@Ā*D˜°°6L³Ų,'T‰ķĻ[įśēčm 7ań×&±łö Ģ¶­īS—”m=…&¬ˆŲö­hžŠeK»ä­šķyXalŪfĢāŁm’ūšĀŹˆjŻ»žlƒā߃ķń³Ńh¢ö%c6pēję~*(wžWŗĒÆwĻ·ūłt÷ńxaõåŚ{b–|¾DłV°ė/µėöŲżo >•ņŪ‚Ż¢ŁnoכUæ³Ėz¹&BĄ„Uˆ0]Āj#œ};œH¹?]7c/•rX¶?ė>§1Ė>kŁroɹHļnēYF” kĶC® ;„œ²/ŻŖ>¢÷]Ś^X‰w¾ˆf×v”čœcžžßŗk]„»=UĆĀŚ87Ł(ńå%Ė/ū’=¦Ŗą˜*ĪI-Ķ)ö<›\ÄŻCt…ČV!Ā„#ÖśI®2wbQ?Ńe÷Fn)‘ž,¾Q„»Ņ Tŗ>Ŗō±É0&¬fń’¦n3?ä¢Q÷­īŽqA/˽°Ręź{n†$’ęŁ6<~Œn¼Õ7³šæŗ}½°ŅĄŁp}j9[‘°_>š‘ģ®Ÿł7&±õ±ą^n}cb<įCˆ™jpŻM¢q¦kšĖ?]Ūš3~ü~ē§–c«|gkė)f”ŗÅą#a" ½3¹‚™© ‘ SÖ3ūļZ%*²Ń•[ŽŪ·Ŗ½A”Ė·²óæd.ĆŌ‰½Į±»cųJflTėŽ•H›ćēGŪĆS²Žet’²Ü m×y1‹×&ģļįŲŸ=öLŸ$ÉNs>ģ›ćįOwL¶!2ļ3ĒĆ9ŁåģŪ’–moĢś[+ÜS¬°všDķ‹ŃĒ*Dž‘° !öŹæļ"žDgs2rī%KˆMµ&“Å`õ¼‡õ=ß1ę€>ęŗ2sŅ­ Ż;™¾ŲVV|&aŻO9HGO«6ēß»ŌĶģęōåę  g™Ÿ]4˜q{yõēŽ\b^ŸYcŚöu&K“Édż±}ķfŌ”-īJĻN¶Č|ńlsč%³Ķi·-ź±ž¼{–ŗwX Üā3 ė~l¾«‰©šśŪŠ‚–Éd3D‘™³z‰z×zć˜kĖĢRūˊĻ$¬ū±µ¶u˜;^Z×5Ļl.ą;üłµ¦„µ#YŠL&ˆ5ķiwļԁ̊|ē¢ą=¼ēÕ ½‡EjÖżŲh-/­ltIJQ/oæ¾zžY°ŗ>Y‚L&‹Ćčb<5ź‹‚_5*_«hµXMĀŗŸ-Ž;_^—skłŽי={ÕJ–Éā4ęöÜ—ŪõŽ…įoči¢ĒIVœ&a-£åĖdßQ/q¢ÕÅė”,!“åĮx·xǢ޽0G_[fklµØMĀZFv/-ąŽZĖD“·½°Ö4kLG&Ė‹ł±ÖØ÷ĻĆŲź]£*ĢŽ6eä³IXKĖ­otY†Q/3Ń.\So¬Źdł3ĘZ‰H£ŽA8źš2÷m¹¬øMĀZ"ęĒZ£^f¢Õ[Ÿ]£V²L–gć=t½G,»ėeeļ&a-#-_ż]+30-R¢L6(FĻPTļŃq7Īw館ųMĀZBęækMk½Ó.ÓŲŖL68FÖż-Ļ®Ił¾œ^£/¬5mķź5ŚLĀZb–>“fY’É×¢fcāW¾9—ķ&a-1 ĻĘ·i–%™lŠ a²š‰TƒY–*M‹¾ßoLĀZbÖ5Óµe…šeI&›æ:˜É­*Ēaæ2 k ź]/ÆsYšeI&c6&¢Ö»GU˜=šeiæ²X…µ¾¾ŽŌŌԈ"`ŹÜµfNy…©®Ž^/ ŗŗŗä›6p#K\ =•5Ķfͦ¦Čubp‰ÓbÖÕ«+Ģń‡½a~öWEsŠ×ķŸ±N‡o“™:±Ü$bšo’RZZŪĢ[S—šIsV™Šµ¦£3aę/­2Ožmī}zR†ŹorĮųĶŹģ·©~÷<5Ɍ|jbVæšś(æ2ė÷T ~•%č—qUXW®Ø0ßžųKęćļ}V#_ų«ēͤwāÖķ;w›£žxæ9čų;Ģ­¼i–®Žlž3Ū~źHóįÆžiŽ’…SS(?+‚Q~™ōöą ū}±Æ~o9?ÄæÅį·Ŗ0ż~Öæįqś`żŹŻok]£a «%F¾„õ§ßcžæOožå;ē›ß’ˆ™6oysņsĄļF˜śÖ¹n]˜łīŠū‹Įļ_Óü~šÅozVæ śēw\L~eū‘ߤŁß7ą÷½Üży†Ł³wŸ„UˆR#ßĀś'Ÿ:ѶźĻ0ē\÷¼›ÕęYAžrŁęæyŽł“OŸŲUyæsÆĻ£ß„ƒļGÄür8¾^č.ļ’dzūĪÅĻī·?|v·ģ•° Qjä[X=ó•3̉=f6lŁa–¬Śd.¹õeWA…}ŗü.ī£ßJļwFÆ~‹­ßŃä÷”(?»,“ßĘl~vżõ㘣żĻŻÆ:éwKfæ“śčW¾bć śiN²8˜~g^żŒŁŻÜ*a¢Ōȇ°īlh1ĒžūPJ%Ckžæy®¹aäę­)KĶźŹ­ęŌĖžģэ60æ'äDz°‘p®~ģ#Ņļž>ųMķ£Ÿ‹Š"ü¾•O暬~ćsō˵<üVUŌ$#Ņhæ“ū-$? «%J>„µŃV&—eŽ’łSR*#ųńo†»Źˆ'FĶp +ņ;¶§ß_dņ»7næ±!æŪģwSžüļ‹ßļ{÷[‚ßĖ3́~ļłäŠłżæū†Ęļę ~V!J”|kŪ¾3wqeęD "JhŠ#ń)=”)Wæl‰OŁż’‰6}õĖ–·_>•╨”«Ÿ\%¬B”(łÖÖ¶v÷ >tćŅ=FיƈHģ`<*œŠD÷ģ€ż’ 4½ł1&öóŻ®Q~>ĮgHż’Ż‹qų‘ø3pæØÄ§Įńė™ 5@æ R™üB‰O}š»ģ¶WL“’—„(=ņ!¬õ-®[Ń%eK@Ź5”©ß~=Oœ_2±Ø/‰OŁü|"PŸüģ²l~™•¢üX–īו U“Ÿ=·”„¦^üRšbō‹'”Éśå%”i§ók£×½ūŚ%¬B”łÖŗ]M.R½~ä딄”Ģ HCå7 Ré~™•rõcĪoj~÷äX^Ų/”eōóūĶā$4 byßJõó‘ę`ųł„¦ ͦӾV!JŒ|«’Üę3ÜUF$v<1j¦q H_HMü،?mśą—–P>ń©čżŽµ~÷ęź$ŠxæōD›žłmŹčē‹rõ 6eL¤Ź»ßĖÖ/CR^üīk¶Ö6hę%!J‘| + ‰JĒ’°{ź5ØĖ/{ĀPÜ~æ+`æÜŸ‚ļ—-Q)Wæ>'>åź—KbQ1ū}ļó˜_ͼ$D ’oa%±ƒńØs®{ĪL›»Ś<ūZ¶„¦ēĢŌ¾ųÉę÷|V?ĘūētFś]Ÿ›ŸKÜIśeKhņåÅå—}æÉÄ"ėGBŽļvĶäĒ~sń˵¼œż’ Cƒ¹_—ų”ō˔Ф™—„(Qņ-¬Dī„”JTņ~+³'õŏD›l~łLTŠņc™óĖ–·Ÿ½yMh“D„ųšō¹%J>„µ·™—z$„u£ ŲĻ.|æxš|„›Ķ/SR^üī±~ن ŻĻ>CųåšųäĖėoB“„Uˆ%ĀŚ5óRdŅ0W¹šWfŗŸģŹź7*Wæ½ś C݉6Q~݉EūŸK| ł„%ŚōÉļXü‚ĝL~>q§æ~™¼_Ø”k‚TŒ~$*åģםŠ$a¢Dɇ°2óŅ<7óŅķęcß:/„2‚ž M·ŪÖ’ ų}7ŻÄ“\żR#–Tæģ‰JCįG¢MÜ~>įŠÄøż†,‘*›_?š$¬B”(łÖ®™—2$ ½÷S¹%*åźG¢H_żH< ‹r(/«_8Qi`~Œiö'A*c’õ#!'W?]2ś}µŸ‰TÉnŅžūõ-‰ņ;”ÉłŁĘ˜÷»\3/ QšäCXŻĢK/ē6óR® MżO|ź™xŅ'拓~+³ū„$*åźg—ÅéDzŒ~ÉD \ż2%õĶ/”€”ĮsĖÕÆÆ‰O.±h0ż4ó’"š>óҚʭęŌ˳' 9?»]ģ~vYo~$ž¾_ęħ°_Æ HłH|ņ‰@¹ś%#¾łŻ“ŻkN,ŠĖÆ/ūÕĢKB”(łÖī™—†¹Ź’ØšI•NˆN“éN@:?— •«ßńqśõ–p5<%Q)W?m2&*Åäēwśā—– ™äü‚D ^żB MƒķחÄ'ͼ$D‰’Oa„¢q‰Eē=ģĘØHŒį÷*?–) ædĀP®~Äįēh|¢Ræ M¹śČāNŹæ39õß/5B üŗŸHÜLæ¾$HłD„\żzOhŹĶļ±—§kę%!J‘| kϤ9ę4ŗ…晚åēŗćōKv»öī$ ŗß˜l~Ż >¹ūŻĒa?mrõcĢŠ'õŏnį‚ö»4»ŸO@ˆŸf^¢DÉ·°zØĢ»6'|āNhź™PŅæóąGbQWā“]闖X·ˊŻ/SĀPą—CB“]–SāS—_€”=”)³Ÿ>·ÉŸžóēĶ×’éUĒgģßÓ×ę/ž7’õÆ˜o|ģUół¼ŠµÜoĒņ0,ūĻæe>k· —ó„æy©‡oo|ķ^1ŸśÓēŗĖų“gĶWžöe[~p,ģē?ŲĻū{soPę×>”‘ūüźß½yśĀ'ķ>~ż£ ꞛ—™3Žšn>ł¾Šyˆ>“aĶ<óŅ9]‰6.±(cBS?ż’‘\’żŗ†ŹÄ¢ŲÆt•óeŻßżl[‘Ÿi>öķóRü(õ¾¬?żĢIęļ’ė,óŸ_mīz|‚™4{ePž®>ńßöŲļ~|YŠ_Tcˆ’ń³ ¼‰³2ūłóčWBS®~†¼_¶¤>łŻ3p? kž8čkoš-›šMŚFsģO'¦¬CN;ršY³¢ĮTon1ē?»kŻ1?™hÖ¬l0õ»ŚŗŲµ³ĶŌli1Ėķ4#oZfžļĖc»üÆ=wŁQ·7Åæ7V.­7æųļwܶ_żČ(sśÆ¦›‰ć¶˜Ķšķ~öšķŪZMł¼fųåNdż~²ńżĻ¼fęĻŖÜēśu»ĶœiŪĶš+›Cæ9Ž|ŠyTŁ !ņę+M[[§Y4·Īüč ÆGś‰Üȇ°ŗ™—†÷2ó’¢½¬‰E¶,hædāN\~·>š¦ilŚc*6֚Ķ[w¹ģźZ˚Ŗmę„7ĖĢĮ'Žéʞ]y6źņ WłÅSͧp±«Č'Ģ\aŖ¶Ō¹{Ąų^§½ÆU6j¾Ó ćŽŗÅ¼ĻŠÆß'žd®āGäu|ßłÅ fÅŗj³«±Å”-Yļ¢=|¢©HÜį‘*'æ{»żH@Źģ7v@~Ö<€“·'LcĆ>ó+^~9¢rä'˜å‹w™ŽŽ„™ńīVóƒĻv Äuē/0ĶĶķN8b…=¾6³×ī Aݼ±Łģn Ü÷īķ4/=^ažó££ŗŽ­7ųź8S»½ÕeĀmXß䎖ŚĘ Œ½{;̾}fÕ²zóĒßĢp{T9½ńåælžy`­»¦SŽ®6߳ĘH?‘łÖ`ę„õY£"1&k¢Ržü²&>eó#Įæ\š²ų!xĢ5Ė7Ą¼?mūŚĶśĶuf•„jjL[{‡ycb¹łč×ĻéQB;}žZ³×^wü(cƒŹ Õ;œp¶wtŗŗ`Ķśmę§ß۵ϯx•üĶn݊u5Nüƒć ®>šo§™ŸŸāÖ/Y½Ł {n‰OQ Hqū„FłōĖ%ń)ģēš$¬y"“°"ļŽŻböµQ×Į_Ņ慕Hļ÷O6ßüēW?ųÜė.:­KŠ×+OU:qü·¾d¾÷É1ę{Ÿz­‹W/q¢ŗzy½‹–Ćė¾óńŃęsł‚óÅów8”»ķŖÅę'’>Ö­?éš©fɂnīŲ==§Ó +ū½÷–å]Ēż­mžē o˜«žXfVچB»mLl­ŽcĪ9n–łōŸõM\9ŗĆųł×ķ31Ś|źĻŌ<ņ!¬~ę„ē|¢’­dč:óŃ{?u‚:;™ø—ŸOŹÕÆ+ń)?ŗq{ų„'*õߏīŽY ×%E®Ś,XZåÄėŖŪG»Ļ7n}šM3ü”ńę#’uVWyēßų‚ómŽÓę¶Ū¾c·ė²%Źüä÷/²\hžż€+ĶČ'ßuQļ^{_žzuV×~I°” ŻNž³Ź‰ >ßļ/xŌlŪŃčf:ł’Ē͟~ö¤äyt'õ~¾aæ'zų±üz$ Eų1¦Y~¶ń“«Ÿ›yi’—b'JXæśw£Ģ UøhŠu0ɍ†·óĀJ÷ļ”ߟ²ayŃF‘ˆ2]·jx½ēņ3ę¹čv…ŠĢ(DłāSęŗć ū8į°)¦i÷>wüO=°¦Ē1FÖįVØÓ×S.‘ryŁ['čnŗŸ<ņ!¬©3/嚨4ų M.±(&æūėg—±īk‡\cšö˜–Ö6sōYt%īųħæżĻ?ŗŹü=”ņM0\sDõѧ9į„‹Ņū× ܲ­Ž,µ‘'åq,¬CŠĒO[ę„yéź-ęŖ;Ęøż®ßTgVÆßjŚ;;ĶĖo–™ųĘ9]å¹ó(€„¦Žżŗ•āóŪ™Õ/œŠ¤™—ņDŗ°~ńÆ_4·_³Ä“““»ńŅóO˜™Ģӛ°Ā5gĻw¢I¹?“QlśzČEX{ƒ„#Ž‘ćęĮµ±+0¶LDLw3Ēwėeå)ė±Ņ÷wą$s¢÷q/o4³&o3OŽ»Ś|’ÓÆ9"č·šŪ® öń1Æ<]i¦MØ1œŲ=Vę§_gĘ÷?—ŗč“gxü“„.—_Iaü4Ŗ<Ę?é:ęzϱ"8ā‘·sŪoDypß3“]tE¢³ !“Ėņµ[Ģa'߯£<¢āpy.a(bæ}õKI@ŠŪÄ¢łE$HEųł)Ęƹ†֘ 냷­pĄ-¶Ā~ģīU. 'jČ$¬Į—?ō²‹¬čŗ™?»Ö|㟣+ņ+ū¹éāEN¼ŽS9Ķ-‹ņ “«°2¾Ė5ą#ūų”ĘĀŹ,‰N[66›»®_jĪ:v¦¹āĢyęæ“+‘*ŪŽµŃżŃæ:œœõĖļĻĘdß~m³ŁgļÅ÷¬¶b/ d•kMSS»yĄŽŸc~ü®łé—Ē¹å\ķŹ[»²ĮGXippmZķ1.Y°Ó\łĒ2×ū@Ćɗ],äSX©hR•¦$‹¾‘ąö›œ'æˆÄ˜¾śeMņ‰E¹ś%ø^¾4Żu“lD×8é’żö6×½Ų•ų”,ļ?æĪ‰Ÿ­·]“Čē4įņ=é.óé^ģ8 ć®a?ŸHõåÆ4‹Wmr÷oó¶]®~©Ś\g–Śćü¢gr34„”—É_wāӀż’ HŽÆŠ©4óRžšĀŹxčĘõMN0Ģ©s]—Qž/¬Tą§9Ż%-ĮaVdŗQ¼«Ī*Ėų]č@„•ć#ś¢µEę- HQ~éä*¬ąÅqy¹=¾d +ˉ‰½PńmƏšÓ…~ž·MUÅn—uĢu §ū«M05›[\„O72ĖČH~ņŽ5īŽŠµK×·÷>ė!{š{FŅ•/Ļ +ū_`6G|ļmŃŅščk"V!oaķJ@ŗ6·Ä¢ŲżrLhŠ/A*"Q)?Ź»lų(W3Ź»G„L&/Ń%ĢZ°®«¼ć/|4ŁÕ˜0?ųõ-)åĶ]\iŖ·×»±f¶÷,XVe~uę}=ļ²'03ÉYÅÜCöżĒ«ŸéNČń3He=ßšbšc|:—)ü‰E¹śeLhŹŃO3/å /¬ ‚ĮŸTīdƦLА†VD± Égµv->Ļ”+łža+Ü$QŪC…õß?ō’&W»ˆq«·“ŸšS70Ä)¬÷Żŗ½AdŖ­čŅōݲž{æ¼)„<ŗÕ›ģ{ŲÖīĘ»łģ_@<»öJŗlų+ī}„E¦1Ÿ‹üżŻ‡„”B÷Ė_¢’f^DĀ]ĮWžYf^}v½«Øē;ņ"·/¬“Z·ÕģqŸ¦Į1±ŻĄ§żršĄØm=żV„ģāSę8ń'#˜nŲšŒPŁČUX™Ń‰®q8>÷łßP2‘Ö Oœ“²M˜(a…ÓmtO4æ}ė—¬Ä2²°gNŚźŗļ¾¢«‘Ą|³Ė5ƟL:>2%j÷Bķ…•ėžöøXɇ°fšy‰ĢŅėrH@Jæ~'HE%²¤ūyeņ³böūŅ’]a¾wäMęē¦8q¤ĖwG}³ó!Į§Ö6^Uųåé÷Śī„®ņžõ{ø±@fTjؽǼ4®ĢM8°^2,V·ßP" Źō"NRTŁŅ*ó…Ÿ\Öķg÷ė/SāN’ü2'ułUf÷#a(—©Įņ“°ę‰°°’|š½å&…ą%”²g§†ńĀJ’ĢŃ?žč>‹ĘW’ķÆ_ģ5ŚõōUXŠKN™ėĆķ½s•Ūg”o&rV¾kåüyą^{¾*%9h ĀśM[īŖåõ¦ĶF§÷ [īDōˆļ½ć ĢLEWŗ÷e–d%"Ł% wš·^Ż ūøčä9n\˜ķ$¬½„P™E%ųüO2Q‰h€īĶL M¹śłÄ§”š#A*7æ įæ¾&R1„ Y ¤ĘMAÖīŹu5]Ÿr<üĀŌeŗņ’‰6TüŒĒ†…5ģ7ģĮ7»"Uö÷>źÄ•ˆ÷öGß1ž¹“SŹ{¢ėų¢śģ—į'ūzśõžØ”«_æŸśį'aĶ驀üń˜¦®¶Õe»>ūŠŚČ$¦LÉK}”/ŠØ2ž‰Š47µ›§ļ_ć¦:Œņķ\„•.[²{»½mnĪßšś+7‚J+~ތZÕÓ@`uŹųj7±÷=ĀF¬$Gqłd&\NoHX{7JI™y)CbŃoĻĖ-”)n?cśä79>攄¦(æ ‰O$M™»Ź ė”9«Ģæżäró»óqāĒõfņ‡oqCĘņ˜Š®]Äóź;Ēōšūł©#]dĖē5ĖÖl1æüýę”ē§øūHW' TįņŅŸŅĖė™Š”ÉĻ'*åźcāSžżH|’°ę‰tae‘Ļ×ß²Ņmyř=SX9žKOk6mhvĒD6lDrV>µ!YØÓÖLpAD^?a¾E“™źLۈ™9y«/¦‹;<ś½O ZÜ2‚s^QĀŚ»QJźĢKO¹īTŗĪ|EŌē¤B÷ % õ×ĻĻ”ōį’8³‡ß­Ī^Tį„õ•·˜æśŅéĪłKŗo_7Ļ|é§W˜÷„ģ7HŗrÄ«¦Ž '‰ID·įżž³ż×'–›{’×mŲnęŲżŠtēcļ˜åk«ŻņWĘ/pc­=•rKĢņ RńłeK|ŹÕ/{‚”óĖ!Ė%R„%H]~Ū«šy)D +0^Ē7˜tC’­ŹDŸų“īJ°„•Hõ¢“ęøHuOK‡KZźk÷o˜Ž„•¬^DļĶW7¹hh• ŅV²{§æ[ć®ķā;ĄV¬n4‡}»ēudŚEŽƒńk>éI?ž}ųwßvæĢć—IX{7Jé9óŅØß/5)WæčDēWŻ?»Œ.Eŗ§ŚČķ¤Kwsųś„œ +vf,wGAž~ÅS]•śĒæw]·Ā‡"® –m0æ:ć>óĮ/wļQēóŹø7>!ŒcażE·¼ä¢Łŗś&s‚ݧß/ĒĒĢA4’Ų7ć‡LJįĻ#žÄ¢¾ųeO,:æĒͦ¤ßŲɚy)/dV8ą?ʙÅe;\–/Ÿu J~Ż` +™±*›l„jÜ·œĢōĘKzšĀ£ī³’Ø2ĀxaåœÉöõŪ³źģ©Ū\’IDü‚Ÿ E‰ų@…Õ­·¢Ī7¦ˆ+Ē2ś¹õę³ļõ£ĻænęN ¢Vʖ9ĪĒlĞ诫ĢKOTøģb¾c=ž)]ŪHX{7Jń3/u' mėŠŠĀ‘šX4T~ń'>łH.Wæ;}Ēņ+2‹–Ū÷ÅF޵;›\DŹæˆźėļ–§tERK0%!ėIÄcRŗ$G½5ßMEųīĢ]Pߦ COĘ{Z„ł!É" ᄦ­v;™Hy”=¦Ļžč’®żFĶ ą“kāSzy™†ŅĖė=±ČūeK@ŠŪqmͼ”'˜qCHųl%¼Ž)łF•.XƹsU×LL—żažū¤†„›C¾Ń?a½ģōy¦ÅF”Kī̘$Åń!ąÜxąå‹¢iw»¹Ō–UF„š_Ł”,Ę9żöū!2œųę— DVŌ¤$5ŃM̘oś:Ó āƒhG­ēēśüqš½/ū‹ņc’D¤ćGor¢Ļ½BŒ÷Ś(įd,œ®d’+B€°ī“÷…ĘŅ÷?=ėU1‘aõŸŪø$+"“ޟ²æŽ•øNTŹÕĻ% ķG~_żŁÕꞧ&ŗ_³įŪG’ī †LuH“D“ś/žÖ£¼CNŗĖ•³iė.7Nź·…–Ö}ī~Ģ[²Ž<ųÜ7I?ūe2ž×&,rłē7v•灒‰TeKŖÜ1“¶ķ3×ÜõZ—s‡żÜyD$fõŁ/™„_T¢W“ Ci~=šśź7°)ü4óRž ";÷øY.a)} Łę·L2ž4Ēż«Ļ$NżŪ™NxzƒcÉEDhŠ­¾=ó÷21ĆŃ?~7ėłøėa£ÕŽ¢ĮŸŚČįõS¦C.ē;Ļ8Ź^Ćæė½{ūkåöėÆūg|öw?›ÜcŹHųŃuœé;Ūb"ŸĀJEӗĢ¢ń›œ?~S••˜Ä®Gŗ‰ÆńŖ™1mļå}÷|sęUĻø1Rę²eZĀ«īmŽ>ū÷”ŸśĮEnŅŸ€4½l›Ÿ )ų4*ü;­¾<üfŚż"¼tķsöƒ)>a?Ÿ€äŽ/"Į§GāSæ‰Oż|ĀPŅ/ēħ\ĖxB“f^¢DÉ·°F&ŁČ‹īOŗĪ|E0¤Ä§¾śłÄøż2'* Ą/2hØżrLhŹĮO3/ Q¢ä[X=TF'\ōØK,bžŁx†ŹDü¢Yœ_2(wæĢ‰O'öÕoe–D›\ż\āĪP%*oB“>·¢Dɇ°ę6óR”'4Åļē"¹ˆ„ür™É©ß~DTõiżŗ†bJTŠŁĻĶ€äü²'õÅ/—D„(? «%J>„5ŪĢKˆ ­ü§^Ķ’ąÓW?crHR"U’üÜLS+6~‹æ7²śuĶH•£óńŲÄ"üīÉĮ/™€”ź—9QÉū WšyIˆ’&Āźg^:(S¢MZĀPÜ~9% ŗßäü¾[Ų~$*į—mFŖō„¦>łåØ”«__©$¬B”(łÖ®™—^Ÿć>az7ŗĪ|EäEξöYWłf÷ Oš Ÿ²ų½Ö?— •‹ß“Åė—L܉ĖĻ'åĆ/H|źŻÆ;A*?ŗ·‡ČļņšyIˆ’$ĀŹĢK%g^r‰JĆzK %4õźJhŹāו€”ĶÄ\•Rü¢YR†ĪeńėJhr~Łw¬ßŹÜüčjŒ„”|śł•rõ§™—„(Mņ!¬µ]3/½ęcÖŗ"ƞ $ʤś Ō/HČŁ_üŗ¤"hŅżzKhŹÕÆ;”)?—øcżˆäbö‹Jr~#Ć Hšrõė‘ų4Š©n?ͼ$D‰’aķžyéVW™/^¹ŃĶōsHĘʰßĢAōę*sOrIŹÉĻVŖĪ„—ü\bLśłD„øżHŹę×#Q)ŹĻ'*嚊·3/m×ĢKB”$łV*~=å·ē>äʞˆ‚:>:ńÄ%ä$żHšÉŁ/C"KŸüĪK&ŚÄ€4T~½$ųzB“÷Ė%”)7æ 欉OšūV“ߣ/ię%!J’| «Oģ8+-Q‰Źˆ®3_…ż¦Ģ‰Ļ/=AŖ7æÜŹ Trö{Ä”ņ{²šü’ >Łü|"ŠPśŃ ž“ßeŃ~ēŻš¼f^¢É·°z>h+£¾&*åā—s¢’÷s‰@JhbYj¢R~9%•f¢R”Ÿ>·¢Dɇ°ö:óŅ]ɤŖm.ā˘øņĖ)ńÉł=™Żoż`ū‰@yóːą“橁_Ö©¾śŁˆ/›_ք¦>ų Hł/OĀ*D‰’a„2¹ü¶č™—~t4‰Eƹ—ŠtŅ]¹łE$ØĄ’8æ į%ædāSą—=A*>æa) R±ų%H¤ŹÅ„œ\ż3”)6æOöĶ/k"U—_t"•„Uˆ%Āźf^Z²Žż\Ł?G$€ōLhŗ#2Q$Տ„¦h?—ø“āxŅ?†rõĖ”š²ßų qBS\~ƒ•ų$a¢Dɇ°ś™—ž÷ >¶’yß§{&€œu C«Rüčb뷟K@ŹŻÆ+iü‚©8żžėņc¦©¬~.q'næ'Ł/”€”ÉļŗĖĖяD„œż¬X{?~GW3/ Q‚äCXżĢK$ ńcŚ—fH,śą—I“y4š[ƒŸ­Ür÷ mrJ|Jń‹Ndɟ‰1¹ū±l0üś—ų”ĶĻ'õāWD MšyIˆ%Āźf^ŗō s­K@Z’5Q)š[Ś'?’céQ~żK|Š1A*6æ×æõyņː“Oæ¬ MŽļ²,~S»ż2%Åķēšrń#”iWC‹f^¢ɇ°śĻm\’9;ś”ØT~A"Ko~=¤rņė-a(~æ>'H½ķו0”«_((næ8•ņįW½½^3/ QŠäSX©hH@āÓĘØˆFzKh üŗš¢üH“鋉,Łü|āŽOŠ×ļöœż»ėĶÄ¢¢M¤"ahØż²%>åąēŸrōÓĢKB”(łV;ӌJ@JOhŹ‹_2Ø7?ĘĘ¢rõ£ °æ~yKhz-~æ¢N|‚„¦s5ó’„I¾…ÕCŅń&‹rMhŹÅÆ:Ēħœü‚D›\żH@ üz&²¤'Håź{ā“õcŁĄżv~YŸ²ūłD„\šrńėN,źÅ/%)n?ͼ$„H’aŻŁ=óŅGæīzOhśč7rKhźö‹§<Ość×kāSŠß“™żrNh*ædb‘÷ė-(~$ eóó‰E}š‹#ń‰D„(? «%J>„5ŪĢKˆ Oæ:ĖŚKĀPŲÆ×Ä¢¤ßą'4Åķ$ĘÄļ7³~=r —© ±({‚Tüį÷Jæ‘Yü\bQ®~A~©Ā~Ė{śIX…(Qņ!¬mķ¦lÉz'šŸüļ ͟}īä>żƒ‹]7Śō²5.*ĄļńūaŖ"›Ÿ–ö?[é÷ę7£lm,~Ÿjæł}ń[’ŁļG—¤ų‘Ü?Ęk%¬B” łV>1himsÓ¾üf™öą[)Üöšxsß3“MŁŅ*SWß4¤~/Åą7_~ƒė·xż–e÷»’Ł4æqefŒ®‘Y°ĀŗzU…¹ś¼·Ķł'½%„ˆ‘KĻoęĶY«°z:Į–Ū„å—ėu‘_4ÅēĒæ!.‹UX[[[ĶīŻ»…y ¹¹9ł¦Éd²B¶X…U&“Éd²R7 «L&“Éd1š„U&“Éd²MĀ*“Éd2YŒ&a•Éd2™,F“°Źd2™L£IXe2™L&‹Ń$¬2™L&“ÅhV™L&“Éb4 «L&“Éd1š„U&“Éd²MĀ*“Éd2YŒ&a•Éd2™,F“°Źd2™L£IXe2™L&‹Ń$¬2™L&“ÅfĘü’€ŅJŁõŽéIEND®B`‚qatengine-1.9.0/kpt/lib/README.md000066400000000000000000000021771500416242000163200ustar00rootroot00000000000000# Key Protection Technology Library The KPT2.0 capability is delivered through the KPT Library which is placed in the QAT_Engine repository. It can provide KPT2.0 functionalities, like special key file parse, KPT init/finish, asymmetric crypto offload etc. And the library will leverage other Intel security technologies, e.g. Software Guard Extensions(SGX) to provide more security services in the future.

drawing

## **Division of the work** * QAT_ENGINE: Control Path * Async job control * QAT resource management * KPT Layer between QAT_Engine and KPT Library: qat_hw_kpt.c * KPT_LIB: Data Path * WPK load and parse * KPT initialization/finish * Crypto offload ## **Environment Setup** ### Requirements * QuickAssist Technology Driver for IntelĀ® XeonĀ® Scalable Processor family with IntelĀ® QAT Gen4/Gen4m Platform * OpenSSL 1.1.1x & 3.0.x ### Build This Library is built along with qatengine build when KPT is enabled using the configure flag `--enable-qat_hw_kpt`. KPT debugs can be enabled by passing "KPT_DEBUG" or "KPT_WARN" in the CFLAGS. qatengine-1.9.0/kpt/lib/kpt.c000066400000000000000000001401251500416242000157770ustar00rootroot00000000000000#ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU /* Standard Includes */ #include #include #include #include /* Local Includes */ #include "kpt.h" #include "kpt_utils.h" /* Total number of loaded device credentials */ static int wpk_num = 0; static int wpk_loading_idx = 0; /** ****************************************************************** * KPT Device Credentials in multiple WPK files, each WPK file * contains multiple credentials for different devices. * WPK 0: (e.g. RSA2k) * ESWK0 DEV_ID0 PARAM0 (e.g. for cpu_socket0->dev0) * ESWK1 DEV_ID1 PARAM1 (e.g. for cpu_socket1->dev1) * ... * WPK 1: (e.g. ECC-P256) * ESWKm DEV_IDm PARAMm * ... * WPK n: ESWKn DEV_IDn PARAMn *****************************************************************/ static kpt_dev_credential_st kpt_dev_crdt[MAX_WPK_NUM] = {{0}}; /** ****************************************************************** * Each instance will do KPT provision for each loaded WPK files * depends on the corresponding ESWK which matches the dev_id. * * Instance 0: (e.g. located on cpu_socket0->dev0) * WPK 0: KPT_unwrap_ctx(0) ESWK(cpu_socket0->dev0) * WPK 1: KPT_unwrap_ctx(1) ESWK(cpu_socket0->dev0) * ... * WPK k: KPT_unwrap_ctx(k) ESWK(cpu_socket0->dev0) * ... * Instance n: (e.g. located on cpu_socket(i)->dev(j)) * WPK 0: KPT_unwrap_ctx(0) ESWK(cpu_socket(i)->dev(j)) * ... * WPK k: KPT_unwrap_ctx(k) ESWK(cpu_socket(i)->dev(j)) *****************************************************************/ kpt_inst_provision_context_st kpt_inst_prvs_ctx[MAX_CRYPTO_INSTANCES] = {{0}}; /* To specify the RSA op sizes supported by QAT engine */ #define RSA_KPT_RANGE_MIN 512 #define RSA_KPT_RANGE_MAX 8192 #define NO_PADDING 0 #define PADDING 1 /* For SWK */ ASN1_SEQUENCE(ESWK) = { ASN1_SIMPLE(ESWK, devSig, ASN1_OCTET_STRING), ASN1_SIMPLE(ESWK, secSWK, ASN1_OCTET_STRING) } ASN1_SEQUENCE_END(ESWK) IMPLEMENT_ASN1_FUNCTIONS(ESWK) ASN1_SEQUENCE(WRAPPINGMETADATA) = { ASN1_SIMPLE(WRAPPINGMETADATA, aesNonce, ASN1_OCTET_STRING), ASN1_SIMPLE(WRAPPINGMETADATA, wrappingAlg, ASN1_OBJECT), ASN1_SEQUENCE_OF(WRAPPINGMETADATA, eSWKs, ESWK) }ASN1_SEQUENCE_END(WRAPPINGMETADATA) IMPLEMENT_ASN1_FUNCTIONS(WRAPPINGMETADATA) /* For RSA */ ASN1_SEQUENCE(RSAPUBLICKEY) = { ASN1_SIMPLE(RSAPUBLICKEY, n, ASN1_INTEGER), ASN1_SIMPLE(RSAPUBLICKEY, e, ASN1_INTEGER), }ASN1_SEQUENCE_END(RSAPUBLICKEY) IMPLEMENT_ASN1_FUNCTIONS(RSAPUBLICKEY) ASN1_SEQUENCE(KPTRSAKEY) = { ASN1_SIMPLE(KPTRSAKEY, version, LONG), ASN1_SIMPLE(KPTRSAKEY, privateKeyType1, ASN1_OCTET_STRING), ASN1_SIMPLE(KPTRSAKEY, privateKeyType2, ASN1_OCTET_STRING), ASN1_SIMPLE(KPTRSAKEY, size, LONG), ASN1_SIMPLE(KPTRSAKEY, kptRSADsi, ASN1_OBJECT), ASN1_SIMPLE(KPTRSAKEY, publicKey, RSAPUBLICKEY), ASN1_SIMPLE(KPTRSAKEY, wrappingMetadata, WRAPPINGMETADATA), }ASN1_SEQUENCE_END(KPTRSAKEY) IMPLEMENT_ASN1_FUNCTIONS(KPTRSAKEY) /* For ECC */ ASN1_SEQUENCE(KPTECCKEY) = { ASN1_SIMPLE(KPTECCKEY, version, LONG), ASN1_SIMPLE(KPTECCKEY, privateKey, ASN1_OCTET_STRING), ASN1_EXP_OPT(KPTECCKEY, curveName, ASN1_OBJECT, 0), ASN1_EXP_OPT(KPTECCKEY, publicKey, ASN1_BIT_STRING, 1), ASN1_SIMPLE(KPTECCKEY, wrappingMetadata, WRAPPINGMETADATA) }ASN1_SEQUENCE_END(KPTECCKEY) IMPLEMENT_ASN1_FUNCTIONS(KPTECCKEY) /** ****************************************************************** * Curve OID DER(OID) * secp256r1 1.2.840.10045.3.1.7 06 08 2A 86 48 CE 3D 03 01 07 * secp384r1 1.3.132.0.34 06 05 2B 81 04 00 22 * secp521r1 1.3.132.0.35 06 05 2B 81 04 00 23 *****************************************************************/ #define NID_SECP256R1 415 #define NID_SECP384R1 715 #define NID_SECP521R1 716 static unsigned char secp256_oid[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }; static unsigned char secp384_oid[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22 }; static unsigned char secp521_oid[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23 }; static unsigned char rsa_oid[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01 }; #ifdef QAT_OPENSSL_3 static int (*default_rsa_init)(RSA *rsa) = NULL; static __thread RSA *kpt_keymgmt_rsa = NULL; static int (*default_ec_key_init)(EC_KEY *key) = NULL; static void (*default_ec_key_finish)(EC_KEY *key) = NULL; static int (*default_ec_key_copy)(EC_KEY *dest, const EC_KEY *src) = NULL; static int (*default_ec_key_set_group)(EC_KEY *key, const EC_GROUP *grp) = NULL; static int (*default_ec_key_set_private)(EC_KEY *key, const BIGNUM *priv_key) = NULL; static int (*default_ec_key_set_public)(EC_KEY *key, const EC_POINT *pub_key) = NULL; static __thread EC_KEY *kpt_keymgmt_ec_key = NULL; #endif /** ***************************************************************************** * * WPK files load and parse implementation. * *****************************************************************************/ int kpt_reset_wpk_num() { wpk_loading_idx = 0; return wpk_loading_idx; } /* Valid WPK index returns 1, invalid index returns 0. */ static int kpt_wpk_idx_check(int wpk_index) { return !(wpk_index < 0 || wpk_index > (wpk_num - 1)); } static int parse_wrapping_metadata(WRAPPINGMETADATA *wrapping_metadata, kpt_wpk_type wpktype, int nid) { ESWK *eSWK = NULL; ASN1_OCTET_STRING *iv = NULL; ASN1_OCTET_STRING *swk_sec = NULL; ASN1_OCTET_STRING *swk_pub = NULL; int enc_algo_nid = 0; unsigned char *aad = NULL; int aad_len = 0; kpt_eswk_meta_data_st *eswk = NULL; kpt_dev_identity_st *dev_id = NULL; int socket_num = 0; int i = 0; socket_num = sk_ESWK_num(wrapping_metadata->eSWKs); if (socket_num <= 0) { WARN("Not found ESWK in current WPK file.\n"); return 0; } enc_algo_nid = OBJ_obj2nid(wrapping_metadata->wrappingAlg); iv = wrapping_metadata->aesNonce; if (PEM_TYPE_ECC_WPK == wpktype) { switch(nid) { case NID_SECP256R1: { aad = secp256_oid; aad_len = sizeof(secp256_oid); break; } case NID_SECP384R1: { aad = secp384_oid; aad_len = sizeof(secp384_oid); break; } case NID_SECP521R1: { aad = secp521_oid; aad_len = sizeof(secp521_oid); break; } default: { WARN("Unknown ECC curve\n"); return 0; } break; } } else if (PEM_TYPE_RSA_WPK == wpktype) { aad = rsa_oid; aad_len = sizeof(rsa_oid); } else { WARN("Unknown WPK type\n"); return 0; } if (wpk_loading_idx < 0 || wpk_loading_idx > (MAX_WPK_NUM - 1)) { WARN("Invalid WPK index whiling loading.\n"); return 0; } eswk = kpt_dev_crdt[wpk_loading_idx].eswk_data; dev_id = kpt_dev_crdt[wpk_loading_idx].dev_id; kpt_dev_crdt[wpk_loading_idx].total = socket_num; for (i = 0; i < socket_num; i++ ) { if (enc_algo_nid != NID_aes_256_gcm) { WARN("Invalid wrapping algorithm for KPT\n"); return 0; } eSWK = sk_ESWK_value(wrapping_metadata->eSWKs, i); if ((swk_sec = eSWK->secSWK) == NULL) return 0; if ((swk_pub = eSWK->devSig) == NULL) return 0; /* Encrypted SWK */ if ((eswk[i].len_eswk = ASN1_STRING_length(swk_sec)) < 0) return 0; memcpy(eswk[i].eswk, ASN1_STRING_get0_data(swk_sec), ASN1_STRING_length(swk_sec)); /* IV */ if ((eswk[i].len_iv = ASN1_STRING_length(iv)) < 0) return 0; memcpy(eswk[i].iv, ASN1_STRING_get0_data(iv), ASN1_STRING_length(iv)); /* AAD data */ if ((eswk[i].len_aad = aad_len) < 0) return 0; memcpy(eswk[i].aad, aad, aad_len); /* Signature */ if ((dev_id[i].len_sig = ASN1_STRING_length(swk_pub)) < 0) return 0; memcpy(dev_id[i].signature, ASN1_STRING_get0_data(swk_pub), ASN1_STRING_length(swk_pub)); DUMP_KPT_WRAPPING_DATA( eswk[i].eswk, eswk[i].len_eswk, dev_id[i].signature, dev_id[i].len_sig, eswk[i].iv, eswk[i].len_iv, eswk[i].aad, eswk[i].len_aad); } DEBUG("Current WPK file has %d eSWK\n", socket_num); return 1; } #ifdef QAT_OPENSSL_3 int kpt_keymgmt_rsa_init(RSA *rsa) { kpt_keymgmt_rsa = rsa; if (default_rsa_init && default_rsa_init != kpt_keymgmt_rsa_init) return default_rsa_init(rsa); return 1; } int kpt_keymgmt_ec_key_init(EC_KEY *key) { kpt_keymgmt_ec_key = key; if (default_ec_key_init && default_ec_key_init != kpt_keymgmt_ec_key_init) return default_ec_key_init(key); return 1; } #endif static EVP_PKEY *EVP_RSAWPK2PKEY(ENGINE *engine, const KPTRSAKEY *wpkinfo, kpt_wpk_type wpktype) { EVP_PKEY *pkey = NULL; RSA *rsa = NULL; kpt_rsa_wpk *rsa_wpk = NULL; RSAPUBLICKEY *pub_key = NULL; WRAPPINGMETADATA *wrapping_metadata = NULL; long version = 0, size = 0; ASN1_OCTET_STRING *wrapped_key_type1 = NULL; ASN1_OCTET_STRING *wrapped_key_type2 = NULL; ASN1_OBJECT *wrapping_algo = NULL; ASN1_OCTET_STRING *iv = NULL; int enc_algo_nid = 0; ASN1_INTEGER *n = NULL; ASN1_INTEGER *e = NULL; BIGNUM *n_bn = NULL; BIGNUM *e_bn = NULL; #ifdef QAT_OPENSSL_3 EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; RSA_METHOD *rsa_method = NULL; ENGINE * rsa_engine = NULL; #endif /* struct kpt_rsa_key */ if ((version = wpkinfo->version) < 0) goto error; if ((size = wpkinfo->size) < 0) goto error; if ((wrapping_metadata = wpkinfo->wrappingMetadata) == NULL) goto error; if ((wrapped_key_type1 = wpkinfo->privateKeyType1) == NULL) goto error; if ((wrapped_key_type2 = wpkinfo->privateKeyType2) == NULL) goto error; if ((pub_key = wpkinfo->publicKey) == NULL) goto error; /* struct wrapping_metadata */ if ((wrapping_algo = wrapping_metadata->wrappingAlg) == NULL) goto error; if ((iv = wrapping_metadata->aesNonce) == NULL) goto error; /* struct rsa_public_key */ if ((n = pub_key->n) == NULL) goto error; if ((e = pub_key->e) == NULL) goto error; /* Populate kpt_dev_crdt array */ enc_algo_nid = OBJ_obj2nid(wrapping_algo); if (!parse_wrapping_metadata(wrapping_metadata, wpktype, 0)) { WARN("Error in parse_wrapping_metadata\n"); goto error; } #ifndef QAT_OPENSSL_3 pkey = EVP_PKEY_new(); if (!pkey) { WARN("Error in EVP_PKEY_new\n"); goto error; } rsa = RSA_new(); if (!rsa) { WARN("Error in RSA_new\n"); goto error; } #endif n_bn = ASN1_INTEGER_to_BN(n, NULL); e_bn = ASN1_INTEGER_to_BN(e, NULL); #ifndef QAT_OPENSSL_3 RSA_set0_key(rsa, n_bn, e_bn, NULL); #endif /* Populate struct kpt_rsa_wpk_st */ rsa_wpk = (kpt_rsa_wpk *)malloc(sizeof(kpt_rsa_wpk)); if (!rsa_wpk) goto error; memset(rsa_wpk, 0, sizeof(kpt_rsa_wpk)); rsa_wpk->version = version; rsa_wpk->size = size; rsa_wpk->wrapping_alg_nid = enc_algo_nid; BN_bn2bin(n_bn, rsa_wpk->n); BN_bn2bin(e_bn, rsa_wpk->e); rsa_wpk->n_size = BN_num_bytes(n_bn); rsa_wpk->e_size = BN_num_bytes(e_bn); if (wrapped_key_type1) { if ((rsa_wpk->wpk_type1_size = ASN1_STRING_length(wrapped_key_type1)) > 0) { memcpy(rsa_wpk->wpk_type1, ASN1_STRING_get0_data(wrapped_key_type1), rsa_wpk->wpk_type1_size); } } if (wrapped_key_type2) { if ((rsa_wpk->wpk_type2_size = ASN1_STRING_length(wrapped_key_type2)) > 0) { memcpy(rsa_wpk->wpk_type2, ASN1_STRING_get0_data(wrapped_key_type2), rsa_wpk->wpk_type2_size); } } /* Save for kpt handle look up */ rsa_wpk->wpk_index = wpk_loading_idx; wpk_loading_idx++; wpk_num = wpk_loading_idx; DEBUG("Total WPK number: %d\n", wpk_loading_idx); #ifdef QAT_OPENSSL_3 rsa_engine = ENGINE_get_default_RSA(); if (rsa_engine == NULL) { ENGINE_set_default_RSA(engine); rsa_engine = engine; } if (rsa_engine == NULL) { WARN("default rsa engine is null\n"); goto error; } rsa_method = (RSA_METHOD *)ENGINE_get_RSA(rsa_engine); if (rsa_method == NULL) { WARN("rsa_method is null\n"); goto error; } default_rsa_init = RSA_meth_get_init(rsa_method); bld = OSSL_PARAM_BLD_new(); OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n_bn); OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e_bn); params = OSSL_PARAM_BLD_to_param(bld); ctx = EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX_get0_global_default(), "RSA", NULL); EVP_PKEY_fromdata_init(ctx); RSA_meth_set_init(rsa_method, kpt_keymgmt_rsa_init); kpt_keymgmt_rsa = NULL; EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params); RSA_meth_set_init(rsa_method, default_rsa_init); rsa = kpt_keymgmt_rsa; /* Save rsa_wpk into EVP_PKEY */ if (RSA_set_ex_data(rsa, KEY_WRAP_STORAGE_INDEX, rsa_wpk) != 1) { WARN("Failed in RSA_set_ex_data\n"); goto error; } OSSL_PARAM_free(params); OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); #else /* Save rsa_wpk into EVP_PKEY */ if (RSA_set_ex_data(rsa, KEY_WRAP_STORAGE_INDEX, rsa_wpk) != 1) { WARN("Failed in RSA_set_ex_data\n"); goto error; } EVP_PKEY_assign_RSA(pkey, rsa); #endif return pkey; error: free(rsa_wpk); #ifdef QAT_OPENSSL_3 if (params) OSSL_PARAM_free(params); if (bld) OSSL_PARAM_BLD_free(bld); if (ctx) EVP_PKEY_CTX_free(ctx); #endif return NULL; } static EVP_PKEY *EVP_ECCWPK2PKEY(ENGINE *engine, const KPTECCKEY *wpkinfo, kpt_wpk_type wpktype) { EVP_PKEY *pkey = NULL; EC_KEY *ec = NULL; kpt_ecc_wpk *ecc_wpk = NULL; long version = 0; WRAPPINGMETADATA *wrapping_metadata = NULL; ASN1_OCTET_STRING *wrapped_key = NULL; unsigned char *priv_key_buf = NULL; int priv_key_buf_len; ASN1_OBJECT *curve_name = NULL; ASN1_BIT_STRING *pub_key = NULL; unsigned char *pub_key_buf = NULL; int pub_key_buf_len; EC_GROUP *group = NULL; ASN1_OBJECT *wrapping_algo = NULL; ASN1_OCTET_STRING *iv = NULL; size_t sz; int enc_algo_nid = 0; int curve_nid = 0; int ecbits; int i = 0; #ifdef QAT_OPENSSL_3 EVP_PKEY_CTX *ctx = NULL; OSSL_PARAM_BLD *bld = NULL; OSSL_PARAM *params = NULL; EC_KEY_METHOD *ec_key_method = NULL; const char *ec_group_name = NULL; BIGNUM *ec_priv_bn = NULL; ENGINE *ec_engine = NULL; #endif /* struct kpt_ecc_key */ if ((version = wpkinfo->version) < 0) goto error; if ((wrapping_metadata = wpkinfo->wrappingMetadata) == NULL) goto error; if ((wrapped_key = wpkinfo->privateKey) == NULL) goto error; if ((curve_name = wpkinfo->curveName) == NULL) goto error; if ((pub_key = wpkinfo->publicKey) == NULL) goto error; /* struct wrapping_metadata */ if ((wrapping_algo = wrapping_metadata->wrappingAlg) == NULL) goto error; if ((iv = wrapping_metadata->aesNonce) == NULL) goto error; /* Populate kpt_dev_crdt array */ enc_algo_nid = OBJ_obj2nid(wrapping_algo); curve_nid = OBJ_obj2nid(curve_name); if (!parse_wrapping_metadata(wrapping_metadata, wpktype, curve_nid)) { WARN("Error in parse_wrapping_metadata\n"); goto error; } #ifdef QAT_OPENSSL_3 bld = OSSL_PARAM_BLD_new(); if (!bld) { WARN("Error in OSSL_PARAM_BLD_new\n"); goto error; } #else pkey = EVP_PKEY_new(); if (!pkey) { WARN("Error in EVP_PKEY_new\n"); goto error; } ec = EC_KEY_new(); if (!ec) { WARN("Error in EC_KEY_new\n"); goto error; } #endif /* Create Group */ group = EC_GROUP_new_by_curve_name(curve_nid); #ifdef QAT_OPENSSL_3 ec_group_name = OBJ_nid2sn(curve_nid); OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, ec_group_name, strlen(ec_group_name)); #else EC_KEY_set_group(ec, group); #endif /* Copy Public Key */ if ((pub_key_buf_len = ASN1_STRING_length(pub_key)) < 0) goto error; pub_key_buf = malloc(pub_key_buf_len); memset(pub_key_buf, 0, pub_key_buf_len); memcpy(pub_key_buf, ASN1_STRING_get0_data(pub_key), pub_key_buf_len); #ifdef QAT_OPENSSL_3 if (!(i = OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key_buf, pub_key_buf_len))) { WARN("Error in OSSL_PARAM_BLD_push_octet_string, return %d\n", i); goto error; } #else if (!(i = EC_KEY_oct2key(ec, (const unsigned char *)pub_key_buf, pub_key_buf_len, NULL))) { WARN("Error in EC_KEY_oct2key, return %d\n", i); goto error; } #endif /* Copy Private Key */ if ((priv_key_buf_len = ASN1_STRING_length(wrapped_key)) < 0) goto error; priv_key_buf = malloc(priv_key_buf_len); memset(priv_key_buf, 0, priv_key_buf_len); memcpy(priv_key_buf, ASN1_STRING_get0_data(wrapped_key), priv_key_buf_len); ecbits = EC_GROUP_order_bits(group); sz = (ecbits + 7 ) / 8; /* Set a dummy private key to align with OpenSSL routine, the private key is not really used. */ #ifdef QAT_OPENSSL_3 ec_priv_bn = BN_bin2bn(priv_key_buf, sz, NULL); OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, ec_priv_bn); #else if (!(i = EC_KEY_oct2priv(ec, (const unsigned char *)priv_key_buf, sz))) { WARN("Error in EC_KEY_oct2priv, return %d\n", i); goto error; } #endif /* Populate struct kpt_ecc_wpk_st */ ecc_wpk = (kpt_ecc_wpk *)malloc(sizeof(kpt_ecc_wpk)); if (!ecc_wpk) goto error; memset(ecc_wpk, 0, sizeof(kpt_ecc_wpk)); ecc_wpk->version = version; ecc_wpk->wrapping_alg_nid = enc_algo_nid; ecc_wpk->curve_nid = curve_nid; /* Copy private key */ memcpy(ecc_wpk->wpk, priv_key_buf, priv_key_buf_len); ecc_wpk->wpk_size = priv_key_buf_len; /* Copy Public Key */ memcpy(ecc_wpk->pub_key, pub_key_buf, pub_key_buf_len); ecc_wpk->pub_key_size = pub_key_buf_len; #ifdef QAT_OPENSSL_3 ec_engine = ENGINE_get_default_EC(); if (ec_engine == NULL) { ENGINE_set_default_EC(engine); ec_engine = engine; } if (ec_engine == NULL) { WARN("default ec engine is null\n"); goto error; } ec_key_method = (EC_KEY_METHOD *)ENGINE_get_EC(ec_engine); EC_KEY_METHOD_get_init(ec_key_method, &default_ec_key_init, &default_ec_key_finish, &default_ec_key_copy, &default_ec_key_set_group, &default_ec_key_set_private, &default_ec_key_set_public); params = OSSL_PARAM_BLD_to_param(bld); ctx = EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX_get0_global_default(), "EC", NULL); EVP_PKEY_fromdata_init(ctx); EC_KEY_METHOD_set_init(ec_key_method, kpt_keymgmt_ec_key_init, default_ec_key_finish, default_ec_key_copy, default_ec_key_set_group, default_ec_key_set_private, default_ec_key_set_public); kpt_keymgmt_ec_key = NULL; EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params); EC_KEY_METHOD_set_init(ec_key_method, default_ec_key_init, default_ec_key_finish, default_ec_key_copy, default_ec_key_set_group, default_ec_key_set_private, default_ec_key_set_public); ec = kpt_keymgmt_ec_key; kpt_keymgmt_ec_key = NULL; OSSL_PARAM_free(params); OSSL_PARAM_BLD_free(bld); EVP_PKEY_CTX_free(ctx); #endif /* Save rsa_wpk into EVP_PKEY */ if (EC_KEY_set_ex_data(ec, KEY_WRAP_STORAGE_INDEX, ecc_wpk) != 1) { WARN("Failed in EC_KEY_set_ex_data\n"); goto error; } /* Save for kpt handle look up */ ecc_wpk->wpk_index = wpk_loading_idx; wpk_loading_idx++; wpk_num = wpk_loading_idx; DEBUG("Total WPK number: %d\n", wpk_loading_idx); #ifndef QAT_OPENSSL_3 EVP_PKEY_assign_EC_KEY(pkey, ec); #endif return pkey; error: if (ecc_wpk) free(ecc_wpk); if (pub_key_buf) free(pub_key_buf); if (priv_key_buf) free(priv_key_buf); #ifdef QAT_OPENSSL_3 if (params) OSSL_PARAM_free(params); if (bld) OSSL_PARAM_BLD_free(bld); if (ctx) EVP_PKEY_CTX_free(ctx); #endif return NULL; } static EVP_PKEY *PEM_read_bio_WPK(ENGINE *e, BIO *bp) { char *nm = NULL; char *header = NULL; const unsigned char *p = NULL; unsigned char *data = NULL; long len; EVP_PKEY *pkey = NULL; if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { WARN("Error in PEM_read_bio\n"); return NULL; } p = data; if (strcmp(nm, PEM_STRING_WRAPPED_RSA_KEY) == 0) { DEBUG("Parse RSA WPK file\n"); KPTRSAKEY *wpkinfo; wpkinfo = d2i_KPTRSAKEY(NULL, &p, len); if (wpkinfo == NULL) { goto error; } if (!(pkey = EVP_RSAWPK2PKEY(e, wpkinfo, PEM_TYPE_RSA_WPK))) { WARN("Error in EVP_RSAWPK2PKEY\n"); } } else if (strcmp(nm, PEM_STRING_WRAPPED_ECC_KEY) == 0) { DEBUG("Parse ECC WPK file\n"); KPTECCKEY *wpkinfo; wpkinfo = d2i_KPTECCKEY(NULL, &p, len); if (wpkinfo == NULL) { goto error; } if (!(pkey = EVP_ECCWPK2PKEY(e, wpkinfo, PEM_TYPE_ECC_WPK))) { WARN("Error in EVP_ECCWPK2PKEY\n"); } } else { WARN("Invalid PEM_STRING for KPT\n"); } error: OPENSSL_free(nm); OPENSSL_clear_free(data, len); return pkey; } EVP_PKEY *kpt_load_priv_key(ENGINE *e, const char *wpk) { EVP_PKEY *pkey = NULL; BIO *in; if (access(wpk, F_OK)) { WARN("File %s does not exist\n", wpk); goto error; } in = BIO_new(BIO_s_file()); if (!in) { WARN("BIO new failed\n"); goto error; } if (!BIO_read_filename(in, wpk)) { WARN("Read wrapped private key file %s failed\n", wpk); BIO_free(in); goto error; } DEBUG("Parse Wrapped Private Key(WPK): \n"); if (!(pkey = PEM_read_bio_WPK(e, in))) { WARN("Error in PEM_read_bio_WPK\n"); goto error; } return pkey; error: WARN("Error in kpt_load_priv_key\n"); return NULL; } /** ****************************************************************************** * * KPT init and finish implementation. * *****************************************************************************/ /* Valid instance index returns 1, invalid index returns 0. */ static int kpt_inst_idx_check(int qat_inst_index) { return !(qat_inst_index < 0 || qat_inst_index > (MAX_CRYPTO_INSTANCES - 1)); } int kpt_instance_available(int qat_inst_index, int wpk_index) { if (!kpt_inst_idx_check(qat_inst_index)) { WARN("Invalid QAT instance index.\n"); return 0; } if (!kpt_wpk_idx_check(wpk_index)) { WARN("Invalid WPK index.\n"); return 0; } return (kpt_inst_prvs_ctx[qat_inst_index].kpt_enabled && kpt_inst_prvs_ctx[qat_inst_index].meta_ctx[wpk_index].swk_provisioned); } static int get_encrypted_swk(CpaInstanceHandle qat_inst_handle, int wpk_idx) { CpaStatus status = CPA_STATUS_SUCCESS; CpaCyKptKeyManagementStatus kptStatus = CPA_CY_KPT_SUCCESS; CpaCyKptValidationKey DevCredential; kpt_dev_identity_st *dev_id = NULL; int num = 0; int i = 0; DevCredential.publicKey.modulusN.pData = (Cpa8U *) qaeMemAllocNUMA(KPT_PER_PART_PUBKEY_N_SIZE_IN_BYTE, 0, 64); if (NULL == DevCredential.publicKey.modulusN.pData) { return -1; } DevCredential.publicKey.modulusN.dataLenInBytes = KPT_PER_PART_PUBKEY_N_SIZE_IN_BYTE; DevCredential.publicKey.publicExponentE.pData = (Cpa8U *) qaeMemAllocNUMA(KPT_PER_PART_PUBKEY_E_SIZE_IN_BYTE, 0, 64); if (NULL == DevCredential.publicKey.publicExponentE.pData) { qaeMemFreeNUMA((void **)&DevCredential.publicKey.modulusN.pData); return -1; } DevCredential.publicKey.publicExponentE.dataLenInBytes = KPT_PER_PART_PUBKEY_E_SIZE_IN_BYTE; status = cpaCyKptQueryDeviceCredentials(qat_inst_handle, &DevCredential, &kptStatus); if (CPA_STATUS_SUCCESS != status || CPA_CY_KPT_SUCCESS != kptStatus) { WARN("Failed to query dev credentials, kptstatus = %d\n", kptStatus); goto not_found; } /* The wpk_idx is passed in within valid range. */ num = kpt_dev_crdt[wpk_idx].total; dev_id = kpt_dev_crdt[wpk_idx].dev_id; for(i = 0; i < num; i++) { if (!memcmp(dev_id[i].signature, DevCredential.signature, KPT_DEV_CREDENTIAL_SIZE_IN_BYTE)) { qaeMemFreeNUMA((void **)&DevCredential.publicKey.modulusN.pData); qaeMemFreeNUMA((void **)&DevCredential.publicKey.publicExponentE.pData); return i; } } not_found: qaeMemFreeNUMA((void **)&DevCredential.publicKey.modulusN.pData); qaeMemFreeNUMA((void **)&DevCredential.publicKey.publicExponentE.pData); return -1; } int kpt_init(int qat_inst_index, CpaInstanceHandle qat_inst_handle) { CpaStatus status = CPA_STATUS_SUCCESS; CpaCyKptKeyManagementStatus kptStatus = CPA_CY_KPT_SUCCESS; CpaCyCapabilitiesInfo CapInfo; kpt_inst_provision_context_st *ctx = NULL; kpt_provision_meta_cxt_st *meta_ctx = NULL; kpt_eswk_meta_data_st *eswk = NULL; CpaCyKptLoadKey *load_key = NULL; CpaCyKptUnwrapContext *unwrap_ctx = NULL; int wpk_idx = 0; int eswk_idx = 0; int pass = 0; if (!kpt_inst_idx_check(qat_inst_index)) { WARN("Invalid QAT instance index.\n"); return 0; } ctx = &kpt_inst_prvs_ctx[qat_inst_index]; ctx->instance_handle = qat_inst_handle; status = cpaCyQueryCapabilities(ctx->instance_handle, &CapInfo); if (CPA_STATUS_SUCCESS != status || CPA_FALSE == CapInfo.kptSupported || CPA_TRUE == CapInfo.symSupported) { ctx->kpt_enabled = 0; WARN("KPT is not supported on current instance\n"); return 0; } ctx->kpt_enabled = 1; /* Each instance needs to support different wpks */ for (wpk_idx = 0; wpk_idx < wpk_num; wpk_idx++) { meta_ctx = &(ctx->meta_ctx[wpk_idx]); /* Continue if no eswk is found */ eswk_idx = get_encrypted_swk(qat_inst_handle, wpk_idx); if (eswk_idx < 0) { WARN("Device credential is not found in WPK file\n"); continue; } eswk = &(kpt_dev_crdt[wpk_idx].eswk_data[eswk_idx]); load_key = &(meta_ctx->wrapping_key); load_key->wrappingAlgorithm = CPA_CY_KPT_WRAPPING_KEY_TYPE_AES256_GCM; load_key->eSWK.pData = (Cpa8U *)qaeMemAllocNUMA(eswk->len_eswk, 0, 64); if (NULL == load_key->eSWK.pData) return 0; if (eswk->len_eswk < 0) return 0; load_key->eSWK.dataLenInBytes = eswk->len_eswk; memcpy(load_key->eSWK.pData, eswk->eswk, eswk->len_eswk); unwrap_ctx = &(meta_ctx->unwrap_ctx); if (eswk->len_iv < 0) return 0; memcpy(unwrap_ctx->iv, eswk->iv, eswk->len_iv); if (eswk->len_aad < 0) return 0; memcpy(unwrap_ctx->additionalAuthData, eswk->aad, eswk->len_aad); unwrap_ctx->aadLenInBytes = eswk->len_aad; status = cpaCyKptLoadKey(ctx->instance_handle, load_key, &(unwrap_ctx->kptHandle), &kptStatus); if (CPA_STATUS_SUCCESS != status || kptStatus != CPA_CY_KPT_SUCCESS) { WARN("KPT Load Key Failed, kptStatus=%d\n", kptStatus); meta_ctx->swk_provisioned = 0; qaeMemFreeNUMA((void **)&load_key->eSWK.pData); continue; } meta_ctx->swk_provisioned = 1; DEBUG("Loads SWK for WPK%d: keyhandle 0x%lx\n", wpk_idx, unwrap_ctx->kptHandle); pass = 1; if (load_key->eSWK.pData) qaeMemFreeNUMA((void **)&load_key->eSWK.pData); } if (pass) return 1; else return 0; } void kpt_finish(int qat_inst_index, CpaInstanceHandle qat_inst_handles) { CpaStatus status = CPA_STATUS_SUCCESS; CpaCyKptKeyManagementStatus kptStatus = CPA_CY_KPT_SUCCESS; kpt_inst_provision_context_st *ctx = NULL; kpt_provision_meta_cxt_st *meta_ctx = NULL; int wpk_idx = 0; if (!kpt_inst_idx_check(qat_inst_index)) { WARN("Invalid QAT instance index.\n"); return; } ctx = &kpt_inst_prvs_ctx[qat_inst_index]; if (!ctx->kpt_enabled) { DEBUG("Instance %d is not provisioned\n", qat_inst_index); return; } for (wpk_idx = 0; wpk_idx < wpk_num; wpk_idx++) { meta_ctx = &(ctx->meta_ctx[wpk_idx]); if (!meta_ctx->swk_provisioned) { DEBUG("WPK %d is not provisioned\n", wpk_idx); continue; } meta_ctx->swk_provisioned = 0; status = cpaCyKptDeleteKey(qat_inst_handles, meta_ctx->unwrap_ctx.kptHandle, &kptStatus); if (CPA_STATUS_SUCCESS != status || kptStatus != CPA_CY_KPT_SUCCESS) { WARN("Instance %d Deletes SWK Failed\n", qat_inst_index); continue; } DEBUG("Instance %d Deletes SWK Successfully for WPK%d\n", qat_inst_index, wpk_idx); } } /** ***************************************************************************** * * KPT RSA Decryption and Sign implementation. * *****************************************************************************/ int kpt_check_rsa_wpk(RSA *rsa) { if (rsa) return RSA_get_ex_data(rsa, KEY_WRAP_STORAGE_INDEX) ? 1 : 0; return -1; } static int kpt_rsa_range_check(int plen) { return ((plen >= RSA_KPT_RANGE_MIN) && (plen <= RSA_KPT_RANGE_MAX)); } static int build_kpt_decrypt_op_buf(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaCyKptRsaDecryptOpData **dec_op_data, CpaFlatBuffer **output_buffer, int alloc_pad, int *wpk_index) { int rsa_len = 0; int padding_result = 0; CpaCyKptRsaPrivateKey *cpa_prv_key = NULL; CpaFlatBuffer *priv_key = NULL; kpt_rsa_wpk *rsa_wpk = NULL; DEBUG("- Started\n"); /* Retrieve data from ex_data field of rsa struct */ rsa_wpk = (kpt_rsa_wpk *)RSA_get_ex_data(rsa, KEY_WRAP_STORAGE_INDEX); if (rsa_wpk == NULL) { WARN("Get RSA WPK data failed\n"); return 0; } /* Using the PKEY matched WPK which is specified previously */ *wpk_index = rsa_wpk->wpk_index; if (!kpt_wpk_idx_check(*wpk_index)) { WARN("Invalid WPK index.\n"); return 0; } /* output signature should have same length as the RSA size */ rsa_len = RSA_size(rsa); if (rsa_len < 0) { WARN("Failed to get RSA length.\n"); return 0; } cpa_prv_key = (CpaCyKptRsaPrivateKey *) OPENSSL_zalloc(sizeof(CpaCyKptRsaPrivateKey)); if (NULL == cpa_prv_key) { WARN("Failed to allocate cpa_prv_key\n"); return 0; } /* output and input data MUST allocate memory for sign process */ /* memory allocation for DecOpdata[IN] */ *dec_op_data = OPENSSL_zalloc(sizeof(CpaCyKptRsaDecryptOpData)); if (NULL == *dec_op_data) { WARN("Failed to allocate dec_op_data\n"); OPENSSL_free(cpa_prv_key); return 0; } /* Setup the DecOpData structure */ (*dec_op_data)->pRecipientPrivateKey = cpa_prv_key; cpa_prv_key->version = CPA_CY_RSA_VERSION_TWO_PRIME; /* Setup the private key type structure, type2 is in priority */ if (rsa_wpk->wpk_type2_size > 0) { /* WPK Copy */ cpa_prv_key->privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2; /* Memory allocate for flat buffer */ priv_key = &(cpa_prv_key->privateKeyRep2.privateKey); priv_key->dataLenInBytes = (Cpa32U) rsa_wpk->wpk_type2_size; priv_key->pData = (Cpa8U *) qaeMemAllocNUMA(priv_key->dataLenInBytes, 0, 64); if (NULL == priv_key->pData) { priv_key->dataLenInBytes = 0; WARN("Failed to allocate priv_key->pData\n"); return 0; } memcpy(priv_key->pData, rsa_wpk->wpk_type2, priv_key->dataLenInBytes); } else if (rsa_wpk->wpk_type1_size > 0) { cpa_prv_key->privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_1; /* Memory allocate for flat buffer */ priv_key = &(cpa_prv_key->privateKeyRep1.privateKey); priv_key->dataLenInBytes = (Cpa32U) rsa_wpk->wpk_type1_size; priv_key->pData = (Cpa8U *) qaeMemAllocNUMA(priv_key->dataLenInBytes, 0, 64); if (NULL == priv_key->pData) { priv_key->dataLenInBytes = 0; WARN("Failed to allocate priv_key->pData\n"); return 0; } memcpy(priv_key->pData, rsa_wpk->wpk_type1, priv_key->dataLenInBytes); } else { WARN("Failed to decide key type\n"); return 0; } (*dec_op_data)->inputData.dataLenInBytes = (padding != RSA_NO_PADDING) && alloc_pad ? rsa_len : flen; (*dec_op_data)->inputData.pData = (Cpa8U *) qaeMemAllocNUMA( ((padding != RSA_NO_PADDING) && alloc_pad) ? rsa_len : flen, 0, 64); if (NULL == (*dec_op_data)->inputData.pData) { WARN("Failed to allocate (*dec_op_data)->inputData.pData\n"); return 0; } if (alloc_pad) { switch (padding) { case RSA_PKCS1_PADDING: padding_result = RSA_padding_add_PKCS1_type_1((*dec_op_data)->inputData.pData, rsa_len, from, flen); break; case RSA_X931_PADDING: padding_result = RSA_padding_add_X931((*dec_op_data)->inputData.pData, rsa_len, from, flen); break; case RSA_NO_PADDING: padding_result = RSA_padding_add_none((*dec_op_data)->inputData.pData, rsa_len, from, flen); break; default: break; } } else { padding_result = RSA_padding_add_none((*dec_op_data)->inputData.pData, rsa_len, from, flen); } if (padding_result <= 0) { WARN("Failed to add padding\n"); /* Error is raised within the padding function. */ return 0; } *output_buffer = OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (NULL == *output_buffer) { WARN("Failed to allocate output_buffer\n"); return 0; } /* * Memory allocation for DecOpdata[IN] the size of outputBuffer * should big enough to contain RSA_size */ (*output_buffer)->pData = (Cpa8U *) qaeMemAllocNUMA(rsa_len, 0, 64); if (NULL == (*output_buffer)->pData) { WARN("Failed to allocate output_buffer->pData\n"); return 0; } (*output_buffer)->dataLenInBytes = rsa_len; DEBUG("- Finished\n"); return 1; } void rsa_kpt_decrypt_op_buf_free(CpaCyKptRsaDecryptOpData *dec_op_data, CpaFlatBuffer *out_buf, int *wpk_index) { DEBUG("- Started\n"); if (wpk_index) { *wpk_index = INVALID_WPK_IDX; } if (dec_op_data) { if (dec_op_data->inputData.pData) qaeMemFreeNUMA((void **)&dec_op_data->inputData.pData); if (dec_op_data->pRecipientPrivateKey) { if (CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2 == dec_op_data->pRecipientPrivateKey->privateKeyRepType) { CpaCyKptRsaPrivateKeyRep2 *key = &dec_op_data->pRecipientPrivateKey->privateKeyRep2; OPENSSL_cleanse(key->privateKey.pData, key->privateKey.dataLenInBytes); if (key->privateKey.pData) qaeMemFreeNUMA((void **)&key->privateKey.pData); } else if (CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_1 == dec_op_data->pRecipientPrivateKey->privateKeyRepType) { CpaCyKptRsaPrivateKeyRep1 *key = &dec_op_data->pRecipientPrivateKey->privateKeyRep1; OPENSSL_cleanse(key->privateKey.pData, key->privateKey.dataLenInBytes); if (key->privateKey.pData) qaeMemFreeNUMA((void **)&key->privateKey.pData); } else { WARN("Wrong RSA key type found during cleanup.\n"); } OPENSSL_free(dec_op_data->pRecipientPrivateKey); } OPENSSL_free(dec_op_data); } if (out_buf) { if (out_buf->pData) qaeMemFreeNUMA((void **)&out_buf->pData); OPENSSL_free(out_buf); } } int kpt_rsa_prepare(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaFlatBuffer **output_buffer, CpaCyKptRsaDecryptOpData **kpt_dec_op_data, int alloc_pad, int *wpk_index) { DEBUG("- Started\n"); /* parameter checks */ if (rsa == NULL || from == NULL || to == NULL || flen <= 0) { WARN("RSA key, input or output is NULL or invalid length, \ flen = %d\n", flen); return 0; } if (output_buffer == NULL || kpt_dec_op_data == NULL || wpk_index == NULL) { WARN("KPT input parameters are invalid.\n"); return 0; } if (!kpt_rsa_range_check(RSA_bits((const RSA*)rsa))) return 0; /* Padding check * Note: RSA SSLv23 padding mode is remove in OpenSSL 3.0 * https://github.com/openssl/openssl/issues/14283 */ if ((padding != RSA_NO_PADDING) && (padding != RSA_PKCS1_PADDING) && (padding != RSA_PKCS1_OAEP_PADDING) && #ifndef QAT_OPENSSL_3 (padding != RSA_SSLV23_PADDING) && #endif (padding != RSA_X931_PADDING)) { WARN("Unknown Padding %d\n", padding); return 0; } if (!build_kpt_decrypt_op_buf(flen, from, to, rsa, padding, kpt_dec_op_data, output_buffer, alloc_pad, wpk_index)) { WARN("Failure in build_kpt_decrypt_op_buf\n"); rsa_kpt_decrypt_op_buf_free(*kpt_dec_op_data, *output_buffer, wpk_index); return 0; } DEBUG("- Finished\n"); return 1; } /* Used for RSA Decrypt and RSA Sign */ int kpt_rsa_decrypt(int qat_inst_index, const kpt_rsa_cb_func cb, void *cb_data, CpaCyKptRsaDecryptOpData *dec_op_data, CpaFlatBuffer *output_buf, int wpk_index) { CpaStatus sts = CPA_STATUS_FAIL; CpaInstanceHandle qat_inst_handle; CpaCyKptUnwrapContext *kpt_unwrap_ctx = NULL; if (!kpt_inst_idx_check(qat_inst_index)) { WARN("Invalid QAT instance index.\n"); return sts; } if (dec_op_data == NULL || output_buf == NULL) { WARN("KPT input parameters are invalid.\n"); return sts; } if (!kpt_wpk_idx_check(wpk_index)) { WARN("Invalid WPK index.\n"); return sts; } kpt_unwrap_ctx = &(kpt_inst_prvs_ctx[qat_inst_index].meta_ctx[wpk_index].unwrap_ctx); qat_inst_handle = kpt_inst_prvs_ctx[qat_inst_index].instance_handle; DEBUG("Started - RSA Decryption\n"); DUMP_KPT_RSA_DECRYPT(qat_inst_handle, kpt_unwrap_ctx->kptHandle, NULL, dec_op_data, output_buf); sts = cpaCyKptRsaDecrypt(qat_inst_handle, cb, cb_data, dec_op_data, output_buf, kpt_unwrap_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", sts); return sts; } DEBUG("kpt_rsa_decrypt - status = %d\n", sts); return sts; } void kpt_rsa_finish(CpaCyKptRsaDecryptOpData *dec_op_data, CpaFlatBuffer *out_buf, int *wpk_index) { rsa_kpt_decrypt_op_buf_free(dec_op_data, out_buf, wpk_index); } /** ***************************************************************************** * * KPT ECDSA Sign implementation. * *****************************************************************************/ int kpt_check_ec_wpk(EC_KEY *eckey) { if (eckey) return EC_KEY_get_ex_data(eckey, KEY_WRAP_STORAGE_INDEX) ? 1 : 0; return -1; } static int kpt_BN_to_FB(CpaFlatBuffer * fb, const BIGNUM *bn) { if ((fb == NULL || bn == NULL )) { WARN("Invalid input params.\n"); return 0; } /* Memory allocate for flat buffer */ fb->dataLenInBytes = (Cpa32U) BN_num_bytes(bn); if (0 == fb->dataLenInBytes) { fb->pData = NULL; DEBUG("Datalen = 0, zero byte memory allocation\n"); return 0; } fb->pData = qaeMemAllocNUMA(fb->dataLenInBytes, 0, 64); if (NULL == fb->pData) { fb->dataLenInBytes = 0; WARN("Failed to allocate fb->pData\n"); return 0; } /* * BN_bn2in() converts the absolute value of big number into big-endian * form and stores it at output buffer. the output buffer must point to * BN_num_bytes of memory */ BN_bn2bin(bn, fb->pData); return 1; } int kpt_ecdsa_prepare(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey, BN_CTX **ctx, ECDSA_SIG **ret, CpaFlatBuffer **pResultR, CpaFlatBuffer **pResultS, BIGNUM **ecdsa_sig_r, BIGNUM **ecdsa_sig_s, CpaCyKptEcdsaSignRSOpData **opData, int *wpk_index) { int i = 0; BIGNUM *m = NULL, *order = NULL; const EC_GROUP *group; BIGNUM *priv_key = NULL; kpt_ecc_wpk *ecc_wpk = NULL; size_t buflen; DEBUG("- Started.\n"); /* parameter checks */ if (dgst == NULL || dgst_len <= 0 || eckey == NULL) { WARN("EC key or digest to be signed are invaliad.\n"); return 0; } if (ctx == NULL || ret == NULL || pResultR == NULL || pResultS == NULL || ecdsa_sig_r == NULL || ecdsa_sig_s == NULL || opData == NULL || wpk_index == NULL) { WARN("Invalid KPT input param.\n"); return 0; } ecc_wpk = (kpt_ecc_wpk *)EC_KEY_get_ex_data(eckey, KEY_WRAP_STORAGE_INDEX); if (ecc_wpk == NULL) { WARN("Get EC WPK data failed\n"); return 0; } /* Using the PKEY matched WPK which is specified previously */ *wpk_index = ecc_wpk->wpk_index; if (!kpt_wpk_idx_check(*wpk_index)) { WARN("Invalid WPK index.\n"); return 0; } group = EC_KEY_get0_group(eckey); if (group == NULL) { WARN("Group is NULL\n"); return 0; } *opData = (CpaCyKptEcdsaSignRSOpData *) OPENSSL_zalloc(sizeof(CpaCyKptEcdsaSignRSOpData)); if (*opData == NULL) { WARN("Failure to allocate opData\n"); return 0; } if ((*ret = ECDSA_SIG_new()) == NULL) { WARN("Failure to allocate ECDSA_SIG\n"); goto err; } *ecdsa_sig_r = BN_new(); *ecdsa_sig_s = BN_new(); /* NULL checking of ecdsa_sig_r & ecdsa_sig_s done in ECDSA_SIG_set0() */ if (ECDSA_SIG_set0(*ret, *ecdsa_sig_r, *ecdsa_sig_s) == 0) { WARN("Failure to allocate r and s values to assign to the ECDSA_SIG\n"); goto err; } if ((*ctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); goto err; } BN_CTX_start(*ctx); m = BN_CTX_get(*ctx); order = BN_CTX_get(*ctx); if (order == NULL || m == NULL) { WARN("Failure to allocate m or order\n"); goto err; } if (!EC_GROUP_get_order(group, order, *ctx)) { WARN("Failure to get order from group\n"); goto err; } i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { WARN("Failure to convert dgst to m\n"); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { WARN("Failure to truncate m\n"); goto err; } priv_key = BN_new(); if (!BN_bin2bn(ecc_wpk->wpk, ecc_wpk->wpk_size, priv_key)) { WARN("Failure to convert wpk to priv_key\n"); goto err; } if (kpt_BN_to_FB(&((*opData)->privateKey), (BIGNUM *)priv_key) != 1 || kpt_BN_to_FB(&((*opData)->m), m) != 1) { WARN("Failed to convert d, m to a flatbuffer\n"); goto err; } buflen = EC_GROUP_get_degree(group); *pResultR = (CpaFlatBuffer *) OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (*pResultR == NULL) { WARN("Failure to allocate pResultR\n"); goto err; } (*pResultR)->pData = qaeMemAllocNUMA(buflen, 0, 64); if ((*pResultR)->pData == NULL) { WARN("Failure to allocate pResultR->pData\n"); goto err; } (*pResultR)->dataLenInBytes = (Cpa32U) buflen; *pResultS = (CpaFlatBuffer *) OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (*pResultS == NULL) { WARN("Failure to allocate pResultS\n"); goto err; } (*pResultS)->pData = qaeMemAllocNUMA(buflen, 0, 64); if ((*pResultS)->pData == NULL) { WARN("Failure to allocate pResultS->pData\n"); goto err; } (*pResultS)->dataLenInBytes = (Cpa32U) buflen; DEBUG("- Finished\n"); return 1; err: kpt_ecdsa_finish(*pResultR, *pResultS, *opData, *ctx, wpk_index); return 0; } int kpt_ecdsa_do_sign(int qat_inst_index, const kpt_ecdsa_cb_func cb, void *cb_data, CpaCyKptEcdsaSignRSOpData *opData, CpaBoolean *bEcdsaSignStatus, CpaFlatBuffer *pResultR, CpaFlatBuffer *pResultS, int wpk_index) { CpaStatus sts = CPA_STATUS_FAIL; CpaInstanceHandle qat_inst_handle; CpaCyKptUnwrapContext *kpt_unwrap_ctx = NULL; if (!kpt_inst_idx_check(qat_inst_index)) { WARN("Invalid QAT instance index.\n"); return sts; } if (opData == NULL || bEcdsaSignStatus == NULL || pResultR == NULL || pResultS == NULL) { WARN("KPT input parameters are invalid.\n"); return sts; } if (!kpt_wpk_idx_check(wpk_index)) { WARN("Invalid WPK index.\n"); return sts; } kpt_unwrap_ctx = &(kpt_inst_prvs_ctx[qat_inst_index].meta_ctx[wpk_index].unwrap_ctx); qat_inst_handle = kpt_inst_prvs_ctx[qat_inst_index].instance_handle; DEBUG("Started - ECDSA\n"); DUMP_KPT_ECDSA_SIGN(qat_inst_handle, kpt_unwrap_ctx->kptHandle, opData, pResultR, pResultS); sts = cpaCyKptEcdsaSignRS(qat_inst_handle, cb, cb_data, opData, bEcdsaSignStatus, pResultR, pResultS, kpt_unwrap_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", sts); } return sts; } void kpt_ecdsa_finish(CpaFlatBuffer *pResultR, CpaFlatBuffer *pResultS, CpaCyKptEcdsaSignRSOpData *opData, BN_CTX *ctx, int *wpk_index) { if (wpk_index) { *wpk_index = INVALID_WPK_IDX; } if (pResultR) { if (pResultR->pData) qaeMemFreeNUMA((void **)&(pResultR->pData)); OPENSSL_free(pResultR); } if (pResultS) { if (pResultS->pData) qaeMemFreeNUMA((void **)&(pResultS->pData)); OPENSSL_free(pResultS); } if (opData) { if (opData->m.pData) qaeMemFreeNUMA((void **)&(opData->m.pData)); if (opData->privateKey.pData) qaeMemFreeNUMA((void **)&(opData->privateKey.pData)); OPENSSL_free(opData); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } } qatengine-1.9.0/kpt/lib/kpt.h000066400000000000000000000165451500416242000160140ustar00rootroot00000000000000#ifndef __KPT_H__ # define __KPT_H__ /* Openssl */ #include #include #ifdef QAT_OPENSSL_3 #include #include #include #endif /* QAT includes */ #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_kpt.h" #include "qae_mem.h" #define MAX_ESWK_SIZE (512) #define MAX_IV_SIZE (12) #define MAX_AAD_SIZE (16) /* Support RSA 8k at most */ #define MAX_KPT_RSA_KEY_TYPE1_SIZE (2064) #define MAX_KPT_RSA_KEY_TYPE2_SIZE (3600) #define MAX_KPT_RSA_KEY_N_SIZE (1024) #define MAX_KPT_RSA_KEY_E_SIZE (1024) #define MAX_KPT_ECC_KEY_SIZE (1024) #define PEM_STRING_WRAPPED_RSA_KEY "KPT RSA KEY" #define PEM_STRING_WRAPPED_ECC_KEY "KPT ECC KEY" #define PEM_TYPE_RSA_WPK (1) #define PEM_TYPE_ECC_WPK (2) #define KEY_WRAP_STORAGE_INDEX (143) #define MAX_SOCKET_NUM (32) #define MAX_WPK_NUM (32) #define INVALID_WPK_IDX (-1) #define MAX_CRYPTO_INSTANCES (64) /* ASN1 encoded Wrapped Private Key context format */ /* ESWK part */ typedef struct e_swk{ ASN1_OCTET_STRING *devSig; ASN1_OCTET_STRING *secSWK; } ESWK; DEFINE_STACK_OF(ESWK) DECLARE_ASN1_FUNCTIONS(ESWK) typedef struct wrapping_metadata { ASN1_OCTET_STRING *aesNonce; ASN1_OBJECT *wrappingAlg; STACK_OF(ESWK) *eSWKs; } WRAPPINGMETADATA; DECLARE_ASN1_FUNCTIONS(WRAPPINGMETADATA) /* RSA part */ typedef struct rsa_public_key { ASN1_INTEGER *n; ASN1_INTEGER *e; } RSAPUBLICKEY; DECLARE_ASN1_FUNCTIONS(RSAPUBLICKEY) typedef struct kpt_rsa_key { long version; ASN1_OCTET_STRING *privateKeyType1; ASN1_OCTET_STRING *privateKeyType2; long size; ASN1_OBJECT *kptRSADsi; RSAPUBLICKEY *publicKey; WRAPPINGMETADATA *wrappingMetadata; } KPTRSAKEY; DECLARE_ASN1_FUNCTIONS(KPTRSAKEY) /* ECC part */ typedef struct kpt_ecc_key { long version; ASN1_OCTET_STRING *privateKey; ASN1_OBJECT *curveName; ASN1_BIT_STRING *publicKey; WRAPPINGMETADATA *wrappingMetadata; } KPTECCKEY; DECLARE_ASN1_FUNCTIONS(KPTECCKEY) /* Local struct to store content of WPK file */ typedef struct kpt_rsa_wpk_st { long version; long size; unsigned char wpk_type1[MAX_KPT_RSA_KEY_TYPE1_SIZE]; unsigned char wpk_type2[MAX_KPT_RSA_KEY_TYPE2_SIZE]; unsigned char n[MAX_KPT_RSA_KEY_N_SIZE]; unsigned char e[MAX_KPT_RSA_KEY_E_SIZE]; int wpk_type1_size; int wpk_type2_size; int n_size; int e_size; int wrapping_alg_nid; /* for global wpk<->eswk<->instance mapping */ int wpk_index; }kpt_rsa_wpk; typedef struct kpt_ecc_wpk_st { long version; unsigned char wpk[MAX_KPT_ECC_KEY_SIZE]; unsigned char pub_key[MAX_KPT_ECC_KEY_SIZE]; int wpk_size; int pub_key_size; /* optional NID for named curve */ int curve_nid; int wrapping_alg_nid; /* for global wpk<->eswk<->instance mapping */ int wpk_index; }kpt_ecc_wpk; /* Encrypted Symmetric Wrapping Key metadata for KPT provision */ typedef struct { unsigned char eswk[MAX_ESWK_SIZE]; int len_eswk; unsigned char iv[MAX_IV_SIZE]; int len_iv; unsigned char aad[MAX_AAD_SIZE]; int len_aad; } kpt_eswk_meta_data_st; /* Signature of KPT Per-Part Key to distinguish QAT devices */ typedef struct { unsigned char signature[MAX_ESWK_SIZE]; int len_sig; } kpt_dev_identity_st; /* Device credentials loaded from WPK file */ typedef struct { int total; kpt_eswk_meta_data_st eswk_data[MAX_SOCKET_NUM]; kpt_dev_identity_st dev_id[MAX_SOCKET_NUM]; } kpt_dev_credential_st; typedef enum { NON_WPK = 0, RSA_WPK, ECC_WPK, } kpt_wpk_type; #define KPT_DEV_CREDENTIAL_SIZE_IN_BYTE (384) #define KPT_ENCRYPTED_SWK_SIZE_IN_BYTE (384) #define KPT_PER_PART_PUBKEY_N_SIZE_IN_BYTE (384) #define KPT_PER_PART_PUBKEY_E_SIZE_IN_BYTE (8) typedef enum { KPT_NON_SHARE_MODE = 0, KPT_SHARE_MODE } kpt_share_mode; /* KPT provision metadata for each ESWK */ typedef struct { int swk_provisioned; CpaCyKptUnwrapContext unwrap_ctx; CpaCyKptLoadKey wrapping_key; } kpt_provision_meta_cxt_st; /* KPT provision context for each instance */ typedef struct { int kpt_enabled; kpt_share_mode mode; CpaInstanceHandle instance_handle; kpt_provision_meta_cxt_st meta_ctx[MAX_WPK_NUM]; } kpt_inst_provision_context_st; typedef void (*kpt_rsa_cb_func)(void *pCallbackTag, CpaStatus status, void *pOpdata, CpaFlatBuffer *pOut); typedef void (*kpt_ecdsa_cb_func)(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bEcdsaSignStatus, CpaFlatBuffer * pResultR, CpaFlatBuffer * pResultS); /* WPK file parse function. It retrieves private key information from ASN1 * encoded stream and saves the data into kpt_rsa_wpk struct. * The kpt_rsa_wpk will be stored into EVP_PKEY->ex_data for later usage. */ EVP_PKEY *kpt_load_priv_key(ENGINE *e, const char *wpk); /* Reset the index of WPK loading for Nginx reload case. */ int kpt_reset_wpk_num(); /* Check the instance whether is provisioned or not. */ int kpt_instance_available(int qat_inst_index, int wpk_index); /* KPT init functions, doing SWK provision. * Note that this library is not responsible for the QAT instance management, * so instances should be inited and started out of the library. */ int kpt_init(int qat_inst_index, CpaInstanceHandle qat_inst_handle); /* KPT finish functions, deleting provisioned SWK. */ void kpt_finish(int qat_inst_index, CpaInstanceHandle qat_inst_handle); /* RSA Operations*/ int kpt_check_rsa_wpk(RSA *rsa); int kpt_rsa_prepare(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaFlatBuffer **output_buffer, CpaCyKptRsaDecryptOpData **kpt_dec_op_data, int alloc_pad, int *wpk_index); int kpt_rsa_decrypt(int qat_inst_index, const kpt_rsa_cb_func cb, void *cb_data, CpaCyKptRsaDecryptOpData *dec_op_data, CpaFlatBuffer *output_buf, int wpk_index); void kpt_rsa_finish(CpaCyKptRsaDecryptOpData *dec_op_data, CpaFlatBuffer *out_buf, int *wpk_index); /* ECDSA Operations */ int kpt_check_ec_wpk(EC_KEY *eckey); int kpt_ecdsa_prepare(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey, BN_CTX **ctx, ECDSA_SIG **ret, CpaFlatBuffer **pResultR, CpaFlatBuffer **pResultS, BIGNUM **ecdsa_sig_r, BIGNUM **ecdsa_sig_s, CpaCyKptEcdsaSignRSOpData **opData, int *wpk_index); int kpt_ecdsa_do_sign(int qat_inst_index, const kpt_ecdsa_cb_func cb, void *cb_data, CpaCyKptEcdsaSignRSOpData *opData, CpaBoolean *bEcdsaSignStatus, CpaFlatBuffer *pResultR, CpaFlatBuffer *pResultS, int wpk_index); void kpt_ecdsa_finish(CpaFlatBuffer *pResultR, CpaFlatBuffer *pResultS, CpaCyKptEcdsaSignRSOpData *opData, BN_CTX *ctx, int *wpk_index); #endif qatengine-1.9.0/kpt/lib/kpt_utils.h000066400000000000000000000154061500416242000172270ustar00rootroot00000000000000#ifndef __KPT2_UTILS_H__ #define __KPT2_UTILS_H__ #include #define NANO_TO_MICROSECS 1000 #ifdef KPT_DEBUG void kpt_hex_dump(const char *func, const char *var, const unsigned char p[], int l) { int i; fputc('\n', stderr); fprintf(stderr, "%s: %s: Length %d, Address %p \n", func, var, l, p); if (NULL != p && l > 0) { for (i = 0; i < l; i++) { if (i % 32 == 0) fputc('\n', stderr); else if (i % 8 == 0) fputs("- ", stderr); fprintf(stderr, "%02x", p[i]); } } fputc('\n', stderr); } # define DEBUG(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ fprintf(stdout,"[DEBUG][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(stdout); \ } while (0) # define DUMPL(var,p,l) kpt_hex_dump(__func__,var,p,l); #else # define DEBUG(...) # define DUMPL(...) #endif #if defined(KPT_WARN) || defined(KPT_DEBUG) # define WARN(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ fprintf(stderr,"[WARN][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(stderr); \ } while (0) # else # define WARN(...) # endif #ifdef KPT_DEBUG # define DUMP_KPT_WRAPPING_DATA(eswk, len_eswk, sig, len_sig, iv, len_iv, \ aad, len_aad) \ do { \ fprintf(stdout,"=========================\n"); \ fprintf(stdout,"KPT Wrapping Metadata\n"); \ DUMPL("ESWK", eswk, len_eswk); \ DUMPL("Signature", sig, len_sig); \ DUMPL("IV", iv, len_iv); \ DUMPL("AAD", aad, len_aad); \ fprintf(stdout,"=========================\n"); \ fflush(stdout); \ } while (0) # define DUMP_KPT_RSA_DECRYPT(instance_handle, kpt_handle, \ op_done, opData, output_buf) \ do { \ fprintf(stdout,"=========================\n"); \ fprintf(stdout,"RSA Decrypt Request: %p\n", opData); \ fprintf(stdout,"instance_handle = %p\n", instance_handle); \ fprintf(stdout,"KPT handle = 0x%lx\n", kpt_handle); \ fprintf(stdout,"op_done = %p\n", op_done); \ fprintf(stdout,"opData: pRecipientPrivateKey->version = %d\n", \ opData->pRecipientPrivateKey->version); \ fprintf(stdout,"opData: pRecipientPrivateKey" \ "->privateKeyRepType = %d\n", \ opData->pRecipientPrivateKey->privateKeyRepType); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep1.privateKey.pData", \ opData->pRecipientPrivateKey->privateKeyRep1.privateKey.pData, \ opData->pRecipientPrivateKey->privateKeyRep1.privateKey. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.privateKey.pData", \ opData->pRecipientPrivateKey->privateKeyRep2.privateKey.pData, \ opData->pRecipientPrivateKey->privateKeyRep2.privateKey. \ dataLenInBytes); \ DUMPL("opData: inputData.pData", opData->inputData.pData, \ opData->inputData.dataLenInBytes); \ fprintf(stdout,"output_buf = %p\n", output_buf); \ fprintf(stdout,"=========================\n"); \ fflush(stdout); \ } while (0) # define DUMP_KPT_ECDSA_SIGN(instance_handle, kpt_handle, \ opData, pResultR, pResultS) \ do { \ fprintf(stdout,"=========================\n"); \ fprintf(stdout,"KPT ECDSA Sign Request: %p\n", opData); \ fprintf(stdout,"instance_handle ptr = %p\n", instance_handle); \ fprintf(stdout,"KPT handle = 0x%lx\n", kpt_handle); \ DUMPL("m.pData", opData->m.pData, opData->m.dataLenInBytes); \ DUMPL("WPK data", opData->privateKey.pData, \ opData->privateKey.dataLenInBytes); \ fprintf(stdout,"pResultR->dataLenInBytes = %u " \ "pResultR->pData = %p\n", \ pResultR->dataLenInBytes, pResultR->pData); \ fprintf(stdout,"pResultS->dataLenInBytes = %u " \ "pResultS->pData = %p\n", \ pResultS->dataLenInBytes, pResultS->pData); \ fprintf(stdout,"=========================\n"); \ fflush(stdout); \ } while (0) #else # define DUMP_KPT_WRAPPING_DATA(...) # define DUMP_KPT_RSA_DECRYPT(...) # define DUMP_KPT_ECDSA_SIGN(...) #endif #endifqatengine-1.9.0/plock.c000066400000000000000000000103561500416242000147470ustar00rootroot00000000000000/* pthread_rwlock emulation (version without exponential back-off) * * Copyright (C) 2022-2025 Willy Tarreau * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* Pthread rwlock emulation using plocks (to avoid expensive futexes). * * These are a direct mapping on Progressive Locks, with the exception that * since there's a common unlock operation in pthreads, we need to know if * we need to unlock for reads or writes, so we set the topmost bit to 1 when * a write lock is acquired to indicate that a write unlock needs to be * performed. This only divides by two the maximum number of threads that * may be supported compared to the default plock implementation, which is * generally OK. In order to ease integration into existing code, the storage * here is the provided pthread_rwlock_t cast as a unsigned long. It is * expected to be zero when unlocked so that code that would forget to * call pthread_rwlock_init() after a calloc() and that would happen to work * by pure luck would continue to work. * * This variant does NOT use exponential backoff as it was found to * significantly reduce performance on some platforms when the application * makes excessive use of pthread_rwlocks but contention remains low (which * is often the case when using rwlocks). If this is needed in the future, * please do not do it in this file and provide it in an alternate one * instead so that users can choose the one they want. * * It is recommended to link this code statically into the target executable * to make sure that the redefined symbols have precedence over the ones * provided by an external shared pthread library. It has no other dependency * beyond pthread and plock.h, so the build process is trivial: * * $ cc -O2 -c pth_rwl.c -pthread * # link the resulting .o into the final executable * * This source file (and its required dependencies) may be directly copied into * the target project as long as its license is compatible with this one (which * should generally be the case). */ #include #include "plock.h" int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr) { unsigned long *lock = (unsigned long *)rwlock; *lock = 0; return 0; } int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) { unsigned long *lock = (unsigned long *)rwlock; *lock = 0; return 0; } int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) { pl_lorw_rdlock((unsigned long *)rwlock); return 0; } int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) { return !!pl_cmpxchg((unsigned long *)rwlock, 0, PLOCK_LORW_SHR_BASE); } int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abstime) { return pthread_rwlock_tryrdlock(rwlock); } int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { pl_lorw_wrlock((unsigned long *)rwlock); return 0; } int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) { return !!pl_cmpxchg((unsigned long *)rwlock, 0, PLOCK_LORW_EXC_BASE); } int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abstime) { return pthread_rwlock_trywrlock(rwlock); } int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { pl_lorw_unlock((unsigned long *)rwlock); return 0; } qatengine-1.9.0/plock.h000077500000000000000000002524771500416242000147730ustar00rootroot00000000000000/* plock - progressive locks * * Copyright (C) 2012-2017 Willy Tarreau * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include "atomic-ops.h" #ifdef _POSIX_PRIORITY_SCHEDULING #include #endif /* 64 bit */ #define PLOCK64_RL_1 0x0000000000000004ULL #define PLOCK64_RL_2PL 0x00000000FFFFFFF8ULL #define PLOCK64_RL_ANY 0x00000000FFFFFFFCULL #define PLOCK64_SL_1 0x0000000100000000ULL #define PLOCK64_SL_ANY 0x0000000300000000ULL #define PLOCK64_WL_1 0x0000000400000000ULL #define PLOCK64_WL_2PL 0xFFFFFFF800000000ULL #define PLOCK64_WL_ANY 0xFFFFFFFC00000000ULL /* 32 bit */ #define PLOCK32_RL_1 0x00000004 #define PLOCK32_RL_2PL 0x0000FFF8 #define PLOCK32_RL_ANY 0x0000FFFC #define PLOCK32_SL_1 0x00010000 #define PLOCK32_SL_ANY 0x00030000 #define PLOCK32_WL_1 0x00040000 #define PLOCK32_WL_2PL 0xFFF80000 #define PLOCK32_WL_ANY 0xFFFC0000 /* dereferences <*p> as unsigned long without causing aliasing issues */ #define pl_deref_long(p) ({ volatile unsigned long *__pl_l = (unsigned long *)(p); *__pl_l; }) /* dereferences <*p> as unsigned int without causing aliasing issues */ #define pl_deref_int(p) ({ volatile unsigned int *__pl_i = (unsigned int *)(p); *__pl_i; }) /* This function waits for to release all bits covered by , and * enforces an exponential backoff using CPU pauses to limit the pollution to * the other threads' caches. The progression follows (1.5^N)-1, limited to * 16384 iterations, which is way sufficient even for very large numbers of * threads. It's possible to disable exponential backoff (EBO) for debugging * purposes by setting PLOCK_DISABLE_EBO, in which case the function will be * replaced with a simpler macro. This may for example be useful to more * easily track callers' CPU usage. The macro was not designed to be used * outside of the functions defined here. */ #if defined(PLOCK_DISABLE_EBO) #define pl_wait_unlock_long(lock, mask) \ ({ \ unsigned long _r; \ do { \ pl_cpu_relax(); \ _r = pl_deref_long(lock); \ } while (_r & mask); \ _r; /* return value */ \ }) #else __attribute__((unused,noinline,no_instrument_function)) static unsigned long pl_wait_unlock_long(const unsigned long *lock, const unsigned long mask) { unsigned long ret; unsigned int m = 0; do { unsigned int loops = m; #ifdef _POSIX_PRIORITY_SCHEDULING if (loops >= 65536) { sched_yield(); loops -= 32768; } #endif for (; loops >= 200; loops -= 10) pl_cpu_relax(); for (; loops >= 1; loops--) pl_barrier(); ret = pl_deref_long(lock); if (__builtin_expect(ret & mask, 0) == 0) break; /* the below produces an exponential growth with loops to lower * values and still growing. This allows competing threads to * wait different times once the threshold is reached. */ m = ((m + (m >> 1)) + 2) & 0x3ffff; } while (1); return ret; } #endif /* PLOCK_DISABLE_EBO */ /* This function waits for to release all bits covered by , and * enforces an exponential backoff using CPU pauses to limit the pollution to * the other threads' caches. The progression follows (2^N)-1, limited to 255 * iterations, which is way sufficient even for very large numbers of threads. * The function slightly benefits from size optimization under gcc, but Clang * cannot do it, so it's not done here, as it doesn't make a big difference. * It is possible to disable exponential backoff (EBO) for debugging purposes * by setting PLOCK_DISABLE_EBO, in which case the function will be replaced * with a simpler macro. This may for example be useful to more easily track * callers' CPU usage. The macro was not designed to be used outside of the * functions defined here. */ #if defined(PLOCK_DISABLE_EBO) #define pl_wait_unlock_int(lock, mask) \ ({ \ unsigned int _r; \ do { \ pl_cpu_relax(); \ _r = pl_deref_int(lock); \ } while (_r & mask); \ _r; /* return value */ \ }) #else __attribute__((unused,noinline,no_instrument_function)) static unsigned int pl_wait_unlock_int(const unsigned int *lock, const unsigned int mask) { unsigned int ret; unsigned int m = 0; do { unsigned int loops = m; #ifdef _POSIX_PRIORITY_SCHEDULING if (loops >= 65536) { sched_yield(); loops -= 32768; } #endif for (; loops >= 200; loops -= 10) pl_cpu_relax(); for (; loops >= 1; loops--) pl_barrier(); ret = pl_deref_int(lock); if (__builtin_expect(ret & mask, 0) == 0) break; /* the below produces an exponential growth with loops to lower * values and still growing. This allows competing threads to * wait different times once the threshold is reached. */ m = ((m + (m >> 1)) + 2) & 0x3ffff; } while (1); return ret; } #endif /* PLOCK_DISABLE_EBO */ /* This function waits for to change from value and returns the * new value. It enforces an exponential backoff using CPU pauses to limit the * pollution to the other threads' caches. The progression follows (2^N)-1, * limited to 255 iterations, which is way sufficient even for very large * numbers of threads. It is designed to be called after a first test which * retrieves the previous value, so it starts by waiting. The function slightly * benefits from size optimization under gcc, but Clang cannot do it, so it's * not done here, as it doesn't make a big difference. */ __attribute__((unused,noinline,no_instrument_function)) static unsigned long pl_wait_new_long(const unsigned long *lock, const unsigned long prev) { unsigned char m = 0; unsigned long curr; do { unsigned char loops = m + 1; m = (m << 1) + 1; do { pl_cpu_relax(); } while (__builtin_expect(--loops, 0)); curr = pl_deref_long(lock); } while (__builtin_expect(curr == prev, 0)); return curr; } /* This function waits for to change from value and returns the * new value. It enforces an exponential backoff using CPU pauses to limit the * pollution to the other threads' caches. The progression follows (2^N)-1, * limited to 255 iterations, which is way sufficient even for very large * numbers of threads. It is designed to be called after a first test which * retrieves the previous value, so it starts by waiting. The function slightly * benefits from size optimization under gcc, but Clang cannot do it, so it's * not done here, as it doesn't make a big difference. */ __attribute__((unused,noinline,no_instrument_function)) static unsigned int pl_wait_new_int(const unsigned int *lock, const unsigned int prev) { unsigned char m = 0; unsigned int curr; do { unsigned char loops = m + 1; m = (m << 1) + 1; do { pl_cpu_relax(); } while (__builtin_expect(--loops, 0)); curr = pl_deref_int(lock); } while (__builtin_expect(curr == prev, 0)); return curr; } /* request shared read access (R), return non-zero on success, otherwise 0 */ #define pl_try_r(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_deref_long(lock) & PLOCK64_WL_ANY; \ pl_barrier(); \ if (!__builtin_expect(__pl_r, 0)) { \ __pl_r = pl_xadd((lock), PLOCK64_RL_1) & PLOCK64_WL_ANY; \ if (__builtin_expect(__pl_r, 0)) \ pl_sub((lock), PLOCK64_RL_1); \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_deref_int(lock) & PLOCK32_WL_ANY; \ pl_barrier(); \ if (!__builtin_expect(__pl_r, 0)) { \ __pl_r = pl_xadd((lock), PLOCK32_RL_1) & PLOCK32_WL_ANY; \ if (__builtin_expect(__pl_r, 0)) \ pl_sub((lock), PLOCK32_RL_1); \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_r__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_r__(__FILE__,__LINE__); \ 0; \ }) \ ) /* request shared read access (R) and wait for it. In order not to disturb a W * lock waiting for all readers to leave, we first check if a W lock is held * before trying to claim the R lock. */ #define pl_take_r(lock) \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_RL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY; \ while (1) { \ if (__builtin_expect(pl_deref_long(__lk_r) & __msk_r, 0)) \ pl_wait_unlock_long(__lk_r, __msk_r); \ if (!__builtin_expect(pl_xadd(__lk_r, __set_r) & __msk_r, 0)) \ break; \ pl_sub(__lk_r, __set_r); \ } \ pl_barrier(); \ 0; \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_RL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY; \ while (1) { \ if (__builtin_expect(pl_deref_int(__lk_r) & __msk_r, 0)) \ pl_wait_unlock_int(__lk_r, __msk_r); \ if (!__builtin_expect(pl_xadd(__lk_r, __set_r) & __msk_r, 0)) \ break; \ pl_sub(__lk_r, __set_r); \ } \ pl_barrier(); \ 0; \ }) : ({ \ void __unsupported_argument_size_for_pl_take_r__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_take_r__(__FILE__,__LINE__); \ 0; \ }) /* release the read access (R) lock */ #define pl_drop_r(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_RL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_RL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_drop_r__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_drop_r__(__FILE__,__LINE__); \ }) \ ) /* request a seek access (S), return non-zero on success, otherwise 0 */ #define pl_try_s(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_deref_long(lock); \ pl_barrier(); \ if (!__builtin_expect(__pl_r & (PLOCK64_WL_ANY | PLOCK64_SL_ANY), 0)) { \ __pl_r = pl_xadd((lock), PLOCK64_SL_1 | PLOCK64_RL_1) & \ (PLOCK64_WL_ANY | PLOCK64_SL_ANY); \ if (__builtin_expect(__pl_r, 0)) \ pl_sub((lock), PLOCK64_SL_1 | PLOCK64_RL_1); \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_deref_int(lock); \ pl_barrier(); \ if (!__builtin_expect(__pl_r & (PLOCK32_WL_ANY | PLOCK32_SL_ANY), 0)) { \ __pl_r = pl_xadd((lock), PLOCK32_SL_1 | PLOCK32_RL_1) & \ (PLOCK32_WL_ANY | PLOCK32_SL_ANY); \ if (__builtin_expect(__pl_r, 0)) \ pl_sub((lock), PLOCK32_SL_1 | PLOCK32_RL_1); \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_s__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_s__(__FILE__,__LINE__); \ 0; \ }) \ ) /* request a seek access (S) and wait for it. The lock is immediately claimed, * and only upon failure an exponential backoff is used. S locks rarely compete * with W locks so S will generally not disturb W. As the S lock may be used as * a spinlock, it's important to grab it as fast as possible. */ #define pl_take_s(lock) \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_SL_1 | PLOCK64_RL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY | PLOCK64_SL_ANY; \ while (1) { \ if (!__builtin_expect(pl_xadd(__lk_r, __set_r) & __msk_r, 0)) \ break; \ pl_sub(__lk_r, __set_r); \ pl_wait_unlock_long(__lk_r, __msk_r); \ } \ pl_barrier(); \ 0; \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_SL_1 | PLOCK32_RL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY | PLOCK32_SL_ANY; \ while (1) { \ if (!__builtin_expect(pl_xadd(__lk_r, __set_r) & __msk_r, 0)) \ break; \ pl_sub(__lk_r, __set_r); \ pl_wait_unlock_int(__lk_r, __msk_r); \ } \ pl_barrier(); \ 0; \ }) : ({ \ void __unsupported_argument_size_for_pl_take_s__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_take_s__(__FILE__,__LINE__); \ 0; \ }) /* release the seek access (S) lock */ #define pl_drop_s(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_SL_1 + PLOCK64_RL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_SL_1 + PLOCK32_RL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_drop_s__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_drop_s__(__FILE__,__LINE__); \ }) \ ) /* drop the S lock and go back to the R lock */ #define pl_stor(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_SL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_SL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_stor__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_stor__(__FILE__,__LINE__); \ }) \ ) /* take the W lock under the S lock */ #define pl_stow(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_xadd((lock), PLOCK64_WL_1); \ while ((__pl_r & PLOCK64_RL_ANY) != PLOCK64_RL_1) \ __pl_r = pl_deref_long(lock); \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_xadd((lock), PLOCK32_WL_1); \ while ((__pl_r & PLOCK32_RL_ANY) != PLOCK32_RL_1) \ __pl_r = pl_deref_int(lock); \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_stow__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_stow__(__FILE__,__LINE__); \ }) \ ) /* drop the W lock and go back to the S lock */ #define pl_wtos(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_WL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_WL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_wtos__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_wtos__(__FILE__,__LINE__); \ }) \ ) /* drop the W lock and go back to the R lock */ #define pl_wtor(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_WL_1 | PLOCK64_SL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_WL_1 | PLOCK32_SL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_wtor__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_wtor__(__FILE__,__LINE__); \ }) \ ) /* request a write access (W), return non-zero on success, otherwise 0. * * Below there is something important : by taking both W and S, we will cause * an overflow of W at 4/5 of the maximum value that can be stored into W due * to the fact that S is 2 bits, so we're effectively adding 5 to the word * composed by W:S. But for all words multiple of 4 bits, the maximum value is * multiple of 15 thus of 5. So the largest value we can store with all bits * set to one will be met by adding 5, and then adding 5 again will place value * 1 in W and value 0 in S, so we never leave W with 0. Also, even upon such an * overflow, there's no risk to confuse it with an atomic lock because R is not * null since it will not have overflown. For 32-bit locks, this situation * happens when exactly 13108 threads try to grab the lock at once, W=1, S=0 * and R=13108. For 64-bit locks, it happens at 858993460 concurrent writers * where W=1, S=0 and R=858993460. */ #define pl_try_w(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_deref_long(lock); \ pl_barrier(); \ if (!__builtin_expect(__pl_r & (PLOCK64_WL_ANY | PLOCK64_SL_ANY), 0)) { \ __pl_r = pl_xadd((lock), PLOCK64_WL_1 | PLOCK64_SL_1 | PLOCK64_RL_1); \ if (__builtin_expect(__pl_r & (PLOCK64_WL_ANY | PLOCK64_SL_ANY), 0)) { \ /* a writer, seeker or atomic is present, let's leave */ \ pl_sub((lock), PLOCK64_WL_1 | PLOCK64_SL_1 | PLOCK64_RL_1); \ __pl_r &= (PLOCK64_WL_ANY | PLOCK64_SL_ANY); /* return value */\ } else { \ /* wait for all other readers to leave */ \ while (__pl_r) \ __pl_r = pl_deref_long(lock) - \ (PLOCK64_WL_1 | PLOCK64_SL_1 | PLOCK64_RL_1); \ } \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_deref_int(lock); \ pl_barrier(); \ if (!__builtin_expect(__pl_r & (PLOCK32_WL_ANY | PLOCK32_SL_ANY), 0)) { \ __pl_r = pl_xadd((lock), PLOCK32_WL_1 | PLOCK32_SL_1 | PLOCK32_RL_1); \ if (__builtin_expect(__pl_r & (PLOCK32_WL_ANY | PLOCK32_SL_ANY), 0)) { \ /* a writer, seeker or atomic is present, let's leave */ \ pl_sub((lock), PLOCK32_WL_1 | PLOCK32_SL_1 | PLOCK32_RL_1); \ __pl_r &= (PLOCK32_WL_ANY | PLOCK32_SL_ANY); /* return value */\ } else { \ /* wait for all other readers to leave */ \ while (__pl_r) \ __pl_r = pl_deref_int(lock) - \ (PLOCK32_WL_1 | PLOCK32_SL_1 | PLOCK32_RL_1); \ } \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_w__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_w__(__FILE__,__LINE__); \ 0; \ }) \ ) /* request a write access (W) and wait for it. The lock is immediately claimed, * and only upon failure an exponential backoff is used. */ #define pl_take_w(lock) \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_WL_1 | PLOCK64_SL_1 | PLOCK64_RL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY | PLOCK64_SL_ANY; \ register unsigned long __pl_r; \ while (1) { \ __pl_r = pl_xadd(__lk_r, __set_r); \ if (!__builtin_expect(__pl_r & __msk_r, 0)) \ break; \ pl_sub(__lk_r, __set_r); \ __pl_r = pl_wait_unlock_long(__lk_r, __msk_r); \ } \ /* wait for all other readers to leave */ \ while (__builtin_expect(__pl_r, 0)) \ __pl_r = pl_deref_long(__lk_r) - __set_r; \ pl_barrier(); \ 0; \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_WL_1 | PLOCK32_SL_1 | PLOCK32_RL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY | PLOCK32_SL_ANY; \ register unsigned int __pl_r; \ while (1) { \ __pl_r = pl_xadd(__lk_r, __set_r); \ if (!__builtin_expect(__pl_r & __msk_r, 0)) \ break; \ pl_sub(__lk_r, __set_r); \ __pl_r = pl_wait_unlock_int(__lk_r, __msk_r); \ } \ /* wait for all other readers to leave */ \ while (__builtin_expect(__pl_r, 0)) \ __pl_r = pl_deref_int(__lk_r) - __set_r; \ pl_barrier(); \ 0; \ }) : ({ \ void __unsupported_argument_size_for_pl_take_w__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_take_w__(__FILE__,__LINE__); \ 0; \ }) /* drop the write (W) lock entirely */ #define pl_drop_w(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_WL_1 | PLOCK64_SL_1 | PLOCK64_RL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_WL_1 | PLOCK32_SL_1 | PLOCK32_RL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_drop_w__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_drop_w__(__FILE__,__LINE__); \ }) \ ) /* Try to upgrade from R to S, return non-zero on success, otherwise 0. * This lock will fail if S or W are already held. In case of failure to grab * the lock, it MUST NOT be retried without first dropping R, or it may never * complete due to S waiting for R to leave before upgrading to W. */ #define pl_try_rtos(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_deref_long(lock); \ pl_barrier(); \ if (!__builtin_expect(__pl_r & (PLOCK64_WL_ANY | PLOCK64_SL_ANY), 0)) { \ __pl_r = pl_xadd((lock), PLOCK64_SL_1) & \ (PLOCK64_WL_ANY | PLOCK64_SL_ANY); \ if (__builtin_expect(__pl_r, 0)) \ pl_sub((lock), PLOCK64_SL_1); \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_deref_int(lock); \ pl_barrier(); \ if (!__builtin_expect(__pl_r & (PLOCK32_WL_ANY | PLOCK32_SL_ANY), 0)) { \ __pl_r = pl_xadd((lock), PLOCK32_SL_1) & \ (PLOCK32_WL_ANY | PLOCK32_SL_ANY); \ if (__builtin_expect(__pl_r, 0)) \ pl_sub((lock), PLOCK32_SL_1); \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_rtos__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_rtos__(__FILE__,__LINE__); \ 0; \ }) \ ) /* Try to upgrade from R to W, return non-zero on success, otherwise 0. * This lock will fail if S or W are already held. In case of failure to grab * the lock, it MUST NOT be retried without first dropping R, or it may never * complete due to S waiting for R to leave before upgrading to W. It waits for * the last readers to leave. */ #define pl_try_rtow(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_WL_1 | PLOCK64_SL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY | PLOCK64_SL_ANY; \ register unsigned long __pl_r; \ pl_barrier(); \ while (1) { \ __pl_r = pl_xadd(__lk_r, __set_r); \ if (__builtin_expect(__pl_r & __msk_r, 0)) { \ if (pl_xadd(__lk_r, - __set_r)) \ break; /* the caller needs to drop the lock now */ \ continue; /* lock was released, try again */ \ } \ /* ok we're the only writer, wait for readers to leave */ \ while (__builtin_expect(__pl_r, 0)) \ __pl_r = pl_deref_long(__lk_r) - (PLOCK64_WL_1|PLOCK64_SL_1|PLOCK64_RL_1); \ /* now return with __pl_r = 0 */ \ break; \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_WL_1 | PLOCK32_SL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY | PLOCK32_SL_ANY; \ register unsigned int __pl_r; \ pl_barrier(); \ while (1) { \ __pl_r = pl_xadd(__lk_r, __set_r); \ if (__builtin_expect(__pl_r & __msk_r, 0)) { \ if (pl_xadd(__lk_r, - __set_r)) \ break; /* the caller needs to drop the lock now */ \ continue; /* lock was released, try again */ \ } \ /* ok we're the only writer, wait for readers to leave */ \ while (__builtin_expect(__pl_r, 0)) \ __pl_r = pl_deref_int(__lk_r) - (PLOCK32_WL_1|PLOCK32_SL_1|PLOCK32_RL_1); \ /* now return with __pl_r = 0 */ \ break; \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_rtow__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_rtow__(__FILE__,__LINE__); \ 0; \ }) \ ) /* request atomic write access (A), return non-zero on success, otherwise 0. * It's a bit tricky as we only use the W bits for this and want to distinguish * between other atomic users and regular lock users. We have to give up if an * S lock appears. It's possible that such a lock stays hidden in the W bits * after an overflow, but in this case R is still held, ensuring we stay in the * loop until we discover the conflict. The lock only return successfully if all * readers are gone (or converted to A). */ #define pl_try_a(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_deref_long(lock) & PLOCK64_SL_ANY; \ pl_barrier(); \ if (!__builtin_expect(__pl_r, 0)) { \ __pl_r = pl_xadd((lock), PLOCK64_WL_1); \ while (1) { \ if (__builtin_expect(__pl_r & PLOCK64_SL_ANY, 0)) { \ pl_sub((lock), PLOCK64_WL_1); \ break; /* return !__pl_r */ \ } \ __pl_r &= PLOCK64_RL_ANY; \ if (!__builtin_expect(__pl_r, 0)) \ break; /* return !__pl_r */ \ __pl_r = pl_deref_long(lock); \ } \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_deref_int(lock) & PLOCK32_SL_ANY; \ pl_barrier(); \ if (!__builtin_expect(__pl_r, 0)) { \ __pl_r = pl_xadd((lock), PLOCK32_WL_1); \ while (1) { \ if (__builtin_expect(__pl_r & PLOCK32_SL_ANY, 0)) { \ pl_sub((lock), PLOCK32_WL_1); \ break; /* return !__pl_r */ \ } \ __pl_r &= PLOCK32_RL_ANY; \ if (!__builtin_expect(__pl_r, 0)) \ break; /* return !__pl_r */ \ __pl_r = pl_deref_int(lock); \ } \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_a__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_a__(__FILE__,__LINE__); \ 0; \ }) \ ) /* request atomic write access (A) and wait for it. See comments in pl_try_a() for * explanations. */ #define pl_take_a(lock) \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_WL_1; \ register unsigned long __msk_r = PLOCK64_SL_ANY; \ register unsigned long __pl_r; \ __pl_r = pl_xadd(__lk_r, __set_r); \ while (__builtin_expect(__pl_r & PLOCK64_RL_ANY, 0)) { \ if (__builtin_expect(__pl_r & __msk_r, 0)) { \ pl_sub(__lk_r, __set_r); \ pl_wait_unlock_long(__lk_r, __msk_r); \ __pl_r = pl_xadd(__lk_r, __set_r); \ continue; \ } \ /* wait for all readers to leave or upgrade */ \ pl_cpu_relax(); pl_cpu_relax(); pl_cpu_relax(); \ __pl_r = pl_deref_long(lock); \ } \ pl_barrier(); \ 0; \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_WL_1; \ register unsigned int __msk_r = PLOCK32_SL_ANY; \ register unsigned int __pl_r; \ __pl_r = pl_xadd(__lk_r, __set_r); \ while (__builtin_expect(__pl_r & PLOCK32_RL_ANY, 0)) { \ if (__builtin_expect(__pl_r & __msk_r, 0)) { \ pl_sub(__lk_r, __set_r); \ pl_wait_unlock_int(__lk_r, __msk_r); \ __pl_r = pl_xadd(__lk_r, __set_r); \ continue; \ } \ /* wait for all readers to leave or upgrade */ \ pl_cpu_relax(); pl_cpu_relax(); pl_cpu_relax(); \ __pl_r = pl_deref_int(lock); \ } \ pl_barrier(); \ 0; \ }) : ({ \ void __unsupported_argument_size_for_pl_take_a__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_take_a__(__FILE__,__LINE__); \ 0; \ }) /* release atomic write access (A) lock */ #define pl_drop_a(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_WL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_WL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_drop_a__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_drop_a__(__FILE__,__LINE__); \ }) \ ) /* Downgrade A to R. Inc(R), dec(W) then wait for W==0 */ #define pl_ator(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_RL_1 - PLOCK64_WL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY; \ register unsigned long __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ while (__builtin_expect(__pl_r & __msk_r, 0)) { \ __pl_r = pl_wait_unlock_long(__lk_r, __msk_r); \ } \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_RL_1 - PLOCK32_WL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY; \ register unsigned int __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ while (__builtin_expect(__pl_r & __msk_r, 0)) { \ __pl_r = pl_wait_unlock_int(__lk_r, __msk_r); \ } \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_ator__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_ator__(__FILE__,__LINE__); \ }) \ ) /* Try to upgrade from R to A, return non-zero on success, otherwise 0. * This lock will fail if S is held or appears while waiting (typically due to * a previous grab that was disguised as a W due to an overflow). In case of * failure to grab the lock, it MUST NOT be retried without first dropping R, * or it may never complete due to S waiting for R to leave before upgrading * to W. The lock succeeds once there's no more R (ie all of them have either * completed or were turned to A). */ #define pl_try_rtoa(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long __pl_r = pl_deref_long(lock) & PLOCK64_SL_ANY; \ pl_barrier(); \ if (!__builtin_expect(__pl_r, 0)) { \ __pl_r = pl_xadd((lock), PLOCK64_WL_1 - PLOCK64_RL_1); \ while (1) { \ if (__builtin_expect(__pl_r & PLOCK64_SL_ANY, 0)) { \ pl_sub((lock), PLOCK64_WL_1 - PLOCK64_RL_1); \ break; /* return !__pl_r */ \ } \ __pl_r &= PLOCK64_RL_ANY; \ if (!__builtin_expect(__pl_r, 0)) \ break; /* return !__pl_r */ \ __pl_r = pl_deref_long(lock); \ } \ } \ !__pl_r; /* return value */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int __pl_r = pl_deref_int(lock) & PLOCK32_SL_ANY; \ pl_barrier(); \ if (!__builtin_expect(__pl_r, 0)) { \ __pl_r = pl_xadd((lock), PLOCK32_WL_1 - PLOCK32_RL_1); \ while (1) { \ if (__builtin_expect(__pl_r & PLOCK32_SL_ANY, 0)) { \ pl_sub((lock), PLOCK32_WL_1 - PLOCK32_RL_1); \ break; /* return !__pl_r */ \ } \ __pl_r &= PLOCK32_RL_ANY; \ if (!__builtin_expect(__pl_r, 0)) \ break; /* return !__pl_r */ \ __pl_r = pl_deref_int(lock); \ } \ } \ !__pl_r; /* return value */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_rtoa__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_rtoa__(__FILE__,__LINE__); \ 0; \ }) \ ) /* * The following operations cover the multiple writers model : U->R->J->C->A */ /* Upgrade R to J. Inc(W) then wait for R==W or S != 0 */ #define pl_rtoj(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __pl_r = pl_xadd(__lk_r, PLOCK64_WL_1) + PLOCK64_WL_1; \ register unsigned char __m = 0; \ while (!(__pl_r & PLOCK64_SL_ANY) && \ (__pl_r / PLOCK64_WL_1 != (__pl_r & PLOCK64_RL_ANY) / PLOCK64_RL_1)) { \ unsigned char __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_long(__lk_r); \ } \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __pl_r = pl_xadd(__lk_r, PLOCK32_WL_1) + PLOCK32_WL_1; \ register unsigned char __m = 0; \ while (!(__pl_r & PLOCK32_SL_ANY) && \ (__pl_r / PLOCK32_WL_1 != (__pl_r & PLOCK32_RL_ANY) / PLOCK32_RL_1)) { \ unsigned char __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_int(__lk_r); \ } \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_rtoj__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_rtoj__(__FILE__,__LINE__); \ }) \ ) /* Upgrade J to C. Set S. Only one thread needs to do it though it's idempotent */ #define pl_jtoc(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __pl_r = pl_deref_long(__lk_r); \ if (!(__pl_r & PLOCK64_SL_ANY)) \ pl_or(__lk_r, PLOCK64_SL_1); \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __pl_r = pl_deref_int(__lk_r); \ if (!(__pl_r & PLOCK32_SL_ANY)) \ pl_or(__lk_r, PLOCK32_SL_1); \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_jtoc__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_jtoc__(__FILE__,__LINE__); \ }) \ ) /* Upgrade R to C. Inc(W) then wait for R==W or S != 0 */ #define pl_rtoc(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __pl_r = pl_xadd(__lk_r, PLOCK64_WL_1) + PLOCK64_WL_1; \ register unsigned char __m = 0; \ while (__builtin_expect(!(__pl_r & PLOCK64_SL_ANY), 0)) { \ unsigned char __loops; \ if (__pl_r / PLOCK64_WL_1 == (__pl_r & PLOCK64_RL_ANY) / PLOCK64_RL_1) { \ pl_or(__lk_r, PLOCK64_SL_1); \ break; \ } \ __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_long(__lk_r); \ } \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __pl_r = pl_xadd(__lk_r, PLOCK32_WL_1) + PLOCK32_WL_1; \ register unsigned char __m = 0; \ while (__builtin_expect(!(__pl_r & PLOCK32_SL_ANY), 0)) { \ unsigned char __loops; \ if (__pl_r / PLOCK32_WL_1 == (__pl_r & PLOCK32_RL_ANY) / PLOCK32_RL_1) { \ pl_or(__lk_r, PLOCK32_SL_1); \ break; \ } \ __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_int(__lk_r); \ } \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_rtoj__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_rtoj__(__FILE__,__LINE__); \ }) \ ) /* Drop the claim (C) lock : R--,W-- then clear S if !R */ #define pl_drop_c(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = - PLOCK64_RL_1 - PLOCK64_WL_1; \ register unsigned long __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ if (!(__pl_r & PLOCK64_RL_ANY)) \ pl_and(__lk_r, ~PLOCK64_SL_1); \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = - PLOCK32_RL_1 - PLOCK32_WL_1; \ register unsigned int __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ if (!(__pl_r & PLOCK32_RL_ANY)) \ pl_and(__lk_r, ~PLOCK32_SL_1); \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_drop_c__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_drop_c__(__FILE__,__LINE__); \ }) \ ) /* Upgrade C to A. R-- then wait for !S or clear S if !R */ #define pl_ctoa(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __pl_r = pl_xadd(__lk_r, -PLOCK64_RL_1) - PLOCK64_RL_1; \ while (__pl_r & PLOCK64_SL_ANY) { \ if (!(__pl_r & PLOCK64_RL_ANY)) { \ pl_and(__lk_r, ~PLOCK64_SL_1); \ break; \ } \ pl_cpu_relax(); \ pl_cpu_relax(); \ __pl_r = pl_deref_long(__lk_r); \ } \ pl_barrier(); \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __pl_r = pl_xadd(__lk_r, -PLOCK32_RL_1) - PLOCK32_RL_1; \ while (__pl_r & PLOCK32_SL_ANY) { \ if (!(__pl_r & PLOCK32_RL_ANY)) { \ pl_and(__lk_r, ~PLOCK32_SL_1); \ break; \ } \ pl_cpu_relax(); \ pl_cpu_relax(); \ __pl_r = pl_deref_int(__lk_r); \ } \ pl_barrier(); \ }) : ({ \ void __unsupported_argument_size_for_pl_ctoa__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_ctoa__(__FILE__,__LINE__); \ }) \ ) /* downgrade the atomic write access lock (A) to join (J) */ #define pl_atoj(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_add(lock, PLOCK64_RL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_add(lock, PLOCK32_RL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_atoj__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_atoj__(__FILE__,__LINE__); \ }) \ ) /* Returns non-zero if the thread calling it is the last writer, otherwise zero. It is * designed to be called before pl_drop_j(), pl_drop_c() or pl_drop_a() for operations * which need to be called only once. */ #define pl_last_writer(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ !(pl_deref_long(lock) & PLOCK64_WL_2PL); \ }) : (sizeof(*(lock)) == 4) ? ({ \ !(pl_deref_int(lock) & PLOCK32_WL_2PL); \ }) : ({ \ void __unsupported_argument_size_for_pl_last_j__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_last_j__(__FILE__,__LINE__); \ 0; \ }) \ ) /* attempt to get an exclusive write access via the J lock and wait for it. * Only one thread may succeed in this operation. It will not conflict with * other users and will first wait for all writers to leave, then for all * readers to leave before starting. This offers a solution to obtain an * exclusive access to a shared resource in the R/J/C/A model. A concurrent * take_a() will wait for this one to finish first. Using a CAS instead of XADD * should make the operation converge slightly faster. Returns non-zero on * success otherwise 0. */ #define pl_try_j(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_WL_1 | PLOCK64_RL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY; \ register unsigned long __pl_r; \ register unsigned char __m; \ pl_wait_unlock_long(__lk_r, __msk_r); \ __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ /* wait for all other readers to leave */ \ __m = 0; \ while (__builtin_expect(__pl_r & PLOCK64_RL_2PL, 0)) { \ unsigned char __loops; \ /* give up on other writers */ \ if (__builtin_expect(__pl_r & PLOCK64_WL_2PL, 0)) { \ pl_sub(__lk_r, __set_r); \ __pl_r = 0; /* failed to get the lock */ \ break; \ } \ __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_long(__lk_r); \ } \ pl_barrier(); \ __pl_r; /* return value, cannot be null on success */ \ }) : (sizeof(*(lock)) == 4) ? ({ \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_WL_1 | PLOCK32_RL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY; \ register unsigned int __pl_r; \ register unsigned char __m; \ pl_wait_unlock_int(__lk_r, __msk_r); \ __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ /* wait for all other readers to leave */ \ __m = 0; \ while (__builtin_expect(__pl_r & PLOCK32_RL_2PL, 0)) { \ unsigned char __loops; \ /* but rollback on other writers */ \ if (__builtin_expect(__pl_r & PLOCK32_WL_2PL, 0)) { \ pl_sub(__lk_r, __set_r); \ __pl_r = 0; /* failed to get the lock */ \ break; \ } \ __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_int(__lk_r); \ } \ pl_barrier(); \ __pl_r; /* return value, cannot be null on success */ \ }) : ({ \ void __unsupported_argument_size_for_pl_try_j__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_try_j__(__FILE__,__LINE__); \ 0; \ }) \ ) /* request an exclusive write access via the J lock and wait for it. Only one * thread may succeed in this operation. It will not conflict with other users * and will first wait for all writers to leave, then for all readers to leave * before starting. This offers a solution to obtain an exclusive access to a * shared resource in the R/J/C/A model. A concurrent take_a() will wait for * this one to finish first. Using a CAS instead of XADD should make the * operation converge slightly faster. */ #define pl_take_j(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ __label__ __retry; \ register unsigned long *__lk_r = (unsigned long *)(lock); \ register unsigned long __set_r = PLOCK64_WL_1 | PLOCK64_RL_1; \ register unsigned long __msk_r = PLOCK64_WL_ANY; \ register unsigned long __pl_r; \ register unsigned char __m; \ __retry: \ pl_wait_unlock_long(__lk_r, __msk_r); \ __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ /* wait for all other readers to leave */ \ __m = 0; \ while (__builtin_expect(__pl_r & PLOCK64_RL_2PL, 0)) { \ unsigned char __loops; \ /* but rollback on other writers */ \ if (__builtin_expect(__pl_r & PLOCK64_WL_2PL, 0)) { \ pl_sub(__lk_r, __set_r); \ goto __retry; \ } \ __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_long(__lk_r); \ } \ pl_barrier(); \ 0; \ }) : (sizeof(*(lock)) == 4) ? ({ \ __label__ __retry; \ register unsigned int *__lk_r = (unsigned int *)(lock); \ register unsigned int __set_r = PLOCK32_WL_1 | PLOCK32_RL_1; \ register unsigned int __msk_r = PLOCK32_WL_ANY; \ register unsigned int __pl_r; \ register unsigned char __m; \ __retry: \ pl_wait_unlock_int(__lk_r, __msk_r); \ __pl_r = pl_xadd(__lk_r, __set_r) + __set_r; \ /* wait for all other readers to leave */ \ __m = 0; \ while (__builtin_expect(__pl_r & PLOCK32_RL_2PL, 0)) { \ unsigned char __loops; \ /* but rollback on other writers */ \ if (__builtin_expect(__pl_r & PLOCK32_WL_2PL, 0)) { \ pl_sub(__lk_r, __set_r); \ goto __retry; \ } \ __loops = __m + 1; \ __m = (__m << 1) + 1; \ do { \ pl_cpu_relax(); \ pl_cpu_relax(); \ } while (--__loops); \ __pl_r = pl_deref_int(__lk_r); \ } \ pl_barrier(); \ 0; \ }) : ({ \ void __unsupported_argument_size_for_pl_take_j__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_take_j__(__FILE__,__LINE__); \ 0; \ }) \ ) /* drop the join (J) lock entirely */ #define pl_drop_j(lock) ( \ (sizeof(long) == 8 && sizeof(*(lock)) == 8) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK64_WL_1 | PLOCK64_RL_1); \ }) : (sizeof(*(lock)) == 4) ? ({ \ pl_barrier(); \ pl_sub(lock, PLOCK32_WL_1 | PLOCK32_RL_1); \ }) : ({ \ void __unsupported_argument_size_for_pl_drop_j__(char *,int); \ if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8)) \ __unsupported_argument_size_for_pl_drop_j__(__FILE__,__LINE__); \ }) \ ) /* * The part below is for Low Overhead R/W locks (LORW). These ones are not * upgradable and not necessarily fair but they try to be fast when uncontended * and to limit the cost and perturbation during contention. Writers always * have precedence over readers to preserve latency as much as possible. * * The principle is to offer a fast no-contention path and a limited total * number of writes for the contended path. Since R/W locks are expected to be * used in situations where there is a benefit in separating reads from writes, * it is expected that reads are common (typ >= 50%) and that there is often at * least one reader (otherwise a spinlock wouldn't be a problem). As such, a * reader will try to pass instantly, detect contention and immediately retract * and wait in the queue in case there is contention. A writer will first also * try to pass instantly, and if it fails due to pending readers, it will mark * that it's waiting so that readers stop entering. This will leave the writer * waiting as close as possible to the point of being granted access. New * writers will also notice this previous contention and will wait outside. * This means that a successful access for a reader or a writer requires a * single CAS, and a contended attempt will require one failed CAS and one * successful XADD for a reader, or an optional OR and a N+1 CAS for the * writer. * * A counter of shared users indicates the number of active readers, while a * (single-bit) counter of exclusive writers indicates whether the lock is * currently held for writes. This distinction also permits to use a single * function to release the lock if desired, since the exclusive bit indicates * the state of the caller of unlock(). The WRQ bit is cleared during the * unlock. * * Layout: (32/64 bit): * 31 2 1 0 * +-----------+--------------+-----+-----+ * | | SHR | WRQ | EXC | * +-----------+--------------+-----+-----+ * * In order to minimize operations, the WRQ bit is held during EXC so that the * write waiter that had to fight for EXC doesn't have to release WRQ during * its operations, and will just drop it along with EXC upon unlock. * * This means the following costs: * reader: * success: 1 CAS * failure: 1 CAS + 1 XADD * unlock: 1 SUB * writer: * success: 1 RD + 1 CAS * failure: 1 RD + 1 CAS + 0/1 OR + N CAS * unlock: 1 AND */ #define PLOCK_LORW_EXC_BIT ((sizeof(long) == 8) ? 0 : 0) #define PLOCK_LORW_EXC_SIZE ((sizeof(long) == 8) ? 1 : 1) #define PLOCK_LORW_EXC_BASE (1UL << PLOCK_LORW_EXC_BIT) #define PLOCK_LORW_EXC_MASK (((1UL << PLOCK_LORW_EXC_SIZE) - 1UL) << PLOCK_LORW_EXC_BIT) #define PLOCK_LORW_WRQ_BIT ((sizeof(long) == 8) ? 1 : 1) #define PLOCK_LORW_WRQ_SIZE ((sizeof(long) == 8) ? 1 : 1) #define PLOCK_LORW_WRQ_BASE (1UL << PLOCK_LORW_WRQ_BIT) #define PLOCK_LORW_WRQ_MASK (((1UL << PLOCK_LORW_WRQ_SIZE) - 1UL) << PLOCK_LORW_WRQ_BIT) #define PLOCK_LORW_SHR_BIT ((sizeof(long) == 8) ? 2 : 2) #define PLOCK_LORW_SHR_SIZE ((sizeof(long) == 8) ? 30 : 30) #define PLOCK_LORW_SHR_BASE (1UL << PLOCK_LORW_SHR_BIT) #define PLOCK_LORW_SHR_MASK (((1UL << PLOCK_LORW_SHR_SIZE) - 1UL) << PLOCK_LORW_SHR_BIT) __attribute__((unused,always_inline,no_instrument_function)) static inline void pl_lorw_rdlock(unsigned long *lock) { unsigned long lk = 0; /* First, assume we're alone and try to get the read lock (fast path). * It often works because read locks are often used on low-contention * structs. */ lk = pl_cmpxchg(lock, 0, PLOCK_LORW_SHR_BASE); if (!lk) return; /* so we were not alone, make sure there's no writer waiting for the * lock to be empty of visitors. */ if (lk & PLOCK_LORW_WRQ_MASK) lk = pl_wait_unlock_long(lock, PLOCK_LORW_WRQ_MASK); /* count us as visitor among others */ lk = pl_xadd(lock, PLOCK_LORW_SHR_BASE); /* wait for end of exclusive access if any */ if (lk & PLOCK_LORW_EXC_MASK) lk = pl_wait_unlock_long(lock, PLOCK_LORW_EXC_MASK); } __attribute__((unused,always_inline,no_instrument_function)) static inline void pl_lorw_wrlock(unsigned long *lock) { unsigned long lk = 0; unsigned long old = 0; /* first, make sure another writer is not already blocked waiting for * readers to leave. Note that tests have shown that it can be even * faster to avoid the first check and to unconditionally wait. */ lk = pl_deref_long(lock); if (__builtin_expect(lk & PLOCK_LORW_WRQ_MASK, 1)) lk = pl_wait_unlock_long(lock, PLOCK_LORW_WRQ_MASK); do { /* let's check for the two sources of contention at once */ if (__builtin_expect(lk & (PLOCK_LORW_SHR_MASK | PLOCK_LORW_EXC_MASK), 1)) { /* check if there are still readers coming. If so, close the door and * wait for them to leave. */ if (lk & PLOCK_LORW_SHR_MASK) { /* note below, an OR is significantly cheaper than BTS or XADD */ if (!(lk & PLOCK_LORW_WRQ_MASK)) pl_or(lock, PLOCK_LORW_WRQ_BASE); lk = pl_wait_unlock_long(lock, PLOCK_LORW_SHR_MASK); } /* And also wait for a previous writer to finish. */ if (lk & PLOCK_LORW_EXC_MASK) lk = pl_wait_unlock_long(lock, PLOCK_LORW_EXC_MASK); } /* A fresh new reader may appear right now if there were none * above and we didn't close the door. */ old = lk & ~PLOCK_LORW_SHR_MASK & ~PLOCK_LORW_EXC_MASK; lk = pl_cmpxchg(lock, old, old | PLOCK_LORW_EXC_BASE); } while (lk != old); /* done, not waiting anymore, the WRQ bit if any, will be dropped by the * unlock */ } __attribute__((unused,always_inline,no_instrument_function)) static inline void pl_lorw_rdunlock(unsigned long *lock) { pl_sub(lock, PLOCK_LORW_SHR_BASE); } __attribute__((unused,always_inline,no_instrument_function)) static inline void pl_lorw_wrunlock(unsigned long *lock) { pl_and(lock, ~(PLOCK_LORW_WRQ_MASK | PLOCK_LORW_EXC_MASK)); } __attribute__((unused,always_inline,no_instrument_function)) static inline void pl_lorw_unlock(unsigned long *lock) { if (pl_deref_long(lock) & PLOCK_LORW_EXC_MASK) pl_lorw_wrunlock(lock); else pl_lorw_rdunlock(lock); }qatengine-1.9.0/qae_mem_utils.h000066400000000000000000000173031500416242000164670ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qae_mem_utils.h * * This file provides linux kernel memory allocation for quick assist API * *****************************************************************************/ #ifndef __QAE_MEM_UTILS_H # define __QAE_MEM_UTILS_H # include "cpa.h" /* * define types which need to vary between 32 and 64 bit */ # ifdef __x86_64__ # define QAE_UINT Cpa64U # define QAE_INT Cpa64S # else # define QAE_UINT Cpa32U # define QAE_INT Cpa32S # endif # define QAE_BYTE_ALIGNMENT 0x0040/* 64 bytes */ extern FILE* qatDebugLogFile; #ifdef QAT_MEM_DEBUG # define MEM_DEBUG(fmt_str, ...) \ do { \ fprintf(qatDebugLogFile,"[MEM_DEBUG][%s:%d:%s()] "fmt_str, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while(0) #else # define MEM_DEBUG(...) #endif # define MEM_ERROR(fmt_str, ...) \ do { \ fprintf(qatDebugLogFile,"[MEM_ERROR][%s:%d:%s()] "fmt_str, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while(0) #if defined(QAT_MEM_WARN) || defined(QAT_MEM_DEBUG) # define MEM_WARN(fmt_str, ...) \ do { \ fprintf(qatDebugLogFile,"[MEM_WARN][%s:%d:%s()] "fmt_str, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while(0) #else # define MEM_WARN(...) #endif /***************************************************************************** * function: * qaeCryptoMemAlloc(size_t memsize, const char *file, int line); * * @description * allocates memsize bytes of memory * * @param[in] memsize, the amount of memory in bytes to be allocated * * @retval pointer to the allocated memory * *****************************************************************************/ void *qaeCryptoMemAlloc(size_t memsize, const char *file, int line); /***************************************************************************** * function: * qaeCryptoMemRealloc(void *ptr, size_t memsize, const char *file, int line) * * @description * re-allocates memsize bytes of memory * * @param[in] pointer to existing memory * @param[in] memsize, the amount of memory in bytes to be allocated * * @retval pointer to the allocated memory * *****************************************************************************/ void *qaeCryptoMemRealloc(void *ptr, size_t memsize, const char *file, int line); /***************************************************************************** * function: * qaeCryptoMemReallocClean(void *ptr, size_t memsize, size_t original_size, const char *file, int line) * * @description * re-allocates memsize bytes of memory * * @param[in] pointer to existing memory * @param[in] memsize, the amount of memory in bytes to be allocated * @param[in] original_size, original size * @param[in] file, the C source filename of the call site * @param[in] line, the line number within the C source file of the call site * * @retval pointer to the allocated memory * *****************************************************************************/ void *qaeCryptoMemReallocClean(void *ptr, size_t memsize, size_t original_size, const char *file, int line); /***************************************************************************** * function: * qaeCryptoMemFree(void *ptr) * * @description * frees memory allocated by the qaeCryptoMemAlloc function * * * @param[in] pointer to the memory to be freed * * @retval none * *****************************************************************************/ void qaeCryptoMemFree(void *ptr); /***************************************************************************** * function: * qaeCryptoMemFreeNonZero(void *ptr) * * @description * frees memory without clearing the contents of the buffer * allocated by the qaeCryptoMemAlloc function * * * @param[in] pointer to the memory to be freed * * @retval none * *****************************************************************************/ void qaeCryptoMemFreeNonZero(void *ptr); /***************************************************************************** * function: * qaeCryptoMemV2P(void *v) * * @description * find the physical address of a block of memory referred to by virtual * address v in the current process's address map * * * @param[in] ptr, virtual pointer to the memory * * @retval the physical address of the memory referred to by ptr * *****************************************************************************/ CpaPhysicalAddr qaeCryptoMemV2P(void *v); /****************************************************************************** * function: * setMyVirtualToPhysical(CpaVirtualToPhysical fp) * * @param CpaVirtualToPhysical [IN] - Function pointer to translation function * * description: * External API to allow users to specify their own virtual to physical * address translation function. * ******************************************************************************/ void setMyVirtualToPhysical(CpaVirtualToPhysical fp); void *copyAllocPinnedMemory(void *ptr, size_t size, const char *file, int line); void *copyAllocPinnedMemoryClean(void *ptr, size_t size, size_t original_size, const char *file, int line); int copyFreePinnedMemory(void *uptr, void *kptr, int size); void qaeCryptoAtFork(); #endif qatengine-1.9.0/qat.ec000066400000000000000000000000371500416242000145640ustar00rootroot00000000000000L QAT qat_err.h qat_err.c qatengine-1.9.0/qat.txt000066400000000000000000000436201500416242000150210ustar00rootroot00000000000000# Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html #Reason codes QAT_R_AAD_INVALID_PTR:100:aad invalid ptr QAT_R_AAD_LEN_INVALID:101:aad len invalid QAT_R_AAD_MALLOC_FAILURE:102:aad malloc failure QAT_R_ADD_M2_FAILURE:103:add m2 failure QAT_R_ADJUST_DELTA_M1_M2_FAILURE:104:adjust delta m1 m2 failure QAT_R_ALGO_TYPE_SUPPORTED:105:algo type supported QAT_R_ALGO_TYPE_UNSUPPORTED:106:algo type unsupported QAT_R_ALLOC_E_CHECK_FAILURE:107:alloc e check failure QAT_R_ALLOC_MULTIBUFF_RSA_METH_FAILURE:108:alloc multibuff rsa meth failure QAT_R_ALLOC_QAT_DSA_METH_FAILURE:109:alloc qat dsa meth failure QAT_R_ALLOC_QAT_RSA_METH_FAILURE:110:alloc qat rsa meth failure QAT_R_ALLOC_QAT_X25519_METH_FAILURE:111:alloc qat x25519 meth failure QAT_R_ALLOC_QAT_X448_METH_FAILURE:112:alloc qat x448 meth failure QAT_R_ALLOC_TAG_FAILURE:113:alloc tag failure QAT_R_BAD_INPUT_PARAMS:114:bad input params QAT_R_BAD_LENGTH:115:bad length QAT_R_BAD_TLS_CLIENT_VERSION:116:bad tls client version QAT_R_BN_LIB_FAILURE:117:bn lib failure QAT_R_BUFFER_TOO_SMALL:118:buffer too small QAT_R_BUF_CONV_FAIL:119:buf conv fail QAT_R_CAPABILITY_FAILURE:120:capability failure QAT_R_CBC_OPERATION_FAILED:121:cbc operation failed QAT_R_CHACHAPOLY_CTX_NULL:122:chachapoly ctx null QAT_R_CIPHER_DATA_NULL:123:cipher data null QAT_R_CIPHER_OPERATION_FAILED:124:cipher operation failed QAT_R_CLOSE_READFD_FAILURE:125:close readfd failure QAT_R_COMPUTE_FAILURE:126:compute failure QAT_R_COMPUTE_H_MULTIPLY_Q_FAILURE:127:compute h multiply q failure QAT_R_CP_BUF_MALLOC_FAILURE:128:cp buf malloc failure QAT_R_CQ_BUF_MALLOC_FAILURE:129:cq buf malloc failure QAT_R_CREATE_FREELIST_QUEUE_FAILURE:130:create freelist queue failure QAT_R_CTX_MALLOC_FAILURE:131:ctx malloc failure QAT_R_CTX_NULL:132:ctx null QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE:133:\ curve coordinate params convert to fb failure QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING:134:curve does not support signing QAT_R_C_MODULO_P_FAILURE:135:c modulo p failure QAT_R_C_MODULO_Q_FAILURE:136:c modulo q failure QAT_R_C_P_Q_CP_CQ_MALLOC_FAILURE:137:c p q cp cq malloc failure QAT_R_DATA_TOO_LARGE_FOR_KEY_SIZE:138:data too large for key size QAT_R_DEC_OP_DATA_MALLOC_FAILURE:139:dec op data malloc failure QAT_R_DERIVE_FAILURE:140:derive failure QAT_R_DGSTLEN_INVALID:141:dgstlen invalid QAT_R_DGST_BN_CONV_FAILURE:142:dgst bn conv failure QAT_R_DH_NULL:143:dh null QAT_R_DINIT_OPERATION_FAILED:144:dinit operation failed QAT_R_DLEN_INVALID:145:dlen invalid QAT_R_DSA_DGST_NULL:146:dsa dgst null QAT_R_DSA_DGST_SIG_NULL:147:dsa dgst sig null QAT_R_ECDH_GET_AFFINE_COORD_FAILED:148:ecdh get affine coord failed QAT_R_ECDH_GROUP_NULL:149:ecdh group null QAT_R_ECDH_PRIVATE_KEY_NULL:150:ecdh private key null QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL:151:ecdh priv key pub key null QAT_R_ECDH_SET_AFFINE_COORD_FAILED:152:ecdh set affine coord failed QAT_R_ECDH_UNKNOWN_FIELD_TYPE:153:ecdh unknown field type QAT_R_ECDSA_MALLOC_FAILURE:154:ecdsa malloc failure QAT_R_ECDSA_SIGN_FAILURE:155:ecdsa sign failure QAT_R_ECDSA_SIGN_NULL:156:ecdsa sign null QAT_R_ECDSA_SIGN_SETUP_FAILURE:157:ecdsa sign setup failure QAT_R_ECDSA_SIG_MALLOC_FAILURE:158:ecdsa sig malloc failure QAT_R_ECDSA_SIG_SET_R_S_FAILURE:159:ecdsa sig set r s failure QAT_R_ECDSA_VERIFY_FAILURE:160:ecdsa verify failure QAT_R_ECDSA_VERIFY_NULL:161:ecdsa verify null QAT_R_ECKEY_GROUP_PUBKEY_SIG_NULL:162:eckey group pubkey sig null QAT_R_EC_KEY_GROUP_PRIV_KEY_NULL:163:ec key group priv key null QAT_R_EC_LIB:164:ec lib QAT_R_EC_POINT_RETRIEVE_FAILURE:165:ec point retrieve failure QAT_R_EINIT_OPERATION_FAILED:166:einit operation failed QAT_R_ENC_OP_DATA_MALLOC_FAILURE:167:enc op data malloc failure QAT_R_ENGINE_CTRL_CMD_FAILURE:168:engine ctrl cmd failure QAT_R_ENGINE_INIT_FAILURE:169:engine init failure QAT_R_ENGINE_NULL:170:engine null QAT_R_EPOLL_CREATE_FAILURE:171:epoll create failure QAT_R_EPOLL_CTL_FAILURE:172:epoll ctl failure QAT_R_EVENTS_MALLOC_FAILURE:173:events malloc failure QAT_R_EVP_LIB:174:evp lib QAT_R_FAILED_TO_DECRYPT:175:failed to decrypt QAT_R_FAILED_TO_GET_PARAMETER:176:failed to get parameter QAT_R_FAILED_TO_SET_PARAMETER:177:failed to set parameter QAT_R_FALLBACK_INIT_FAILURE:178:fallback init failure QAT_R_FALLBACK_POINTER_NULL:179:fallback pointer null QAT_R_FIELD_SIZE_INVALID:180:field size invalid QAT_R_FREE_DH_METH_FAILURE:181:free dh meth failure QAT_R_FREE_MULTIBUFF_RSA_METH_FAILURE:182:free multibuff rsa meth failure QAT_R_FREE_QAT_DSA_METH_FAILURE:183:free qat dsa meth failure QAT_R_FREE_QAT_RSA_METH_FAILURE:184:free qat rsa meth failure QAT_R_GCM_TAG_VERIFY_FAILURE:185:gcm tag verify failure QAT_R_GET_COFACTOR_FAILURE:186:get cofactor failure QAT_R_GET_FILE_DESCRIPTOR_FAILURE:187:get file descriptor failure QAT_R_GET_GROUP_FAILURE:188:get group failure QAT_R_GET_INSTANCE_FAILURE:189:get instance failure QAT_R_GET_INSTANCE_INFO_FAILURE:190:get instance info failure QAT_R_GET_NUM_INSTANCE_FAILURE:191:get num instance failure QAT_R_GET_ORDER_FAILURE:192:get order failure QAT_R_GET_PQG_FAILURE:193:get pqg failure QAT_R_GET_PRIV_KEY_FAILURE:194:get priv key failure QAT_R_GROUP_NULL:195:group null QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL:196:group priv key pub key null QAT_R_GROUP_PUB_KEY_NULL:197:group pub key null QAT_R_H_CONVERT_TO_FB_FAILURE:198:h convert to fb failure QAT_R_ICP_SAL_USERSTART_FAIL:199:icp sal userstart fail QAT_R_ID_TOO_LARGE:200:id too large QAT_R_INITIALIZE_CTX_FAILURE:201:initialize ctx failure QAT_R_INIT_FAIL:202:init fail QAT_R_INIT_FAILURE:203:init failure QAT_R_INPUT_DATA_MALLOC_FAILURE:204:input data malloc failure QAT_R_INPUT_PARAM_INVALID:205:input param invalid QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE:206:instance handle malloc failure QAT_R_INSTANCE_UNAVAILABLE:207:instance unavailable QAT_R_INTERNAL_ERROR:208:internal error QAT_R_INVALID_AAD:209:invalid aad QAT_R_INVALID_ATTACHED_TAG:210:invalid attached tag QAT_R_INVALID_CTRL_TYPE:211:invalid ctrl type QAT_R_INVALID_CURVE:212:invalid curve QAT_R_INVALID_DATA:213:invalid data QAT_R_INVALID_DIGEST:214:invalid digest QAT_R_INVALID_HASH_DATA:215:invalid hash data QAT_R_INVALID_INPUT:216:invalid input QAT_R_INVALID_INPUT_LENGTH:217:invalid input length QAT_R_INVALID_INPUT_PARAMETER:218:invalid input parameter QAT_R_INVALID_IVLEN:219:invalid ivlen QAT_R_INVALID_IV_LENGTH:220:invalid iv length QAT_R_INVALID_KEY:221:invalid key QAT_R_INVALID_KEY_LENGTH:222:invalid key length QAT_R_INVALID_L:223:invalid l QAT_R_INVALID_LEN:224:invalid len QAT_R_INVALID_LENGTH:225:invalid length QAT_R_INVALID_PEER_KEY:226:invalid peer key QAT_R_INVALID_PRIVATE_KEY:227:invalid private key QAT_R_INVALID_PTR:228:invalid ptr QAT_R_INVALID_PTR_IV:229:invalid ptr iv QAT_R_INVALID_PUB_KEY:230:invalid pub key QAT_R_INVALID_QCTX_MEMORY:231:invalid qctx memory QAT_R_INVALID_TAG:232:invalid tag QAT_R_INVALID_TAG_LEN:233:invalid tag len QAT_R_INVALID_TYPE:234:invalid type QAT_R_IN_KINV_CONVERT_TO_FB_FAILURE:235:in kinv convert to fb failure QAT_R_IN_R_CONVERT_TO_FB_FAILURE:236:in r convert to fb failure QAT_R_IPSEC_MGR_NULL:237:ipsec mgr null QAT_R_IV_ALLOC_FAILURE:238:iv alloc failure QAT_R_IV_GEN_INVALID:239:iv gen invalid QAT_R_IV_INVALID:240:iv invalid QAT_R_IV_LEN_NOT_SUPPORTED:241:iv len not supported QAT_R_IV_MALLOC_FAILURE:242:iv malloc failure QAT_R_IV_NOTSET:243:iv notset QAT_R_IV_NULL_PTR_INVALID:244:iv null ptr invalid QAT_R_IV_NVALID:245:iv nvalid QAT_R_KEYGEN_FAILURE:246:keygen failure QAT_R_KEYS_NOT_SET:247:keys not set QAT_R_KEY_IV_NOT_SET:248:key iv not set QAT_R_KEY_MALLOC_FAILURE:249:key malloc failure QAT_R_KEY_NOTSET:250:key notset QAT_R_KEY_NULL:251:key null QAT_R_KEY_SIZE_TOO_SMALL:252:key size too small QAT_R_K_ALLOCATE_FAILURE:253:k allocate failure QAT_R_K_CONVERT_TO_FB_FAILURE:254:k convert to fb failure QAT_R_K_E_ORDER_MALLOC_FAILURE:255:k e order malloc failure QAT_R_K_ORDER_CONVERT_TO_FB_FAILURE:256:k order convert to fb failure QAT_R_K_RAND_GENERATE_FAILURE:257:k rand generate failure QAT_R_M1_DEDUCT_M2_FAILURE:258:m1 deduct m2 failure QAT_R_M1_M2_P_Q_QINV_TMP_MALLOC_FAILURE:259:m1 m2 p q qinv tmp malloc failure QAT_R_MALLOC_FAILURE:260:malloc failure QAT_R_MAX_RETRIES_EXCEEDED:261:max retries exceeded QAT_R_MB_FREE_EC_METHOD_FAILURE:262:mb free ec method failure QAT_R_MB_GET_EC_METHOD_MALLOC_FAILURE:263:mb get ec method malloc failure QAT_R_MODULO_P_FAILURE:264:modulo p failure QAT_R_MOD_GET_NEXT_INST_FAIL:265:mod get next inst fail QAT_R_MOD_LN_MOD_EXP_FAIL:266:mod ln mod exp fail QAT_R_MOD_SETUP_ASYNC_EVENT_FAIL:267:mod setup async event fail QAT_R_MSGLEN_NOTSET:268:msglen notset QAT_R_MULTIPLY_QINV_FAILURE:269:multiply qinv failure QAT_R_NID_NOT_SUPPORTED:270:nid not supported QAT_R_NO_PARAMETERS_SET:271:no parameters set QAT_R_N_E_CONVERT_TO_FB_FAILURE:272:n e convert to fb failure QAT_R_N_E_NULL:273:n e null QAT_R_OP1_BASE_PDATA_MALLOC_FAILURE:274:op1 base pdata malloc failure QAT_R_OP2_BASE_PDATA_MALLOC_FAILURE:275:op2 base pdata malloc failure QAT_R_OPDATA_A_PDATA_MALLOC_FAILURE:276:opdata a pdata malloc failure QAT_R_OPDATA_DATA_MALLOC_FAILURE:277:opdata data malloc failure QAT_R_OPDATA_D_MALLOC_FAILURE:278:opdata d malloc failure QAT_R_OPDATA_E_MALLOC_FAILURE:279:opdata e malloc failure QAT_R_OPDATA_K_MALLOC_FAILURE:280:opdata k malloc failure QAT_R_OPDATA_MALLOC_FAILURE:281:opdata malloc failure QAT_R_OPDATA_PDATA_MALLOC_FAILURE:282:opdata pdata malloc failure QAT_R_OPDATA_ZPDATA_MALLOC_FAILURE:283:opdata zpdata malloc failure QAT_R_OPDCRT_NULL:284:opdcrt null QAT_R_OPDONE_NULL:285:opdone null QAT_R_OPDPIPE_NULL:286:opdpipe null QAT_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:287:\ operation not supported for this keytype QAT_R_ORDER_MALLOC_FAILURE:288:order malloc failure QAT_R_OUT1_PDATA_MALLOC_FAILURE:289:out1 pdata malloc failure QAT_R_OUT2_PDATA_MALLOC_FAILURE:290:out2 pdata malloc failure QAT_R_OUTPUT_BUFFER_TOO_SMALL:291:output buffer too small QAT_R_OUTPUT_BUF_MALLOC_FAILURE:292:output buf malloc failure QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE:293:output buf pdata malloc failure QAT_R_OUTX_MALLOC_FAILURE:294:outx malloc failure QAT_R_OUTX_OUTY_LEN_NULL:295:outx outy len null QAT_R_OUTY_MALLOC_FAILURE:296:outy malloc failure QAT_R_PADDING_UNKNOWN:297:padding unknown QAT_R_PKCS_DECODING_ERROR:298:pkcs decoding error QAT_R_POLLING_THREAD_CREATE_FAILURE:299:polling thread create failure QAT_R_POLLING_THREAD_SEM_INIT_FAILURE:300:polling thread sem init failure QAT_R_POLLING_THREAD_SIGMASK_FAILURE:301:polling thread sigmask failure QAT_R_POLL_INSTANCE_FAILURE:302:poll instance failure QAT_R_POPDATA_A_PDATA_MALLOC_FAILURE:303:popdata a pdata malloc failure QAT_R_POPDATA_MALLOC_FAILURE:304:popdata malloc failure QAT_R_POPDATA_PCURVE_MALLOC_FAILURE:305:popdata pcurve malloc failure QAT_R_PPV_MALLOC_FAILURE:306:ppv malloc failure QAT_R_PPV_PDATA_MALLOC_FAILURE:307:ppv pdata malloc failure QAT_R_PRESULTR_MALLOC_FAILURE:308:presultr malloc failure QAT_R_PRESULTR_PDATA_MALLOC_FAILURE:309:presultr pdata malloc failure QAT_R_PRESULTS_MALLOC_FAILURE:310:presults malloc failure QAT_R_PRESULTS_PDATA_MALLOC_FAILURE:311:presults pdata malloc failure QAT_R_PRESULTX_MALLOC_FAILURE:312:presultx malloc failure QAT_R_PRESULTX_PDATA_MALLOC_FAILURE:313:presultx pdata malloc failure QAT_R_PRESULTY_LENGTH_CHECK_FAILURE:314:presulty length check failure QAT_R_PRESULTY_MALLOC_FAILURE:315:presulty malloc failure QAT_R_PRESULTY_PDATA_MALLOC_FAILURE:316:presulty pdata malloc failure QAT_R_PRIV_KEY_DUPLICATE_FAILURE:317:priv key duplicate failure QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE:318:\ priv key k e d convert to fb failure QAT_R_PRIV_KEY_MALLOC_FAILURE:319:priv key malloc failure QAT_R_PRIV_KEY_M_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE:320:\ priv key m xg yg a b p convert to fb failure QAT_R_PRIV_KEY_NULL:321:priv key null QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE:322:priv key rand generate failure QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE:323:\ priv key xg yg a b p convert to fb failure QAT_R_PRIV_KEY_XP_YP_A_B_P_CONVERT_TO_FB_FAILURE:324:\ priv key xp yp a b p convert to fb failure QAT_R_PTHREAD_CREATE_FAILURE:325:pthread create failure QAT_R_PTHREAD_GETAFFINITY_FAILURE:326:pthread getaffinity failure QAT_R_PTHREAD_JOIN_FAILURE:327:pthread join failure QAT_R_PTHREAD_SETAFFINITY_FAILURE:328:pthread setaffinity failure QAT_R_PUB_KEY_DUPLICATE_FAILURE:329:pub key duplicate failure QAT_R_PUB_KEY_MALLOC_FAILURE:330:pub key malloc failure QAT_R_PUB_KEY_NULL:331:pub key null QAT_R_P_A_B_XG_YG_MALLOC_FAILURE:332:p a b xg yg malloc failure QAT_R_P_A_B_XG_YG_M_K_R_ORDER_MALLOC_FAILURE:333:\ p a b xg yg m k r order malloc failure QAT_R_P_A_B_XG_YG_XP_YP_M_ORDER_FAILURE:334:p a b xg yg xp yp m order failure QAT_R_P_A_B_XP_YP_FAILURE:335:p a b xp yp failure QAT_R_P_A_B_XP_YP_MALLOC_FAILURE:336:p a b xp yp malloc failure QAT_R_P_G_PRIV_KEY_CONVERT_TO_FB_FAILURE:337:p g priv key convert to fb failure QAT_R_P_PUB_PRIV_KEY_CONVERT_TO_FB_FAILURE:338:\ p pub priv key convert to fb failure QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE:339:p q dmp dmq convert to fb failure QAT_R_P_Q_DMP_DMQ_IQMP_NULL:340:p q dmp dmq iqmp null QAT_R_P_Q_G_NULL:341:p q g null QAT_R_P_Q_G_X_K_CONVERT_TO_FB_FAILURE:342:p q g x k convert to fb failure QAT_R_P_Q_G_Y_Z_R_S_CONVERT_TO_FB_FAILURE:343:\ p q g y z r s convert to fb failure QAT_R_QAT_ALLOC_DH_METH_FAILURE:344:qat alloc dh meth failure QAT_R_QAT_CREATE_ENGINE_FAILURE:345:qat create engine failure QAT_R_QAT_ECDSA_DO_SIGN_FAIL:346:qat ecdsa do sign fail QAT_R_QAT_FREE_EC_METHOD_FAILURE:347:qat free ec method failure QAT_R_QAT_GET_EC_METHOD_MALLOC_FAILURE:348:qat get ec method malloc failure QAT_R_QAT_SET_DH_METH_FAILURE:349:qat set dh meth failure QAT_R_QCTX_CTX_NULL:350:qctx ctx null QAT_R_QCTX_NULL:351:qctx null QAT_R_RAND_BYTES_FAILURE:352:rand bytes failure QAT_R_RAND_FAILURE:353:rand failure QAT_R_RAND_GENERATE_FAILURE:354:rand generate failure QAT_R_RESULT_PDATA_ALLOC_FAIL:355:result pdata alloc fail QAT_R_RETRIEVE_EC_POINT_FAILURE:356:retrieve ec point failure QAT_R_RETRIEVE_ORDER_FAILURE:357:retrieve order failure QAT_R_RSA_FROM_TO_NULL:358:rsa from to null QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE:359:\ rsa output buf pdata malloc failure QAT_R_R_Q_COMPARE_FAILURE:360:r q compare failure QAT_R_SECRET_KEY_MALLOC_FAILURE:361:secret key malloc failure QAT_R_SECRET_KEY_PDATA_MALLOC_FAILURE:362:secret key pdata malloc failure QAT_R_SEM_POST_FAILURE:363:sem post failure QAT_R_SETUP_ASYNC_EVENT_FAILURE:364:setup async event failure QAT_R_SET_ADDRESS_TRANSLATION_FAILURE:365:set address translation failure QAT_R_SET_FILE_DESCRIPTOR_NONBLOCKING_FAILURE:366:\ set file descriptor nonblocking failure QAT_R_SET_INSTANCE_FAILURE:367:set instance failure QAT_R_SET_MULTIBUFF_RSA_METH_FAILURE:368:set multibuff rsa meth failure QAT_R_SET_NOTIFICATION_CALLBACK_FAILURE:369:set notification callback failure QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE:370:\ set polling thread affinity failure QAT_R_SET_PRIV_KEY_FAILURE:371:set priv key failure QAT_R_SET_QAT_DSA_METH_FAILURE:372:set qat dsa meth failure QAT_R_SET_QAT_RSA_METH_FAILURE:373:set qat rsa meth failure QAT_R_SET_TAG_INVALID_OP:374:set tag invalid op QAT_R_SHA3_CTX_NULL:375:sha3 ctx null QAT_R_SIG_GET_R_S_FAILURE:376:sig get r s failure QAT_R_SIG_MALLOC_FAILURE:377:sig malloc failure QAT_R_SM2_BAD_SIGNATURE:378:sm2 bad signature QAT_R_SM2_ID_TOO_LARGE:379:sm2 id too large QAT_R_SM2_INVALID_DIGEST:380:sm2 invalid digest QAT_R_SM2_SIGN_NULL:381:sm2 sign null QAT_R_SM2_SIG_GEN_MALLOC_FAILURE:382:sm2 sig gen malloc failure QAT_R_SM2_SIG_MALLOC_FAILURE:383:sm2 sig malloc failure QAT_R_SM2_SIG_SET_R_S_FAILURE:384:sm2 sig set r s failure QAT_R_SM2_VERIFY_NULL:385:sm2 verify null QAT_R_SM3_CTX_NULL:386:sm3 ctx null QAT_R_SM3_FINAL_FAILURE:387:sm3 final failure QAT_R_SM3_INIT_FAILURE:388:sm3 init failure QAT_R_SM3_UPDATE_FAILURE:389:sm3 update failure QAT_R_SM4_CCM_DECRYPT_FAILURE:390:sm4 ccm decrypt failure QAT_R_SM4_GCM_DECRYPT_FAILURE:391:sm4 gcm decrypt failure QAT_R_SM4_GCM_ENCRYPT_FAILURE:392:sm4 gcm encrypt failure QAT_R_SM4_GET_INSTANCE_FAILED:393:sm4 get instance failed QAT_R_SM4_GET_SESSIONCTX_SIZE_FAILED:394:sm4 get sessionctx size failed QAT_R_SM4_MALLOC_FAILED:395:sm4 malloc failed QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE:396:sm4 no qat instance available QAT_R_SM4_NULL_CKEY:397:sm4 null ckey QAT_R_SM4_NULL_CTX:398:sm4 null ctx QAT_R_SM4_NULL_CTX_OR_KEY:399:sm4 null ctx or key QAT_R_SM4_NULL_POINTER:400:sm4 null pointer QAT_R_SM4_NULL_QCTX:401:sm4 null qctx QAT_R_SM4_QAT_CONTEXT_NOT_INITIALISED:402:sm4 qat context not initialised QAT_R_SM4_QAT_INITSESSION_FAILED:403:sm4 qat initsession failed QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED:404:sm4 qat submit request failed QAT_R_SM4_REMOVE_SESSION_FAILED:405:sm4 remove session failed QAT_R_SM4_SETUP_META_DATA_FAILED:406:sm4 setup meta data failed QAT_R_SM4_SET_METHODS_FAILED:407:sm4 set methods failed QAT_R_SSD_MALLOC_FAILURE:408:ssd malloc failure QAT_R_SSD_NULL:409:ssd null QAT_R_START_INSTANCE_FAILURE:410:start instance failure QAT_R_STOP_INSTANCE_FAILURE:411:stop instance failure QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL:412:sw get compute key pfunc null QAT_R_SW_GET_KEYGEN_PFUNC_NULL:413:sw get keygen pfunc null QAT_R_SW_GET_SIGN_PFUNC_NULL:414:sw get sign pfunc null QAT_R_SW_GET_SIGN_SETUP_PFUNC_NULL:415:sw get sign setup pfunc null QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL:416:sw get sign sig pfunc null QAT_R_SW_GET_VERIFY_PFUNC_NULL:417:sw get verify pfunc null QAT_R_SW_GET_VERIFY_SIG_PFUNC_NULL:418:sw get verify sig pfunc null QAT_R_SW_METHOD_NULL:419:sw method null QAT_R_S_NULL:420:s null QAT_R_S_Q_COMPARE_FAILURE:421:s q compare failure QAT_R_TAG_NOTSET:422:tag notset QAT_R_TAG_NOT_NEEDED:423:tag not needed QAT_R_UNKNOWN_PADDING:424:unknown padding QAT_R_UNKNOWN_PADDING_TYPE:425:unknown padding type QAT_R_WAKE_PAUSE_JOB_FAILURE:426:wake pause job failure QAT_R_X_Y_E_MALLOC_FAILURE:427:x y e malloc failure QAT_R_X_Y_TX_TY_BN_MALLOC_FAILURE:428:x y tx ty bn malloc failure QAT_R_X_Y_Z_MALLOC_FAILURE:429:x y z malloc failure QAT_R_ZALLOC_FAILURE:430:zalloc failure QAT_R_Z_ALLOCATE_FAILURE:431:z allocate failure qatengine-1.9.0/qat_bssl.c000066400000000000000000001004061500416242000154430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_bssl.c * * This file provides and interface for undefined OpenSSL APIs in BoringSSL * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif #ifdef QAT_BORINGSSL # include "qat_bssl.h" # include "e_qat.h" # include "qat_fork.h" # include "qat_utils.h" # ifdef QAT_HW # include "qat_hw_callback.h" # endif /* QAT_HW */ # ifdef QAT_SW # include "qat_events.h" # include "qat_sw_rsa.h" # include "qat_evp.h" #endif /* QAT_SW */ # include "qat_events.h" # include # include # include # include # include # include ENGINE_QAT_PTR_DEFINE typedef pthread_key_t ASYNC_JOB_THREAD_KEY; # define BSSL_RUN_ONCE bssl_once # define BSSL_THREAD_LOCAL_KEY(name) \ bssl_thread_local_##name##_key # define BSSL_THREAD_LOCAL_INIT_ONCE(name) \ bssl_thread_local_##name##_init_once # define BSSL_THREAD_LOCAL_KEY_CREATED(name) \ bssL_thread_local_##name##_key_created # define BSSL_THREAD_LOCAL_INIT_FUNC(name) \ bssl_qat_##name##_thread_local_init # define BSSL_THREAD_LOCAL_DESTROY_FUNC(name) \ bssl_qat_##name##_thread_local_destructor # define BSSL_DEFINE_THREAD_LOCAL_INIT_OF(name, destructor) \ static pthread_key_t BSSL_THREAD_LOCAL_KEY(name); \ static pthread_once_t BSSL_THREAD_LOCAL_INIT_ONCE(name) =PTHREAD_ONCE_INIT;\ static int BSSL_THREAD_LOCAL_KEY_CREATED(name) = 0; \ static void BSSL_THREAD_LOCAL_DESTROY_FUNC(name) (void *tlv) { \ if (tlv) { \ OPENSSL_free(tlv); \ } \ } \ static void BSSL_THREAD_LOCAL_INIT_FUNC(name) (void) { \ BSSL_THREAD_LOCAL_KEY_CREATED(name) = \ pthread_key_create(&BSSL_THREAD_LOCAL_KEY(name), \ destructor == NULL?NULL:BSSL_THREAD_LOCAL_DESTROY_FUNC(name)) == 0;\ } # define BSSL_QAT_METHOD_RSA (unsigned int)0x0001 # define BSSL_QAT_METHOD_ECDSA (unsigned int)0x0020 unsigned int default_algorithm_conf_flags = 0; typedef struct bssl_qat_cmd_lookup_st{ const char* cmd_name; const int cmd_flag; } BSSL_QAT_CTL_CMD;; static const BSSL_QAT_CTL_CMD bssl_qat_cmds_table[] ={ {"ENABLE_INLINE_POLLING", QAT_CMD_ENABLE_INLINE_POLLING}, {"SET_INTERNAL_POLL_INTERVAL", QAT_CMD_SET_INTERNAL_POLL_INTERVAL}, {"ENABLE_SW_FALLBACK", QAT_CMD_ENABLE_SW_FALLBACK}, {BSSL_QAT_INIT_DEBUG_LOG, ENGINE_CMD_INVALD}, {NULL, ENGINE_CMD_INVALD} }; /* To be compatible with the jobs' behaviors or interfaces designed in OpenSSL, * we used the thread local storage(TLS) to save the async_job on the * application side, such as the bssl qat module that we added to Nginx-QUIC, * and then to load the async_job in QATEngine by calling ASYNC_get_current_job * or other similar actions. */ BSSL_DEFINE_THREAD_LOCAL_INIT_OF(async_job, NULL); int bssl_qat_send_ctrl_cmd(ENGINE *e, const char *cmd_name, long i, void *p, void (*f)(void), int cmd_optional) { const BSSL_QAT_CTL_CMD *tbl = bssl_qat_cmds_table; while (tbl && tbl->cmd_name) { if (strcmp(cmd_name, BSSL_QAT_INIT_DEBUG_LOG) == 0) { /* For previous scenario, log initialized when calling * qat_engine_init() * Currently, init log may be essential before calling * ENGINE_load_qat() */ QAT_DEBUG_LOG_INIT(); return 1;/* Success */ } if (strcmp(cmd_name, tbl->cmd_name) == 0) { return qat_engine_ctrl(e, tbl->cmd_flag, i, p, f); } tbl++; } return 0;/* Fail */ } /* Referred to the similar interfaces in qat_hw_init.c */ static void *bssl_qat_async_check_create_local_variables(void *new, ASYNC_JOB_THREAD_KEY key) { void *tlv = (void *)qat_getspecific_thread(key); if (tlv != NULL) { return tlv; } tlv = new; if (tlv != NULL) { qat_setspecific_thread(key, (void *)tlv); } return tlv; } int bssl_qat_async_local_variable_destructor(void *tlv) { if (tlv) { OPENSSL_free(tlv); } qat_setspecific_thread(BSSL_THREAD_LOCAL_KEY(async_job), NULL); return 1; /* Success */ } int bssl_qat_async_save_current_job(ASYNC_JOB *job) { BSSL_RUN_ONCE(&BSSL_THREAD_LOCAL_INIT_ONCE(async_job), BSSL_THREAD_LOCAL_INIT_FUNC(async_job)); /* Set local_variable_destructor in ASYNC_JOB */ job->tlv_destructor = bssl_qat_async_local_variable_destructor; if (bssl_qat_async_check_create_local_variables(job, BSSL_THREAD_LOCAL_KEY(async_job))) { return 0; } return 1; } ASYNC_JOB *bssl_qat_async_load_current_job(void) { BSSL_RUN_ONCE(&BSSL_THREAD_LOCAL_INIT_ONCE(async_job), BSSL_THREAD_LOCAL_INIT_FUNC(async_job)); return (ASYNC_JOB *)bssl_qat_async_check_create_local_variables(NULL, BSSL_THREAD_LOCAL_KEY(async_job)); } #ifdef QAT_HW /* Duplicate op_done_t structure and set op_buf_free */ static void *bssl_qat_copy_op_done(const void *op_done, unsigned int size, void (*buffers_free)(void *in_buf, void *out_buf, int qat_svm)) { op_done_t *op_done_dup = OPENSSL_memdup(op_done, size); volatile ASYNC_JOB *job = op_done_dup->job; job->op_buf_free = buffers_free; return op_done_dup; } /* Free memory for op_done_t structure */ static void bssl_qat_free_op_done(void *op_done) { /* Clean op_done before free memory */ qat_cleanup_op_done((op_done_t *)op_done); if (op_done) { OPENSSL_free(op_done); } } #endif /* QAT_HW */ /* All bssl_async_wait_ctx*() copied from openssl/crypto/async/async_wait.c */ static ASYNC_WAIT_CTX *bssl_async_wait_ctx_new(void) { return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX)); } static void bssl_async_wait_ctx_free(ASYNC_WAIT_CTX *ctx) { struct fd_lookup_st *curr; struct fd_lookup_st *next; if (ctx == NULL) return; curr = ctx->fds; while (curr != NULL) { /* Only try and cleanup if it hasn't been marked deleted */ if (curr->cleanup != NULL) curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data); /* Always free the fd_lookup_st */ next = curr->next; OPENSSL_free(curr); curr = next; } if (ctx->data) { OPENSSL_free(ctx->data); } OPENSSL_free(ctx); } int bssl_async_wait_ctx_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD fd, void *custom_data, void (*cleanup)(ASYNC_WAIT_CTX *, const void *, OSSL_ASYNC_FD, void *)) { struct fd_lookup_st *fdlookup; if ((fdlookup = OPENSSL_zalloc(sizeof(*fdlookup))) == NULL) { return 0; } fdlookup->key = key; fdlookup->fd = fd; fdlookup->custom_data = custom_data; fdlookup->cleanup = cleanup; fdlookup->add = 1; fdlookup->next = ctx->fds; ctx->fds = fdlookup; ctx->numadd++; return 1; } int bssl_async_wait_ctx_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD *fd, void **custom_data) { struct fd_lookup_st *curr; curr = ctx->fds; while (curr != NULL) { if (curr->del) { /* This one has been marked deleted so do nothing */ curr = curr->next; continue; } if (curr->key == key) { *fd = curr->fd; *custom_data = curr->custom_data; return 1; } curr = curr->next; } return 0; } int bssl_async_wait_ctx_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, size_t *numfds) { struct fd_lookup_st *curr; curr = ctx->fds; *numfds = 0; while (curr != NULL) { if (curr->del) { /* This one has been marked deleted so do nothing */ curr = curr->next; continue; } if (fd != NULL) { *fd = curr->fd; fd++; } (*numfds)++; curr = curr->next; } return 1; } int bssl_async_wait_ctx_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds) { struct fd_lookup_st *curr; *numaddfds = ctx->numadd; *numdelfds = ctx->numdel; if (addfd == NULL && delfd == NULL) return 1; curr = ctx->fds; while (curr != NULL) { /* We ignore fds that have been marked as both added and deleted */ if (curr->del && !curr->add && (delfd != NULL)) { *delfd = curr->fd; delfd++; } if (curr->add && !curr->del && (addfd != NULL)) { *addfd = curr->fd; addfd++; } curr = curr->next; } return 1; } int bssl_qat_async_ctx_get_changed_fds(async_ctx *ctx, OSSL_ASYNC_FD *addfd, size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds) { if (ctx && ctx->currjob && ctx->currjob->waitctx) { return bssl_async_wait_ctx_get_changed_fds(ctx->currjob->waitctx, addfd, numaddfds, delfd, numdelfds); } return 0;/* Fail */ } int bssl_async_wait_ctx_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key) { struct fd_lookup_st *curr, *prev; curr = ctx->fds; prev = NULL; while (curr != NULL) { if (curr->del == 1) { /* This one has been marked deleted already so do nothing */ prev = curr; curr = curr->next; continue; } if (curr->key == key) { /* If fd has just been added, remove it from the list */ if (curr->add == 1) { if (ctx->fds == curr) { ctx->fds = curr->next; } else { prev->next = curr->next; } /* It is responsibility of the caller to cleanup before calling * ASYNC_WAIT_CTX_clear_fd */ OPENSSL_free(curr); ctx->numadd--; return 1; } /* * Mark it as deleted. We don't call cleanup if explicitly asked * to clear an fd. We assume the caller is going to do that (if * appropriate). */ curr->del = 1; ctx->numdel++; return 1; } prev = curr; curr = curr->next; } return 0; } void bssl_async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx) { struct fd_lookup_st *curr, *prev = NULL; ctx->numadd = 0; ctx->numdel = 0; curr = ctx->fds; while (curr != NULL) { if (curr->del) { if (prev == NULL) ctx->fds = curr->next; else prev->next = curr->next; OPENSSL_free(curr); if (prev == NULL) curr = ctx->fds; else curr = prev->next; continue; } if (curr->add) { curr->add = 0; } prev = curr; curr = curr->next; } } /* Called in ssl private sign function of SSL_PRIVATE_KEY_METHOD */ async_ctx *bssl_qat_async_start_job(void) { async_ctx *ctx = NULL; ASYNC_JOB *job = NULL; ASYNC_WAIT_CTX *wctx = NULL; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL || (job = OPENSSL_zalloc(sizeof(*job))) == NULL || (wctx = bssl_async_wait_ctx_new()) == NULL) { goto err; } /* Config waitctx */ wctx->init = 1; /* Set init to non-zero */ /* Config job */ job->waitctx = wctx; job->status = ASYNC_JOB_RUNNING; #ifdef QAT_HW job->copy_op_done = bssl_qat_copy_op_done; job->free_op_done = bssl_qat_free_op_done; #endif /* QAT_HW */ #ifdef QAT_SW job->copy_op_done = NULL; job->free_op_done = NULL; #endif /* QAT_SW */ /* Config async_ctx */ ctx->currjob = job; ctx->currjob_status = &ctx->currjob->status; bssl_qat_async_save_current_job(ctx->currjob); return ctx; err: if (ctx) { OPENSSL_free(ctx); } if (job) { OPENSSL_free(job); } return NULL; } void bssl_qat_async_finish_job(const async_ctx *ctx) { if (ctx) { if (ctx->currjob) { bssl_async_wait_ctx_free(ctx->currjob->waitctx); OPENSSL_free(ctx->currjob); } OPENSSL_free((async_ctx *)ctx); } } static void bssl_qat_async_reset_fds(const async_ctx *ctx) { ASYNC_WAIT_CTX *wctx = NULL; if (ctx && ctx->currjob) { wctx = ctx->currjob->waitctx; if (wctx->fds_reset == 0) { bssl_async_wait_ctx_reset_counts(wctx); bssl_async_wait_ctx_clear_fd(wctx, wctx->fds->key); wctx->fds_reset = 1; } } } #ifdef QAT_SW static void mb_async_callback(mb_async_ctx *async_ctx, unsigned char *out_buffer, unsigned long *size, unsigned long max_size) { if (async_ctx && async_ctx->callback_func) { async_ctx->callback_func(async_ctx->ctx, out_buffer, size, max_size); } } #endif /* QAT_SW */ int bssl_qat_async_ctx_copy_result(const async_ctx *ctx, unsigned char *buffer, unsigned long *size, unsigned long max_size) { unsigned long bytes_len = 0; #ifdef QAT_HW CpaFlatBuffer *from; thread_local_variables_t *tlv = NULL; /* Decrease num_requests_in_flight by 1 to * avoid high cpu load from polling thread */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); return 0; } QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); #endif /* QAT_HW */ /* Change fds state from add to del */ bssl_qat_async_reset_fds(ctx); if (ctx && ctx->currjob && ctx->currjob->waitctx) { /* complete to operation with async, need to copy data to buffer. */ if (ctx->currjob->waitctx->data && ctx->currjob->status == ASYNC_JOB_COMPLETE) { #ifdef QAT_HW from = (CpaFlatBuffer *)ctx->currjob->waitctx->data; bytes_len = from->dataLenInBytes; bssl_memcpy(buffer, from->pData, bytes_len); /* Free output buffers allocated from build_decrypt_op_buf */ ctx->currjob->op_buf_free(NULL, from, ctx->currjob->qat_svm); #endif /* QAT_HW */ #ifdef QAT_SW mb_async_callback((mb_async_ctx *)ctx->currjob->waitctx->data, buffer, &bytes_len, max_size); #endif /* QAT_SW */ ctx->currjob->waitctx->data = NULL; ctx->currjob->status = ASYNC_JOB_STOPPED; } else if (ctx->currjob->status == ASYNC_JOB_OPER_COMPLETE) { if (ctx->currjob->waitctx->data) { bytes_len = (unsigned long)ctx->currjob->waitctx->data; } ctx->currjob->waitctx->data = NULL; ctx->currjob->status = ASYNC_JOB_STOPPED; } } if (bytes_len == 0 || bytes_len > max_size) { return 1; /* Data not ready, return fail */ } *size = bytes_len; return 0; /* Copied valid data, return success */ } int bssl_qat_before_wake_job(volatile ASYNC_JOB *job, int status, void *in_buf, void *out_buf, void *op_done) { ASYNC_WAIT_CTX *waitctx = ASYNC_get_wait_ctx(job); /* Free op_done allocated in qat_rsa_decrypt */ job->free_op_done(op_done); /* Free input buffers allocated from build_decrypt_op_buf or * build_encrypt_op_buf, pointing to dec_op_data or enc_op_data */ job->op_buf_free(in_buf, NULL, job->qat_svm); if (waitctx && waitctx->init && out_buf) { waitctx->data = out_buf; waitctx->status = status; /* Set waitctx->status to status */ job->status = ASYNC_JOB_COMPLETE; return 0; /* Success */ } job->status = ASYNC_JOB_STOPPED; /* Free output buffers allocated from build_decrypt_op_buf or * build_encrypt_op_buf, pointing to output_buffer */ job->op_buf_free(NULL, out_buf, job->qat_svm); return 1; /* Fail */ } void bssl_mb_async_job_finish_wait(volatile ASYNC_JOB *job, int job_status, int waitctx_status) { ASYNC_WAIT_CTX *waitctx = ASYNC_get_wait_ctx(job); if (waitctx && waitctx->init) { waitctx->status = waitctx_status; /* Set waitctx->status to status */ } job->status = job_status; } /* Refers to openssl/crypto/rsa/rsa_local.h */ RSA_METHOD *bssl_rsa_meth_new(const char *name, int flags) { RSA_METHOD *meth = OPENSSL_zalloc(sizeof(*meth)); if (meth) { meth->flags = flags; } return meth; } void bssl_rsa_meth_free(RSA_METHOD *meth) { if (meth) { OPENSSL_free(meth); } } int bssl_rsa_set_priv_meth(RSA_METHOD *meth, int (*sign_raw)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding), int (*decrypt)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding)) { if (!meth || !sign_raw || !decrypt) { return 0; } meth->common.is_static = 1; meth->sign_raw = sign_raw; meth->decrypt = decrypt; return 1; } /* Copy from OpenSSL or BoringSSL because of these functions not exported * using OPENSSL_EXPORT or not defined in BoringSSL */ #define RSA_PKCS1_PADDING_SIZE 11 static int rand_nonzero(uint8_t *out, size_t len) { if (!RAND_bytes(out, len)) { return 0; } for (size_t i = 0; i < len; i++) { while (out[i] == 0) { if (!RAND_bytes(out + i, 1)) { return 0; } } } return 1; } /* OpenSSL declaration *int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, * int fl); * BoringSSL declaration *int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, * size_t from_len); * Ported from boringssl/crypto/fipsmodule/rsa/padding.c */ int bssl_rsa_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { if (from_len > to_len) { return 0; } if (from_len < to_len) { return 0; } memcpy(to, from, from_len); return 1; } /* Ported from openssl/crypto/rsa/rsa_none.c */ int bssl_rsa_padding_check_none(unsigned char *to, int tlen, const unsigned char *from, int flen, int num) { if (flen > tlen) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); return -1; } memset(to, 0, tlen - flen); memcpy(to + tlen - flen, from, flen); return tlen; } /* OpenSSL declaration *int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, * const unsigned char *f, int fl); * BoringSSL declaration *int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, * const uint8_t *from, size_t from_len); * Ported from boringssl/crypto/fipsmodule/rsa/padding.c */ int bssl_rsa_padding_add_pkcs1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { /* See RFC 8017, section 9.2. */ if (to_len < RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return 0; } to[0] = 0; to[1] = 1; memset(to + 2, 0xff, to_len - 3 - from_len); to[to_len - from_len - 1] = 0; memcpy(to + to_len - from_len, from, from_len); return 1; } /* OpenSSL declaration *int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, * const unsigned char *f, int fl, * int rsa_len); * BoringSSL declaration *int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, * size_t max_out, const uint8_t *from, * size_t from_len); * Ported from openssl openssl/crypto/rsa/rsa_pk1.c but replace RSAerr by * OPENSSL_PUT_ERROR */ int bssl_rsa_padding_check_pkcs1_type_1(unsigned char *to, int tlen, const unsigned char *from, int flen, int num) { int i, j; const unsigned char *p; p = from; /* * The format is * 00 || 01 || PS || 00 || D * PS - padding string, at least 8 bytes of FF * D - data. */ if (num < RSA_PKCS1_PADDING_SIZE) return -1; /* Accept inputs with and without the leading 0-byte. */ if (num == flen) { if ((*p++) != 0x00) { return -1; } flen--; } if ((num != (flen + 1)) || (*(p++) != 0x01)) { OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01); return -1; } /* scan over padding data */ j = flen - 1; /* one for type. */ for (i = 0; i < j; i++) { if (*p != 0xff) { /* should decrypt to 0xff */ if (*p == 0) { p++; break; } else { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); return -1; } } p++; } if (i == j) { OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING); return -1; } if (i < 8) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT); return -1; } i++; /* Skip over the '\0' */ j -= i; if (j > tlen) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); return -1; } memcpy(to, p, (unsigned int)j); return j; } /* OpenSSL declaration *int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, * const unsigned char *f, int fl); * BoringSSL declaration *int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, * const uint8_t *from, size_t from_len); * Ported from boringssl/crypto/fipsmodule/rsa/padding.c */ int bssl_rsa_padding_add_pkcs1_type_2(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len) { // See RFC 8017, section 7.2.1. if (to_len < RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } to[0] = 0; to[1] = 2; size_t padding_len = to_len - 3 - from_len; if (!rand_nonzero(to + 2, padding_len)) { return 0; } to[2 + padding_len] = 0; memcpy(to + to_len - from_len, from, from_len); return 1; } /* Although OpenSSL or BoringSSL implemented parts of these functions , * we still decide to not port them because it's pretty complex to port * Do nothing currently */ int bssl_rsa_padding_check_pkcs1_type_2(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len) { return 0; } int bssl_rsa_padding_check_pkcs1_OAEP(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len, const unsigned char *p, int pl) { return 0; } int bssl_rsa_padding_add_sslv23(unsigned char *to, int tlen, const unsigned char *f, int fl) { return 1; } int bssl_rsa_padding_check_sslv23(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len) { return 0; } int bssl_rsa_padding_add_x931(unsigned char *to, int tlen, const unsigned char *f, int fl) { return 1; } int bssl_rsa_padding_check_x931(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len) { return 0; } void *bssl_openssl_malloc(size_t size) { void *addr = NULL; if ((addr = OPENSSL_malloc(size)) != NULL) memset(addr, 0, size); return addr; } EC_KEY_METHOD *bssl_ec_key_method_new(const EC_KEY_METHOD *meth) { EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth)); return ret; } void bssl_ec_key_method_free(EC_KEY_METHOD *meth) { if (meth) { OPENSSL_free(meth); } } ECDSA_SIG *bssl_default_ecdsa_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { return ECDSA_do_sign(dgst, dgst_len, eckey); } #ifdef QAT_SW int bssl_ecdsa_sign(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey) { EC_KEY *default_eckey = NULL; const EC_GROUP *ecgroup = NULL; int ret = 0; int type = 0; if (eckey && (ecgroup = EC_KEY_get0_group(eckey))) { type = EC_GROUP_get_curve_name(ecgroup); } default_eckey = EC_KEY_dup(eckey); if (!default_eckey) { return ret; } ret = ECDSA_sign(type, digest, digest_len, sig, sig_len, default_eckey); EC_KEY_free(default_eckey); return ret; } #endif /* QAT_SW */ int bssl_default_ecdsa_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) { return ECDSA_do_verify(dgst, dgst_len, sig, eckey); } void bssl_ecdsa_meth_set_do_sign(EC_KEY_METHOD *meth, int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey)) { if (meth && sign) { meth->sign = sign; meth->common.is_static = 1; } } int bssl_private_key_method_update(EVP_PKEY *pkey) { RSA_METHOD *rsa_method = NULL; ECDSA_METHOD *ec_method = NULL; EVP_PKEY *privkey = pkey; switch (EVP_PKEY_id(privkey)) { case EVP_PKEY_RSA: if (!(default_algorithm_conf_flags & BSSL_QAT_METHOD_RSA)) { return 1; } rsa_method = bssl_engine_get_rsa_method(); if (!rsa_method || !rsa_method->sign_raw || !rsa_method->decrypt) { return 1; } EVP_PKEY_get0_RSA(pkey)->meth->sign_raw = rsa_method->sign_raw; EVP_PKEY_get0_RSA(pkey)->meth->decrypt = rsa_method->decrypt; break; case EVP_PKEY_EC: if (!(default_algorithm_conf_flags & BSSL_QAT_METHOD_ECDSA)) { return 1; } ec_method = bssl_engine_get_ecdsa_method(); if (!ec_method || !ec_method->sign) { return 1; } EVP_PKEY_get0_EC_KEY(pkey)->ecdsa_meth = ec_method; break; default: return 1; } return 0; } /* Port from openssl/crypto/engine/eng_fat.c */ static int bssl_int_def_cb(const char *alg, int len, void *arg) { unsigned int *pflags = arg; if (alg == NULL) return 0; if (strncmp(alg, "RSA", len) == 0) *pflags |= BSSL_QAT_METHOD_RSA; else if (strncmp(alg, "EC", len) == 0) /* Only support ECDSA */ *pflags |= BSSL_QAT_METHOD_ECDSA; else return 0; /* Not supported */ return 1; /* Success */ } /* Port from boringssl/crypto/conf/conf.c, since it not exported */ static int bssl_conf_parse_list(const char *list, char sep, int remove_whitespace, int (*list_cb)(const char *elem, int len, void *usr), void *arg) { int ret; const char *lstart, *tmpend, *p; if (list == NULL) { OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL); return 0; } lstart = list; for (;;) { if (remove_whitespace) { while (*lstart && isspace((unsigned char)*lstart)) { lstart++; } } p = strchr(lstart, sep); if (p == lstart || !*lstart) { ret = list_cb(NULL, 0, arg); } else { if (p) { tmpend = p - 1; } else { tmpend = lstart + strlen(lstart) - 1; } if (remove_whitespace) { while (isspace((unsigned char)*tmpend)) { tmpend--; } } ret = list_cb(lstart, tmpend - lstart + 1, arg); } if (ret <= 0) { return ret; } if (p == NULL) { return 1; } lstart = p + 1; } } int bssl_qat_set_default_string(const char *def_list) { return bssl_conf_parse_list(def_list, ',', 1, bssl_int_def_cb, &default_algorithm_conf_flags); } void bssl_once(bssl_once_t *once, void (*init)(void)) { if (pthread_once(once, init) != 0) { abort(); } } void bssl_ec_key_method_get_sign(EC_KEY_METHOD *meth, PFUNC_EC_SIGN *sig_func, PFUNC_EC_SIGN_SIG *sig_sig_func) { if (meth) { if (sig_func) { *sig_func = meth->sign; } } if (sig_sig_func) { *sig_sig_func = bssl_default_ecdsa_sign; } } #endif /* QAT_BORINGSSL */ qatengine-1.9.0/qat_bssl.h000066400000000000000000000607111500416242000154540ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_bssl.h * * This file provides and interface for undefined OpenSSL APIs in BoringSSL * *****************************************************************************/ #ifndef QAT_BSSL_H # define QAT_BSSL_H /* Standard Includes */ # include # include /* OpenSSL Includes */ # include # include # include #ifdef BSSL_SOURCE #include "../crypto/fipsmodule/ec/internal.h" #else # include #endif /* BSSL_SOURCE */ /* From engine.h in OpenSSL */ # define ENGINE_CMD_BASE 200 # define ENGINE_CMD_INVALD -1 # define ENGINE_QAT_PTR_DEFINE ENGINE *qat_engine_ptr = NULL; # define ENGINE_QAT_PTR_RESET() qat_engine_ptr = NULL # define ENGINE_QAT_PTR_SET(pt) qat_engine_ptr = pt # define ENGINE_QAT_PTR_GET() qat_engine_ptr # define ENGINE_QAT_PTR_EXPORT extern ENGINE *qat_engine_ptr; ENGINE_QAT_PTR_EXPORT # define SSL_MAX_PIPELINES 32 /* Copy from openssl/include/openssl/async.h */ #if defined(_WIN32) # if defined(BASETYPES) || defined(_WINDEF_H) /* application has to include to use this */ #define OSSL_ASYNC_FD HANDLE #define OSSL_BAD_ASYNC_FD INVALID_HANDLE_VALUE # endif #else #define OSSL_ASYNC_FD int #define OSSL_BAD_ASYNC_FD -1 #endif typedef struct async_wait_ctx_st ASYNC_WAIT_CTX; typedef struct async_job_st ASYNC_JOB; typedef struct async_ctx_st async_ctx; /* Copy from openssl/crypto/async/async_local.h */ struct fd_lookup_st { const void *key; OSSL_ASYNC_FD fd; void *custom_data; void (*cleanup)(ASYNC_WAIT_CTX *, const void *, OSSL_ASYNC_FD, void *); int add; int del; struct fd_lookup_st *next; }; struct async_wait_ctx_st { struct fd_lookup_st *fds; size_t numadd; size_t numdel; int init; int status; int fds_reset; void *data; }; struct async_job_st { int status; ASYNC_WAIT_CTX *waitctx; void (*op_buf_free)(void *, void *, int); int (*tlv_destructor)(void *); void (*free_op_done)(void *); void *(*copy_op_done)(const void *, unsigned int, void (*)(void *, void *, int)); int qat_svm; }; struct async_ctx_st {; ASYNC_JOB *currjob; int *currjob_status; }; #ifndef BSSL_SOURCE struct ec_key_st { /* porting from boringssl/crypto/fipsmodule/ec/internal.h */ EC_GROUP *group; /* Ideally |pub_key| would be an |EC_AFFINE| so serializing it does not pay an inversion each time, but the |EC_KEY_get0_public_key| API implies public keys are stored in an |EC_POINT|-compatible form. */ EC_POINT *pub_key; void *priv_key; /* EC_WRAPPED_SCALAR *priv_key; */ unsigned int enc_flag; point_conversion_form_t conv_form; CRYPTO_refcount_t references; ECDSA_METHOD *ecdsa_meth; CRYPTO_EX_DATA ex_data; } /* EC_KEY */; #endif /* BSSL_SOURCE */ typedef pthread_once_t bssl_once_t; #define BSSL_ONCE_INIT PTHREAD_ONCE_INIT #define bssl_memcpy(dst, src, n) (n == 0 ? dst : memcpy(dst, src, n)) /* These all AYNC macros used to instead of the APIs that defined in OpenSSL but * no definition in BoringSSL */ /* Status of Async Jobs */ #define ASYNC_JOB_OPER_COMPLETE 5 /* OPERATION has completed */ #define ASYNC_JOB_COMPLETE 4 #define ASYNC_JOB_RUNNING 3 #define ASYNC_JOB_ABORT 2 /* unused */ #define ASYNC_JOB_PAUSED 1 /* unused */ #define ASYNC_JOB_STOPPED 0 #define ASYNC_DEFAULT_VAL 1 #define ASYNC_get_current_job bssl_qat_async_load_current_job #define ASYNC_mode_is_enabled ASYNC_get_current_job #define ASYNC_current_job_last_check_and_get() (ASYNC_get_current_job() && \ ((ASYNC_JOB*)ASYNC_get_current_job())->tlv_destructor(NULL)) #define ASYNC_get_wait_ctx(job) (((ASYNC_JOB*)job)->waitctx) #define ASYNC_WAIT_CTX_get_fd bssl_async_wait_ctx_get_fd #define ASYNC_WAIT_CTX_set_wait_fd bssl_async_wait_ctx_set_wait_fd #define ASYNC_WAIT_CTX_get_changed_fds \ bssl_async_wait_ctx_get_changed_fds #define ASYNC_WAIT_CTX_clear_fd bssl_async_wait_ctx_clear_fd #define ASYNC_pause_job(void) ASYNC_DEFAULT_VAL #define ASYNC_job_is_running(async_ctx) \ (*async_ctx->currjob_status != ASYNC_JOB_COMPLETE && \ *async_ctx->currjob_status != ASYNC_JOB_STOPPED && \ *async_ctx->currjob_status != ASYNC_JOB_OPER_COMPLETE) #define ASYNC_job_is_stopped(async_ctx) \ (*async_ctx->currjob_status == ASYNC_JOB_STOPPED) /* These all macros used to instead of the APIs that defined in OpenSSL but * no definition in BoringSSL */ # define ENGINE_DEFAULT (1) # define ENGINE_set_id(e, id) ENGINE_DEFAULT # define ENGINE_set_name(e, name) ENGINE_DEFAULT # define ENGINE_set_RSA(e, rsa_get_method) \ ENGINE_set_RSA_method(e, rsa_get_method, sizeof(RSA_METHOD)) # define ENGINE_set_DSA(e, rsa) ENGINE_DEFAULT # define ENGINE_set_DH(e, dh) ENGINE_DEFAULT # define ENGINE_set_EC(e, ec_get_mothod) \ ENGINE_set_ECDSA_method(e, ec_get_mothod, sizeof(ECDSA_METHOD)) # define ENGINE_set_pkey_meths(e, pkey) ENGINE_DEFAULT # define ENGINE_set_ciphers(e, ciphers) ENGINE_DEFAULT # define qat_create_ciphers() # define ENGINE_set_destroy_function(e, des) ENGINE_DEFAULT /* Called qat_engine_init in ENGINE_set_init_function when binding engine */ # define ENGINE_set_init_function(e, init) (init(e)) # define ENGINE_set_ctrl_function(e, ctrl) ENGINE_DEFAULT # define ENGINE_set_finish_function(e, finish) ENGINE_DEFAULT # define ENGINE_set_cmd_defns(e, cmd_defns) ENGINE_DEFAULT # define ENGINE_by_id(id) (qat_engine_ptr) # define ENGINE_add(add) {} # define EC_KEY_can_sign(ec_key) (1) # define bssl_engine_get_rsa_method() \ (ENGINE_QAT_PTR_GET() ? ENGINE_get_RSA_method(ENGINE_QAT_PTR_GET()) : NULL) # define bssl_engine_get_ecdsa_method() \ ENGINE_get_ECDSA_method(ENGINE_QAT_PTR_GET()) /* Defined a function as variant memory allocation interface with memset used * for no OPENSSL_zalloc() in BoringSSL */ # define OPENSSL_zalloc bssl_openssl_malloc /* Redefine all functions related to RSA methods that defined in OpenSSL but * not in BoringSSL */ /* No effect, just to pass compilation when BoringSSL enabled */ # define RSA_SSLV23_PADDING 2 # define RSA_X931_PADDING 5 # define RSA_METH_RET_DEFAULT (1) # define RSA_meth_set_mod_exp(meth, exp) RSA_METH_RET_DEFAULT # define RSA_meth_set_bn_mod_exp(meth, exp) RSA_METH_RET_DEFAULT # define RSA_meth_set_init(meth, init) RSA_METH_RET_DEFAULT # define RSA_meth_set_finish(meth, finish) RSA_METH_RET_DEFAULT # define RSA_get_default_method() bssl_get_default_RSA_methods() # define RSA_meth_new bssl_rsa_meth_new # define RSA_meth_free bssl_rsa_meth_free # define RSA_meth_get_pub_enc(meth) RSA_public_encrypt # define RSA_meth_get_pub_dec(meth) RSA_public_decrypt # define RSA_meth_get_priv_enc(meth) RSA_private_encrypt_default # define RSA_meth_get_priv_dec(meth) RSA_private_decrypt_default /* Do nothing */ # define RSA_METH_SET_NULL(method, func) \ RSA_METH_RET_DEFAULT; \ do { \ if (method->app_data == NULL) { \ method->app_data = func; \ method->app_data = NULL; \ } \ } while(0) # define RSA_meth_set_pub_enc(meth, func) RSA_METH_SET_NULL(meth, func) # define RSA_meth_set_pub_dec(meth, func) RSA_METH_SET_NULL(meth, func) # define RSA_meth_set_priv_enc(meth, func) RSA_METH_SET_NULL(meth, func) # define RSA_meth_set_priv_dec(meth, func) RSA_METH_SET_NULL(meth, func) # define RSA_meth_set_priv_bssl bssl_rsa_set_priv_meth # define RSA_padding_add_none bssl_rsa_padding_add_none # define RSA_padding_check_none bssl_rsa_padding_check_none # define RSA_padding_add_PKCS1_type_1 bssl_rsa_padding_add_pkcs1_type_1 # define RSA_padding_check_PKCS1_type_1 bssl_rsa_padding_check_pkcs1_type_1 # define RSA_padding_add_PKCS1_type_2 bssl_rsa_padding_add_pkcs1_type_2 # define RSA_padding_check_PKCS1_type_2 bssl_rsa_padding_check_pkcs1_type_2 # define RSA_padding_check_PKCS1_OAEP bssl_rsa_padding_check_pkcs1_OAEP # define RSA_padding_add_SSLv23 bssl_rsa_padding_add_sslv23 # define RSA_padding_check_SSLv23 bssl_rsa_padding_check_sslv23 # define RSA_padding_add_X931 bssl_rsa_padding_add_x931 # define RSA_padding_check_X931 bssl_rsa_padding_check_x931 /* Redefine all functions related to ECDSA methods that defined in OpenSSL but * not in BoringSSL */ # define EC_KEY_METHOD ECDSA_METHOD # define EC_KEY_get_default_method() bssl_get_default_EC_methods() # define EC_KEY_OpenSSL() bssl_get_default_EC_methods() # define EC_KEY_METHOD_new bssl_ec_key_method_new # define EC_KEY_METHOD_free bssl_ec_key_method_free /* Do nothing */ # define EC_KEY_NULL_METHOD(meth, k, m, n) \ do { \ if (meth->app_data == NULL) { \ meth->app_data = k; \ meth->app_data = m; \ meth->app_data = n; \ meth->common.is_static = 1; \ meth->app_data = NULL; \ } \ } while(0) # define EC_KEY_METHOD_get_sign(meth, \ sign_pfunc, sign_setup_pfunc, \ sign_sig_pfunc) \ bssl_ec_key_method_get_sign(meth, sign_pfunc, sign_sig_pfunc) # define EC_KEY_METHOD_set_sign(meth, \ sign_pfunc, sign_setup_pfunc, \ sign_sig_pfunc) \ bssl_ecdsa_meth_set_do_sign(meth, sign_pfunc) /* Ignored ECDSA get verify method */ # define EC_KEY_METHOD_get_verify(meth, \ verify_pfunc, verify_sig_pfunc) \ *(verify_sig_pfunc) = bssl_default_ecdsa_verify # define EC_KEY_METHOD_set_verify(meth, \ verify_pfunc, verify_sig_pfunc) \ EC_KEY_NULL_METHOD(meth, verify_pfunc, NULL, NULL) /* Ignored ECDH methods by redefining invalid methods */ # define EC_KEY_METHOD_get_keygen(meth, pfunc) \ EC_KEY_NULL_METHOD(meth, pfunc, NULL, NULL) # define EC_KEY_METHOD_set_keygen(meth, pfunc) \ EC_KEY_NULL_METHOD(meth, pfunc, NULL, NULL) # define EC_KEY_METHOD_get_compute_key(meth, pfunc) \ EC_KEY_NULL_METHOD(meth, pfunc, NULL, NULL) # define EC_KEY_METHOD_set_compute_key(meth, pfunc) \ EC_KEY_NULL_METHOD(meth, pfunc, NULL, NULL) /* * The default interval in microseconds used for the inline polling thread */ # define QAT_INLINE_POLL_PERIOD_IN_US 1 /* * Used to sleep for QAT_INLINE_POLL_PERIOD_IN_US microseconds after one time * inline polling, purpose to reduce the high CPU usage in performance tests */ # define QAT_INLINE_POLLING_USLEEP() \ do { \ usleep(QAT_INLINE_POLL_PERIOD_IN_US); \ } while(0) # define RSA_INLINE_POLLING_USLEEP QAT_INLINE_POLLING_USLEEP # define ECDSA_INLINE_POLLING_USLEEP QAT_INLINE_POLLING_USLEEP void ENGINE_load_qat(void); void ENGINE_unload_qat(void); int bssl_qat_send_ctrl_cmd(ENGINE *e, const char *cmd_name, long i, void *p, void (*f)(void), int cmd_optional); void *bssl_openssl_malloc(size_t size); int bssl_qat_async_save_current_job(ASYNC_JOB *job); ASYNC_JOB *bssl_qat_async_load_current_job(void); int bssl_qat_before_wake_job(volatile ASYNC_JOB *job, int status, void *in_buf, void *out_buf, void *op_done); RSA_METHOD *bssl_rsa_meth_new(const char *name, int flags); void bssl_rsa_meth_free(RSA_METHOD *meth); int bssl_rsa_set_priv_meth(RSA_METHOD *meth, int (*sign_raw)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding), int (*decrypt)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding)); int bssl_rsa_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); int bssl_rsa_padding_check_none(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len); int bssl_rsa_padding_add_pkcs1_type_1(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); int bssl_rsa_padding_check_pkcs1_type_1(unsigned char *to, int tlen, const unsigned char *from, int flen, int num); int bssl_rsa_padding_add_pkcs1_type_2(uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len); /* RSA_padding_add_PKCS1_OAEP defined in boring/decrepit/rsa/rsa_decrepit.c, * but built into boringssl/build/decrepit/libdecrepit not libcrypto or libssl * One option is to redefine this or link to libdecrepit.so in built system */ /* int RSA_padding_add_PKCS1_OAEP(uint8_t *to, size_t to_len, * const uint8_t *from, size_t from_len, * const uint8_t *param, size_t param_len); */ /* Not porting */ int bssl_rsa_padding_check_pkcs1_type_2(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len); int bssl_rsa_padding_check_pkcs1_OAEP(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len, const unsigned char *p, int pl); int bssl_rsa_padding_add_sslv23(unsigned char *to, int tlen, const unsigned char *f, int fl); int bssl_rsa_padding_check_sslv23(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len); int bssl_rsa_padding_add_x931(unsigned char *to, int tlen, const unsigned char *f, int fl); int bssl_rsa_padding_check_x931(unsigned char *to, int tlen, const unsigned char *f, int fl, int rsa_len); EC_KEY_METHOD *bssl_ec_key_method_new(const EC_KEY_METHOD *meth); void bssl_ec_key_method_free(EC_KEY_METHOD *meth); ECDSA_SIG *bssl_default_ecdsa_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); #ifdef QAT_SW int bssl_ecdsa_sign(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey); #endif /* QAT_SW */ int bssl_default_ecdsa_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); void bssl_ecdsa_meth_set_do_sign(EC_KEY_METHOD *meth, int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey)); int bssl_private_key_method_update(EVP_PKEY *pkey); /* Optional 'name': RSA, EC_KEY, SSL; 'type' set arbitrarily by user */ # define BSSL_DEFINE_EXDATA_OF(name, type) \ static bssl_once_t name##_##type##_index_once = BSSL_ONCE_INIT; \ static int name##_##type##_index = 0; \ \ static void bssl_##name##_##type##_free(void *parent, void *ptr, \ CRYPTO_EX_DATA *ad, int index, \ long argl, void *argp) \ { \ if (ptr) OPENSSL_free((type *)ptr); \ } \ \ static void bssl_##name##_##type##_index_init_once() \ { \ name##_##type##_index = \ name##_get_ex_new_index(0, NULL, NULL, NULL, \ bssl_##name##_##type##_free); \ if (name##_##type##_index < 0) { \ abort(); \ } \ } \ \ static int bssl_##name##_set_##type (name *n, type *t) \ { \ bssl_once(&name##_##type##_index_once, \ bssl_##name##_##type##_index_init_once); \ if (name##_set_ex_data(n, name##_##type##_index, t) != 1) { \ return 1; /* Fail */ \ } \ return 0; /* Success */ \ } \ \ static type *bssl_##name##_get_##type (const name *n) \ { \ bssl_once(&name##_##type##_index_once, \ bssl_##name##_##type##_index_init_once); \ return (type *) name##_get_ex_data(n, name##_##type##_index); \ } # define BSSL_SET_EXDATA_OF(name, type, n, t) \ bssl_##name##_set_##type (n, t) # define BSSL_GET_EXDATA_OF(name, type, n) \ bssl_##name##_get_##type (n) /* Define a group of variables and functions with type async_ctx */ # define BSSL_DEFINE_ASYNC_CTX_INIT_EXDATA(name) \ BSSL_DEFINE_EXDATA_OF(name, async_ctx); /* Set ASYNC_CTX st to RSA/EC_KEY/SSL exdata */ # define BSSL_SET_ASYNC_CTX_TO_EXDATA(name, n, t) \ BSSL_SET_EXDATA_OF(name, async_ctx, n, t) /* Get ASYNC_CTX st from RSA/EC_KEY/SSL exdata */ # define BSSL_GET_ASYNC_CTX_FM_EXDATA(name, n) \ BSSL_GET_EXDATA_OF(name, async_ctx, n) /* Define a group of variables and functions with type async_enable * Note that this type async_enable needs to be defined externally */ # define BSSL_DEFINE_ASYNC_CFG_INIT_EXDATA(name) \ BSSL_DEFINE_EXDATA_OF(name, async_enable); /* Set async_enable to RSA/EC_KEY/SSL exdata */ # define BSSL_SET_ASYNC_CFG_TO_EXDATA(name, n, t) \ BSSL_SET_EXDATA_OF(name, async_enable, n, t) /* Get async_enable from RSA/EC_KEY/SSL exdata */ # define BSSL_GET_ASYNC_CFG_FM_EXDATA(name, n) \ BSSL_GET_EXDATA_OF(name, async_enable, n) # define BSSL_QAT_INIT_DEBUG_LOG "INIT_DEBUG_QAT_LOG" /* Declaration on operation interfaces of ASYNC_WAIT_CTX */ int bssl_async_wait_ctx_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD fd, void *custom_data, void (*cleanup)(ASYNC_WAIT_CTX *, const void *, OSSL_ASYNC_FD, void *)); int bssl_async_wait_ctx_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD *fd, void **custom_data); int bssl_async_wait_ctx_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds); int bssl_async_wait_ctx_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); /* Declaration on operation interfaces of async_ctx */ async_ctx *bssl_qat_async_start_job(void); void bssl_qat_async_finish_job(const async_ctx *ctx); int bssl_qat_async_ctx_copy_result(const async_ctx *ctx, unsigned char *buffer, unsigned long *size, unsigned long max_size); int bssl_qat_async_ctx_get_changed_fds(async_ctx *ctx, OSSL_ASYNC_FD *addfd, size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds); int bssl_qat_set_default_string(const char *def_list); void bssl_once(bssl_once_t *once, void (*init)(void)); typedef int (*PFUNC_EC_SIGN)(const uint8_t *, size_t, uint8_t *, unsigned int *, EC_KEY *); typedef ECDSA_SIG *(*PFUNC_EC_SIGN_SIG)(const unsigned char *, int, const BIGNUM *, const BIGNUM *, EC_KEY *); void bssl_ec_key_method_get_sign(EC_KEY_METHOD *meth, PFUNC_EC_SIGN *sig_func, PFUNC_EC_SIGN_SIG *sig_sig_func); #ifdef QAT_SW typedef void (*mb_async_callback_func) (void *ctx, unsigned char *out_buffer, unsigned long *size, unsigned long max_size); typedef struct _mb_async_ctx { mb_async_callback_func callback_func; void *ctx; } mb_async_ctx; void bssl_mb_async_job_finish_wait(volatile ASYNC_JOB *job, int job_status, int waitctx_status); #endif /* QAT_SW */ #endif qatengine-1.9.0/qat_bssl_err.c000066400000000000000000001124751500416242000163240ustar00rootroot00000000000000/* * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include #include "qat_bssl_err.h" #ifndef OPENSSL_NO_ERR static ERR_STRING_DATA QAT_str_functs[] = { {ERR_PACK(0, QAT_F_AES_GCM_TLS_CIPHER, 0), "aes_gcm_tls_cipher"}, {ERR_PACK(0, QAT_F_BUILD_DECRYPT_OP_BUF, 0), "build_decrypt_op_buf"}, {ERR_PACK(0, QAT_F_BUILD_ENCRYPT_OP_BUF, 0), "build_encrypt_op_buf"}, {ERR_PACK(0, QAT_F_ENGINE_FINISH_BEFORE_FORK_HANDLER, 0), "engine_finish_before_fork_handler"}, {ERR_PACK(0, QAT_F_ENGINE_INIT_CHILD_AT_FORK_HANDLER, 0), "engine_init_child_at_fork_handler"}, {ERR_PACK(0, QAT_F_ENGINE_QAT, 0), "engine_qat"}, {ERR_PACK(0, QAT_F_EVENT_POLL_FUNC, 0), "event_poll_func"}, {ERR_PACK(0, QAT_F_MB_ECDH_COMPUTE_KEY, 0), "mb_ecdh_compute_key"}, {ERR_PACK(0, QAT_F_MB_ECDH_GENERATE_KEY, 0), "mb_ecdh_generate_key"}, {ERR_PACK(0, QAT_F_MB_ECDSA_DO_VERIFY, 0), "mb_ecdsa_do_verify"}, {ERR_PACK(0, QAT_F_MB_ECDSA_SIGN, 0), "mb_ecdsa_sign"}, {ERR_PACK(0, QAT_F_MB_ECDSA_SIGN_SETUP, 0), "mb_ecdsa_sign_setup"}, {ERR_PACK(0, QAT_F_MB_ECDSA_SIGN_SIG, 0), "mb_ecdsa_sign_sig"}, {ERR_PACK(0, QAT_F_MB_ECDSA_SM2_SIGN, 0), "mb_ecdsa_sm2_sign"}, {ERR_PACK(0, QAT_F_MB_ECDSA_SM2_VERIFY, 0), "mb_ecdsa_sm2_verify"}, {ERR_PACK(0, QAT_F_MB_ECDSA_VERIFY, 0), "mb_ecdsa_verify"}, {ERR_PACK(0, QAT_F_MB_SM2_CTRL, 0), "mb_sm2_ctrl"}, {ERR_PACK(0, QAT_F_MB_SM2_INIT, 0), "mb_sm2_init"}, {ERR_PACK(0, QAT_F_MULTIBUFF_RSA_ADD_PADDING_PRIV_ENC, 0), "multibuff_rsa_add_padding_priv_enc"}, {ERR_PACK(0, QAT_F_MULTIBUFF_RSA_ADD_PADDING_PUB_ENC, 0), "multibuff_rsa_add_padding_pub_enc"}, {ERR_PACK(0, QAT_F_MULTIBUFF_RSA_PRIV_DEC, 0), "multibuff_rsa_priv_dec"}, {ERR_PACK(0, QAT_F_MULTIBUFF_RSA_PRIV_ENC, 0), "multibuff_rsa_priv_enc"}, {ERR_PACK(0, QAT_F_MULTIBUFF_RSA_PUB_DEC, 0), "multibuff_rsa_pub_dec"}, {ERR_PACK(0, QAT_F_MULTIBUFF_RSA_PUB_ENC, 0), "multibuff_rsa_pub_enc"}, {ERR_PACK(0, QAT_F_MULTIBUFF_VALIDATE_ECX_DERIVE, 0), "multibuff_validate_ecx_derive"}, {ERR_PACK(0, QAT_F_MULTIBUFF_X25519_DERIVE, 0), "multibuff_x25519_derive"}, {ERR_PACK(0, QAT_F_MULTIBUFF_X25519_KEYGEN, 0), "multibuff_x25519_keygen"}, {ERR_PACK(0, QAT_F_POLL_INSTANCES, 0), "poll_instances"}, {ERR_PACK(0, QAT_F_QAT_ADJUST_THREAD_AFFINITY, 0), "qat_adjust_thread_affinity"}, {ERR_PACK(0, QAT_F_QAT_AES_CCM_CIPHER, 0), "qat_aes_ccm_cipher"}, {ERR_PACK(0, QAT_F_QAT_AES_CCM_CLEANUP, 0), "qat_aes_ccm_cleanup"}, {ERR_PACK(0, QAT_F_QAT_AES_CCM_CTRL, 0), "qat_aes_ccm_ctrl"}, {ERR_PACK(0, QAT_F_QAT_AES_CCM_INIT, 0), "qat_aes_ccm_init"}, {ERR_PACK(0, QAT_F_QAT_AES_CCM_SESSION_INIT, 0), "qat_aes_ccm_session_init"}, {ERR_PACK(0, QAT_F_QAT_AES_CCM_TLS_CIPHER, 0), "qat_aes_ccm_tls_cipher"}, {ERR_PACK(0, QAT_F_QAT_AES_GCM_CIPHER, 0), "qat_aes_gcm_cipher"}, {ERR_PACK(0, QAT_F_QAT_AES_GCM_CLEANUP, 0), "qat_aes_gcm_cleanup"}, {ERR_PACK(0, QAT_F_QAT_AES_GCM_CTRL, 0), "qat_aes_gcm_ctrl"}, {ERR_PACK(0, QAT_F_QAT_AES_GCM_INIT, 0), "qat_aes_gcm_init"}, {ERR_PACK(0, QAT_F_QAT_AES_GCM_SESSION_INIT, 0), "qat_aes_gcm_session_init"}, {ERR_PACK(0, QAT_F_QAT_AES_GCM_TLS_CIPHER, 0), "qat_aes_gcm_tls_cipher"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_CLEANUP, 0), "qat_chacha20_poly1305_cleanup"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_CTRL, 0), "qat_chacha20_poly1305_ctrl"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, 0), "qat_chacha20_poly1305_do_cipher"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_INIT, 0), "qat_chacha20_poly1305_init"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_INIT_KEY_IV, 0), "qat_chacha20_poly1305_init_key_iv"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_MAC_KEYGEN, 0), "qat_chacha20_poly1305_mac_keygen"}, {ERR_PACK(0, QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, 0), "qat_chacha20_poly1305_tls_cipher"}, {ERR_PACK(0, QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, 0), "qat_chachapoly_session_data_init"}, {ERR_PACK(0, QAT_F_QAT_CHACHAPOLY_SETUP_OP_PARAMS, 0), "qat_chachapoly_setup_op_params"}, {ERR_PACK(0, QAT_F_QAT_CREATE_SM4_CBC_CIPHER_METH, 0), "qat_create_sm4_cbc_cipher_meth"}, {ERR_PACK(0, QAT_F_QAT_CREATE_SM4_CCM_CIPHER_METH, 0), "qat_create_sm4_ccm_cipher_meth"}, {ERR_PACK(0, QAT_F_QAT_CRYPTO_CALLBACKFN, 0), "qat_crypto_callbackFn"}, {ERR_PACK(0, QAT_F_QAT_DH_COMPUTE_KEY, 0), "qat_dh_compute_key"}, {ERR_PACK(0, QAT_F_QAT_DH_GENERATE_KEY, 0), "qat_dh_generate_key"}, {ERR_PACK(0, QAT_F_QAT_DSA_DO_SIGN, 0), "qat_dsa_do_sign"}, {ERR_PACK(0, QAT_F_QAT_DSA_DO_VERIFY, 0), "qat_dsa_do_verify"}, {ERR_PACK(0, QAT_F_QAT_DSA_SIGN_SETUP, 0), "qat_dsa_sign_setup"}, {ERR_PACK(0, QAT_F_QAT_ECDH_COMPUTE_KEY, 0), "qat_ecdh_compute_key"}, {ERR_PACK(0, QAT_F_QAT_ECDH_GENERATE_KEY, 0), "qat_ecdh_generate_key"}, {ERR_PACK(0, QAT_F_QAT_ECDSA_DO_SIGN, 0), "qat_ecdsa_do_sign"}, {ERR_PACK(0, QAT_F_QAT_ECDSA_DO_VERIFY, 0), "qat_ecdsa_do_verify"}, {ERR_PACK(0, QAT_F_QAT_ECDSA_SIGN, 0), "qat_ecdsa_sign"}, {ERR_PACK(0, QAT_F_QAT_ECDSA_VERIFY, 0), "qat_ecdsa_verify"}, {ERR_PACK(0, QAT_F_QAT_ENGINE_CTRL, 0), "qat_engine_ctrl"}, {ERR_PACK(0, QAT_F_QAT_ENGINE_ECDH_COMPUTE_KEY, 0), "qat_engine_ecdh_compute_key"}, {ERR_PACK(0, QAT_F_QAT_FD_CLEANUP, 0), "qat_fd_cleanup"}, {ERR_PACK(0, QAT_F_QAT_GET_DH_METHODS, 0), "qat_get_DH_methods"}, {ERR_PACK(0, QAT_F_QAT_GET_DSA_METHODS, 0), "qat_get_DSA_methods"}, {ERR_PACK(0, QAT_F_QAT_GET_EC_METHODS, 0), "qat_get_EC_methods"}, {ERR_PACK(0, QAT_F_QAT_GET_RSA_METHODS, 0), "qat_get_RSA_methods"}, {ERR_PACK(0, QAT_F_QAT_HKDF_CTRL, 0), "qat_hkdf_ctrl"}, {ERR_PACK(0, QAT_F_QAT_HKDF_DERIVE, 0), "qat_hkdf_derive"}, {ERR_PACK(0, QAT_F_QAT_HKDF_INIT, 0), "qat_hkdf_init"}, {ERR_PACK(0, QAT_F_QAT_HKDF_PMETH, 0), "qat_hkdf_pmeth"}, {ERR_PACK(0, QAT_F_QAT_HW_CREATE_SM3_METH, 0), "qat_hw_create_sm3_meth"}, {ERR_PACK(0, QAT_F_QAT_HW_FINISH_INT, 0), "qat_hw_finish_int"}, {ERR_PACK(0, QAT_F_QAT_HW_INIT, 0), "qat_hw_init"}, {ERR_PACK(0, QAT_F_QAT_HW_SHA3_OFFLOAD, 0), "qat_hw_sha3_offload"}, {ERR_PACK(0, QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, 0), "qat_hw_sm2_compute_z_digest"}, {ERR_PACK(0, QAT_F_QAT_HW_SM3_CLEANUP, 0), "qat_hw_sm3_cleanup"}, {ERR_PACK(0, QAT_F_QAT_HW_SM3_COPY, 0), "qat_hw_sm3_copy"}, {ERR_PACK(0, QAT_F_QAT_HW_SM3_DO_OFFLOAD, 0), "qat_hw_sm3_do_offload"}, {ERR_PACK(0, QAT_F_QAT_HW_SM3_FINAL, 0), "qat_hw_sm3_final"}, {ERR_PACK(0, QAT_F_QAT_HW_SM3_SETUP_PARAM, 0), "qat_hw_sm3_setup_param"}, {ERR_PACK(0, QAT_F_QAT_HW_SM3_UPDATE, 0), "qat_hw_sm3_update"}, {ERR_PACK(0, QAT_F_QAT_INIT_OP_DONE, 0), "qat_init_op_done"}, {ERR_PACK(0, QAT_F_QAT_INIT_OP_DONE_PIPE, 0), "qat_init_op_done_pipe"}, {ERR_PACK(0, QAT_F_QAT_INIT_OP_DONE_RSA_CRT, 0), "qat_init_op_done_rsa_crt"}, {ERR_PACK(0, QAT_F_QAT_MOD_EXP, 0), "qat_mod_exp"}, {ERR_PACK(0, QAT_F_QAT_PKEY_ECX_DERIVE25519, 0), "qat_pkey_ecx_derive25519"}, {ERR_PACK(0, QAT_F_QAT_PKEY_ECX_DERIVE448, 0), "qat_pkey_ecx_derive448"}, {ERR_PACK(0, QAT_F_QAT_PKEY_ECX_KEYGEN, 0), "qat_pkey_ecx_keygen"}, {ERR_PACK(0, QAT_F_QAT_PRF_PMETH, 0), "qat_prf_pmeth"}, {ERR_PACK(0, QAT_F_QAT_PRF_TLS_DERIVE, 0), "qat_prf_tls_derive"}, {ERR_PACK(0, QAT_F_QAT_REMAP_INSTANCES, 0), "qat_remap_instances"}, {ERR_PACK(0, QAT_F_QAT_RSA_DECRYPT, 0), "qat_rsa_decrypt"}, {ERR_PACK(0, QAT_F_QAT_RSA_ENCRYPT, 0), "qat_rsa_encrypt"}, {ERR_PACK(0, QAT_F_QAT_RSA_PRIV_DEC, 0), "qat_rsa_priv_dec"}, {ERR_PACK(0, QAT_F_QAT_RSA_PRIV_ENC, 0), "qat_rsa_priv_enc"}, {ERR_PACK(0, QAT_F_QAT_RSA_PUB_DEC, 0), "qat_rsa_pub_dec"}, {ERR_PACK(0, QAT_F_QAT_RSA_PUB_ENC, 0), "qat_rsa_pub_enc"}, {ERR_PACK(0, QAT_F_QAT_SESSION_DATA_INIT, 0), "qat_session_data_init"}, {ERR_PACK(0, QAT_F_QAT_SETUP_OP_PARAMS, 0), "qat_setup_op_params"}, {ERR_PACK(0, QAT_F_QAT_SET_INSTANCE_FOR_THREAD, 0), "qat_set_instance_for_thread"}, {ERR_PACK(0, QAT_F_QAT_SHA3_CLEANUP, 0), "qat_sha3_cleanup"}, {ERR_PACK(0, QAT_F_QAT_SHA3_CTRL, 0), "qat_sha3_ctrl"}, {ERR_PACK(0, QAT_F_QAT_SHA3_FINAL, 0), "qat_sha3_final"}, {ERR_PACK(0, QAT_F_QAT_SHA3_SESSION_DATA_INIT, 0), "qat_sha3_session_data_init"}, {ERR_PACK(0, QAT_F_QAT_SHA3_SETUP_PARAM, 0), "qat_sha3_setup_param"}, {ERR_PACK(0, QAT_F_QAT_SHA3_UPDATE, 0), "qat_sha3_update"}, {ERR_PACK(0, QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, 0), "qat_sm2_compute_z_digest"}, {ERR_PACK(0, QAT_F_QAT_SM2_COPY, 0), "qat_sm2_copy"}, {ERR_PACK(0, QAT_F_QAT_SM2_CTRL, 0), "qat_sm2_ctrl"}, {ERR_PACK(0, QAT_F_QAT_SM2_DIGEST_CUSTOM, 0), "qat_sm2_digest_custom"}, {ERR_PACK(0, QAT_F_QAT_SM2_INIT, 0), "qat_sm2_init"}, {ERR_PACK(0, QAT_F_QAT_SM2_SIGN, 0), "qat_sm2_sign"}, {ERR_PACK(0, QAT_F_QAT_SM2_VERIFY, 0), "qat_sm2_verify"}, {ERR_PACK(0, QAT_F_QAT_SM4_CBC_CLEANUP, 0), "qat_sm4_cbc_cleanup"}, {ERR_PACK(0, QAT_F_QAT_SM4_CBC_DO_CIPHER, 0), "qat_sm4_cbc_do_cipher"}, {ERR_PACK(0, QAT_F_QAT_SM4_CBC_INIT, 0), "qat_sm4_cbc_init"}, {ERR_PACK(0, QAT_F_QAT_SW_INIT, 0), "qat_sw_init"}, {ERR_PACK(0, QAT_F_QAT_SW_SM3_FINAL, 0), "qat_sw_sm3_final"}, {ERR_PACK(0, QAT_F_QAT_SW_SM3_INIT, 0), "qat_sw_sm3_init"}, {ERR_PACK(0, QAT_F_QAT_SW_SM3_UPDATE, 0), "qat_sw_sm3_update"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CBC_CIPHER, 0), "qat_sw_sm4_cbc_cipher"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CBC_CLEANUP, 0), "qat_sw_sm4_cbc_cleanup"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CBC_KEY_INIT, 0), "qat_sw_sm4_cbc_key_init"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CCM_CLEANUP, 0), "qat_sw_sm4_ccm_cleanup"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CCM_CTRL, 0), "qat_sw_sm4_ccm_ctrl"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CCM_DECRYPT, 0), "qat_sw_sm4_ccm_decrypt"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, 0), "qat_sw_sm4_ccm_do_cipher"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CCM_ENCRYPT, 0), "qat_sw_sm4_ccm_encrypt"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_CCM_INIT, 0), "qat_sw_sm4_ccm_init"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_CIPHER, 0), "qat_sw_sm4_gcm_cipher"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_CLEANUP, 0), "qat_sw_sm4_gcm_cleanup"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_CTRL, 0), "qat_sw_sm4_gcm_ctrl"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_DECRYPT, 0), "qat_sw_sm4_gcm_decrypt"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_ENCRYPT, 0), "qat_sw_sm4_gcm_encrypt"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_INIT, 0), "qat_sw_sm4_gcm_init"}, {ERR_PACK(0, QAT_F_QAT_SW_SM4_GCM_TLS_CIPHER, 0), "qat_sw_sm4_gcm_tls_cipher"}, {ERR_PACK(0, QAT_F_QAT_VALIDATE_ECX_DERIVE, 0), "qat_validate_ecx_derive"}, {ERR_PACK(0, QAT_F_QAT_X25519_PMETH, 0), "qat_x25519_pmeth"}, {ERR_PACK(0, QAT_F_QAT_X448_PMETH, 0), "qat_x448_pmeth"}, {ERR_PACK(0, QAT_F_SM2_COMPUTE_MSG_HASH, 0), "sm2_compute_msg_hash"}, {ERR_PACK(0, QAT_F_VAESGCM_CIPHERS_CTRL, 0), "vaesgcm_ciphers_ctrl"}, {ERR_PACK(0, QAT_F_VAESGCM_CIPHERS_DO_CIPHER, 0), "vaesgcm_ciphers_do_cipher"}, {ERR_PACK(0, QAT_F_VAESGCM_CIPHERS_INIT, 0), "vaesgcm_ciphers_init"}, {ERR_PACK(0, QAT_F_VAESGCM_INIT_GCM, 0), "vaesgcm_init_gcm"}, {ERR_PACK(0, QAT_F_VAESGCM_INIT_IPSEC_MB_MGR, 0), "vaesgcm_init_ipsec_mb_mgr"}, {ERR_PACK(0, QAT_F_VAESGCM_INIT_KEY, 0), "vaesgcm_init_key"}, {0, NULL} }; static ERR_STRING_DATA QAT_str_reasons[] = { {ERR_PACK(0, 0, QAT_R_AAD_INVALID_PTR), "aad invalid ptr"}, {ERR_PACK(0, 0, QAT_R_AAD_LEN_INVALID), "aad len invalid"}, {ERR_PACK(0, 0, QAT_R_AAD_MALLOC_FAILURE), "aad malloc failure"}, {ERR_PACK(0, 0, QAT_R_ADD_M2_FAILURE), "add m2 failure"}, {ERR_PACK(0, 0, QAT_R_ADJUST_DELTA_M1_M2_FAILURE), "adjust delta m1 m2 failure"}, {ERR_PACK(0, 0, QAT_R_ALGO_TYPE_SUPPORTED), "algo type supported"}, {ERR_PACK(0, 0, QAT_R_ALGO_TYPE_UNSUPPORTED), "algo type unsupported"}, {ERR_PACK(0, 0, QAT_R_ALLOC_E_CHECK_FAILURE), "alloc e check failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_MULTIBUFF_RSA_METH_FAILURE), "alloc multibuff rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_DSA_METH_FAILURE), "alloc qat dsa meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_RSA_METH_FAILURE), "alloc qat rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_X25519_METH_FAILURE), "alloc qat x25519 meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_X448_METH_FAILURE), "alloc qat x448 meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_TAG_FAILURE), "alloc tag failure"}, {ERR_PACK(0, 0, QAT_R_BAD_INPUT_PARAMS), "bad input params"}, {ERR_PACK(0, 0, QAT_R_BAD_LENGTH), "bad length"}, {ERR_PACK(0, 0, QAT_R_BAD_TLS_CLIENT_VERSION), "bad tls client version"}, {ERR_PACK(0, 0, QAT_R_BN_LIB_FAILURE), "bn lib failure"}, {ERR_PACK(0, 0, QAT_R_BUFFER_TOO_SMALL), "buffer too small"}, {ERR_PACK(0, 0, QAT_R_BUF_CONV_FAIL), "buf conv fail"}, {ERR_PACK(0, 0, QAT_R_CAPABILITY_FAILURE), "capability failure"}, {ERR_PACK(0, 0, QAT_R_CBC_OPERATION_FAILED), "cbc operation failed"}, {ERR_PACK(0, 0, QAT_R_CHACHAPOLY_CTX_NULL), "chachapoly ctx null"}, {ERR_PACK(0, 0, QAT_R_CIPHER_DATA_NULL), "cipher data null"}, {ERR_PACK(0, 0, QAT_R_CIPHER_OPERATION_FAILED), "cipher operation failed"}, {ERR_PACK(0, 0, QAT_R_CLOSE_READFD_FAILURE), "close readfd failure"}, {ERR_PACK(0, 0, QAT_R_COMPUTE_FAILURE), "compute failure"}, {ERR_PACK(0, 0, QAT_R_COMPUTE_H_MULTIPLY_Q_FAILURE), "compute h multiply q failure"}, {ERR_PACK(0, 0, QAT_R_CP_BUF_MALLOC_FAILURE), "cp buf malloc failure"}, {ERR_PACK(0, 0, QAT_R_CQ_BUF_MALLOC_FAILURE), "cq buf malloc failure"}, {ERR_PACK(0, 0, QAT_R_CREATE_FREELIST_QUEUE_FAILURE), "create freelist queue failure"}, {ERR_PACK(0, 0, QAT_R_CTX_MALLOC_FAILURE), "ctx malloc failure"}, {ERR_PACK(0, 0, QAT_R_CTX_NULL), "ctx null"}, {ERR_PACK(0, 0, QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE), "curve coordinate params convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING), "curve does not support signing"}, {ERR_PACK(0, 0, QAT_R_C_MODULO_P_FAILURE), "c modulo p failure"}, {ERR_PACK(0, 0, QAT_R_C_MODULO_Q_FAILURE), "c modulo q failure"}, {ERR_PACK(0, 0, QAT_R_C_P_Q_CP_CQ_MALLOC_FAILURE), "c p q cp cq malloc failure"}, {ERR_PACK(0, 0, QAT_R_DATA_TOO_LARGE_FOR_KEY_SIZE), "data too large for key size"}, {ERR_PACK(0, 0, QAT_R_DEC_OP_DATA_MALLOC_FAILURE), "dec op data malloc failure"}, {ERR_PACK(0, 0, QAT_R_DERIVE_FAILURE), "derive failure"}, {ERR_PACK(0, 0, QAT_R_DGSTLEN_INVALID), "dgstlen invalid"}, {ERR_PACK(0, 0, QAT_R_DGST_BN_CONV_FAILURE), "dgst bn conv failure"}, {ERR_PACK(0, 0, QAT_R_DH_NULL), "dh null"}, {ERR_PACK(0, 0, QAT_R_DINIT_OPERATION_FAILED), "dinit operation failed"}, {ERR_PACK(0, 0, QAT_R_DLEN_INVALID), "dlen invalid"}, {ERR_PACK(0, 0, QAT_R_DSA_DGST_NULL), "dsa dgst null"}, {ERR_PACK(0, 0, QAT_R_DSA_DGST_SIG_NULL), "dsa dgst sig null"}, {ERR_PACK(0, 0, QAT_R_ECDH_GET_AFFINE_COORD_FAILED), "ecdh get affine coord failed"}, {ERR_PACK(0, 0, QAT_R_ECDH_GROUP_NULL), "ecdh group null"}, {ERR_PACK(0, 0, QAT_R_ECDH_PRIVATE_KEY_NULL), "ecdh private key null"}, {ERR_PACK(0, 0, QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL), "ecdh priv key pub key null"}, {ERR_PACK(0, 0, QAT_R_ECDH_SET_AFFINE_COORD_FAILED), "ecdh set affine coord failed"}, {ERR_PACK(0, 0, QAT_R_ECDH_UNKNOWN_FIELD_TYPE), "ecdh unknown field type"}, {ERR_PACK(0, 0, QAT_R_ECDSA_MALLOC_FAILURE), "ecdsa malloc failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIGN_FAILURE), "ecdsa sign failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIGN_NULL), "ecdsa sign null"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIGN_SETUP_FAILURE), "ecdsa sign setup failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIG_MALLOC_FAILURE), "ecdsa sig malloc failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIG_SET_R_S_FAILURE), "ecdsa sig set r s failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_VERIFY_FAILURE), "ecdsa verify failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_VERIFY_NULL), "ecdsa verify null"}, {ERR_PACK(0, 0, QAT_R_ECKEY_GROUP_PUBKEY_SIG_NULL), "eckey group pubkey sig null"}, {ERR_PACK(0, 0, QAT_R_EC_KEY_GROUP_PRIV_KEY_NULL), "ec key group priv key null"}, {ERR_PACK(0, 0, QAT_R_EC_LIB), "ec lib"}, {ERR_PACK(0, 0, QAT_R_EC_POINT_RETRIEVE_FAILURE), "ec point retrieve failure"}, {ERR_PACK(0, 0, QAT_R_EINIT_OPERATION_FAILED), "einit operation failed"}, {ERR_PACK(0, 0, QAT_R_ENC_OP_DATA_MALLOC_FAILURE), "enc op data malloc failure"}, {ERR_PACK(0, 0, QAT_R_ENGINE_CTRL_CMD_FAILURE), "engine ctrl cmd failure"}, {ERR_PACK(0, 0, QAT_R_ENGINE_INIT_FAILURE), "engine init failure"}, {ERR_PACK(0, 0, QAT_R_ENGINE_NULL), "engine null"}, {ERR_PACK(0, 0, QAT_R_EPOLL_CREATE_FAILURE), "epoll create failure"}, {ERR_PACK(0, 0, QAT_R_EPOLL_CTL_FAILURE), "epoll ctl failure"}, {ERR_PACK(0, 0, QAT_R_EVENTS_MALLOC_FAILURE), "events malloc failure"}, {ERR_PACK(0, 0, QAT_R_EVP_LIB), "evp lib"}, {ERR_PACK(0, 0, QAT_R_FAILED_TO_DECRYPT), "failed to decrypt"}, {ERR_PACK(0, 0, QAT_R_FAILED_TO_GET_PARAMETER), "failed to get parameter"}, {ERR_PACK(0, 0, QAT_R_FAILED_TO_SET_PARAMETER), "failed to set parameter"}, {ERR_PACK(0, 0, QAT_R_FALLBACK_INIT_FAILURE), "fallback init failure"}, {ERR_PACK(0, 0, QAT_R_FALLBACK_POINTER_NULL), "fallback pointer null"}, {ERR_PACK(0, 0, QAT_R_FIELD_SIZE_INVALID), "field size invalid"}, {ERR_PACK(0, 0, QAT_R_FREE_DH_METH_FAILURE), "free dh meth failure"}, {ERR_PACK(0, 0, QAT_R_FREE_MULTIBUFF_RSA_METH_FAILURE), "free multibuff rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_FREE_QAT_DSA_METH_FAILURE), "free qat dsa meth failure"}, {ERR_PACK(0, 0, QAT_R_FREE_QAT_RSA_METH_FAILURE), "free qat rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_GCM_TAG_VERIFY_FAILURE), "gcm tag verify failure"}, {ERR_PACK(0, 0, QAT_R_GET_COFACTOR_FAILURE), "get cofactor failure"}, {ERR_PACK(0, 0, QAT_R_GET_FILE_DESCRIPTOR_FAILURE), "get file descriptor failure"}, {ERR_PACK(0, 0, QAT_R_GET_GROUP_FAILURE), "get group failure"}, {ERR_PACK(0, 0, QAT_R_GET_INSTANCE_FAILURE), "get instance failure"}, {ERR_PACK(0, 0, QAT_R_GET_INSTANCE_INFO_FAILURE), "get instance info failure"}, {ERR_PACK(0, 0, QAT_R_GET_NUM_INSTANCE_FAILURE), "get num instance failure"}, {ERR_PACK(0, 0, QAT_R_GET_ORDER_FAILURE), "get order failure"}, {ERR_PACK(0, 0, QAT_R_GET_PQG_FAILURE), "get pqg failure"}, {ERR_PACK(0, 0, QAT_R_GET_PRIV_KEY_FAILURE), "get priv key failure"}, {ERR_PACK(0, 0, QAT_R_GROUP_NULL), "group null"}, {ERR_PACK(0, 0, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL), "group priv key pub key null"}, {ERR_PACK(0, 0, QAT_R_GROUP_PUB_KEY_NULL), "group pub key null"}, {ERR_PACK(0, 0, QAT_R_H_CONVERT_TO_FB_FAILURE), "h convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_ICP_SAL_USERSTART_FAIL), "icp sal userstart fail"}, {ERR_PACK(0, 0, QAT_R_ID_TOO_LARGE), "id too large"}, {ERR_PACK(0, 0, QAT_R_INITIALIZE_CTX_FAILURE), "initialize ctx failure"}, {ERR_PACK(0, 0, QAT_R_INIT_FAIL), "init fail"}, {ERR_PACK(0, 0, QAT_R_INIT_FAILURE), "init failure"}, {ERR_PACK(0, 0, QAT_R_INPUT_DATA_MALLOC_FAILURE), "input data malloc failure"}, {ERR_PACK(0, 0, QAT_R_INPUT_PARAM_INVALID), "input param invalid"}, {ERR_PACK(0, 0, QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE), "instance handle malloc failure"}, {ERR_PACK(0, 0, QAT_R_INSTANCE_UNAVAILABLE), "instance unavailable"}, {ERR_PACK(0, 0, QAT_R_INTERNAL_ERROR), "internal error"}, {ERR_PACK(0, 0, QAT_R_INVALID_AAD), "invalid aad"}, {ERR_PACK(0, 0, QAT_R_INVALID_ATTACHED_TAG), "invalid attached tag"}, {ERR_PACK(0, 0, QAT_R_INVALID_CTRL_TYPE), "invalid ctrl type"}, {ERR_PACK(0, 0, QAT_R_INVALID_CURVE), "invalid curve"}, {ERR_PACK(0, 0, QAT_R_INVALID_DATA), "invalid data"}, {ERR_PACK(0, 0, QAT_R_INVALID_DIGEST), "invalid digest"}, {ERR_PACK(0, 0, QAT_R_INVALID_HASH_DATA), "invalid hash data"}, {ERR_PACK(0, 0, QAT_R_INVALID_INPUT), "invalid input"}, {ERR_PACK(0, 0, QAT_R_INVALID_INPUT_LENGTH), "invalid input length"}, {ERR_PACK(0, 0, QAT_R_INVALID_INPUT_PARAMETER), "invalid input parameter"}, {ERR_PACK(0, 0, QAT_R_INVALID_IVLEN), "invalid ivlen"}, {ERR_PACK(0, 0, QAT_R_INVALID_IV_LENGTH), "invalid iv length"}, {ERR_PACK(0, 0, QAT_R_INVALID_KEY), "invalid key"}, {ERR_PACK(0, 0, QAT_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_PACK(0, 0, QAT_R_INVALID_L), "invalid l"}, {ERR_PACK(0, 0, QAT_R_INVALID_LEN), "invalid len"}, {ERR_PACK(0, 0, QAT_R_INVALID_LENGTH), "invalid length"}, {ERR_PACK(0, 0, QAT_R_INVALID_PEER_KEY), "invalid peer key"}, {ERR_PACK(0, 0, QAT_R_INVALID_PRIVATE_KEY), "invalid private key"}, {ERR_PACK(0, 0, QAT_R_INVALID_PTR), "invalid ptr"}, {ERR_PACK(0, 0, QAT_R_INVALID_PTR_IV), "invalid ptr iv"}, {ERR_PACK(0, 0, QAT_R_INVALID_PUB_KEY), "invalid pub key"}, {ERR_PACK(0, 0, QAT_R_INVALID_QCTX_MEMORY), "invalid qctx memory"}, {ERR_PACK(0, 0, QAT_R_INVALID_TAG), "invalid tag"}, {ERR_PACK(0, 0, QAT_R_INVALID_TAG_LEN), "invalid tag len"}, {ERR_PACK(0, 0, QAT_R_INVALID_TYPE), "invalid type"}, {ERR_PACK(0, 0, QAT_R_IN_KINV_CONVERT_TO_FB_FAILURE), "in kinv convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_IN_R_CONVERT_TO_FB_FAILURE), "in r convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_IPSEC_MGR_NULL), "ipsec mgr null"}, {ERR_PACK(0, 0, QAT_R_IV_ALLOC_FAILURE), "iv alloc failure"}, {ERR_PACK(0, 0, QAT_R_IV_GEN_INVALID), "iv gen invalid"}, {ERR_PACK(0, 0, QAT_R_IV_INVALID), "iv invalid"}, {ERR_PACK(0, 0, QAT_R_IV_LEN_NOT_SUPPORTED), "iv len not supported"}, {ERR_PACK(0, 0, QAT_R_IV_MALLOC_FAILURE), "iv malloc failure"}, {ERR_PACK(0, 0, QAT_R_IV_NOTSET), "iv notset"}, {ERR_PACK(0, 0, QAT_R_IV_NULL_PTR_INVALID), "iv null ptr invalid"}, {ERR_PACK(0, 0, QAT_R_IV_NVALID), "iv nvalid"}, {ERR_PACK(0, 0, QAT_R_KEYGEN_FAILURE), "keygen failure"}, {ERR_PACK(0, 0, QAT_R_KEYS_NOT_SET), "keys not set"}, {ERR_PACK(0, 0, QAT_R_KEY_IV_NOT_SET), "key iv not set"}, {ERR_PACK(0, 0, QAT_R_KEY_MALLOC_FAILURE), "key malloc failure"}, {ERR_PACK(0, 0, QAT_R_KEY_NOTSET), "key notset"}, {ERR_PACK(0, 0, QAT_R_KEY_NULL), "key null"}, {ERR_PACK(0, 0, QAT_R_KEY_SIZE_TOO_SMALL), "key size too small"}, {ERR_PACK(0, 0, QAT_R_K_ALLOCATE_FAILURE), "k allocate failure"}, {ERR_PACK(0, 0, QAT_R_K_CONVERT_TO_FB_FAILURE), "k convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_K_E_ORDER_MALLOC_FAILURE), "k e order malloc failure"}, {ERR_PACK(0, 0, QAT_R_K_ORDER_CONVERT_TO_FB_FAILURE), "k order convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_K_RAND_GENERATE_FAILURE), "k rand generate failure"}, {ERR_PACK(0, 0, QAT_R_M1_DEDUCT_M2_FAILURE), "m1 deduct m2 failure"}, {ERR_PACK(0, 0, QAT_R_M1_M2_P_Q_QINV_TMP_MALLOC_FAILURE), "m1 m2 p q qinv tmp malloc failure"}, {ERR_PACK(0, 0, QAT_R_MALLOC_FAILURE), "malloc failure"}, {ERR_PACK(0, 0, QAT_R_MAX_RETRIES_EXCEEDED), "max retries exceeded"}, {ERR_PACK(0, 0, QAT_R_MB_FREE_EC_METHOD_FAILURE), "mb free ec method failure"}, {ERR_PACK(0, 0, QAT_R_MB_GET_EC_METHOD_MALLOC_FAILURE), "mb get ec method malloc failure"}, {ERR_PACK(0, 0, QAT_R_MODULO_P_FAILURE), "modulo p failure"}, {ERR_PACK(0, 0, QAT_R_MOD_GET_NEXT_INST_FAIL), "mod get next inst fail"}, {ERR_PACK(0, 0, QAT_R_MOD_LN_MOD_EXP_FAIL), "mod ln mod exp fail"}, {ERR_PACK(0, 0, QAT_R_MOD_SETUP_ASYNC_EVENT_FAIL), "mod setup async event fail"}, {ERR_PACK(0, 0, QAT_R_MSGLEN_NOTSET), "msglen notset"}, {ERR_PACK(0, 0, QAT_R_MULTIPLY_QINV_FAILURE), "multiply qinv failure"}, {ERR_PACK(0, 0, QAT_R_NID_NOT_SUPPORTED), "nid not supported"}, {ERR_PACK(0, 0, QAT_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_PACK(0, 0, QAT_R_N_E_CONVERT_TO_FB_FAILURE), "n e convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_N_E_NULL), "n e null"}, {ERR_PACK(0, 0, QAT_R_OP1_BASE_PDATA_MALLOC_FAILURE), "op1 base pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OP2_BASE_PDATA_MALLOC_FAILURE), "op2 base pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_A_PDATA_MALLOC_FAILURE), "opdata a pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_DATA_MALLOC_FAILURE), "opdata data malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_D_MALLOC_FAILURE), "opdata d malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_E_MALLOC_FAILURE), "opdata e malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_K_MALLOC_FAILURE), "opdata k malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_MALLOC_FAILURE), "opdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_PDATA_MALLOC_FAILURE), "opdata pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_ZPDATA_MALLOC_FAILURE), "opdata zpdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDCRT_NULL), "opdcrt null"}, {ERR_PACK(0, 0, QAT_R_OPDONE_NULL), "opdone null"}, {ERR_PACK(0, 0, QAT_R_OPDPIPE_NULL), "opdpipe null"}, {ERR_PACK(0, 0, QAT_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, {ERR_PACK(0, 0, QAT_R_ORDER_MALLOC_FAILURE), "order malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUT1_PDATA_MALLOC_FAILURE), "out1 pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUT2_PDATA_MALLOC_FAILURE), "out2 pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTPUT_BUFFER_TOO_SMALL), "output buffer too small"}, {ERR_PACK(0, 0, QAT_R_OUTPUT_BUF_MALLOC_FAILURE), "output buf malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE), "output buf pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTX_MALLOC_FAILURE), "outx malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTX_OUTY_LEN_NULL), "outx outy len null"}, {ERR_PACK(0, 0, QAT_R_OUTY_MALLOC_FAILURE), "outy malloc failure"}, {ERR_PACK(0, 0, QAT_R_PADDING_UNKNOWN), "padding unknown"}, {ERR_PACK(0, 0, QAT_R_PKCS_DECODING_ERROR), "pkcs decoding error"}, {ERR_PACK(0, 0, QAT_R_POLLING_THREAD_CREATE_FAILURE), "polling thread create failure"}, {ERR_PACK(0, 0, QAT_R_POLLING_THREAD_SEM_INIT_FAILURE), "polling thread sem init failure"}, {ERR_PACK(0, 0, QAT_R_POLLING_THREAD_SIGMASK_FAILURE), "polling thread sigmask failure"}, {ERR_PACK(0, 0, QAT_R_POLL_INSTANCE_FAILURE), "poll instance failure"}, {ERR_PACK(0, 0, QAT_R_POPDATA_A_PDATA_MALLOC_FAILURE), "popdata a pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_POPDATA_MALLOC_FAILURE), "popdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_POPDATA_PCURVE_MALLOC_FAILURE), "popdata pcurve malloc failure"}, {ERR_PACK(0, 0, QAT_R_PPV_MALLOC_FAILURE), "ppv malloc failure"}, {ERR_PACK(0, 0, QAT_R_PPV_PDATA_MALLOC_FAILURE), "ppv pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTR_MALLOC_FAILURE), "presultr malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTR_PDATA_MALLOC_FAILURE), "presultr pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTS_MALLOC_FAILURE), "presults malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTS_PDATA_MALLOC_FAILURE), "presults pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTX_MALLOC_FAILURE), "presultx malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTX_PDATA_MALLOC_FAILURE), "presultx pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTY_LENGTH_CHECK_FAILURE), "presulty length check failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTY_MALLOC_FAILURE), "presulty malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTY_PDATA_MALLOC_FAILURE), "presulty pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_DUPLICATE_FAILURE), "priv key duplicate failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE), "priv key k e d convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_MALLOC_FAILURE), "priv key malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_M_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE), "priv key m xg yg a b p convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_NULL), "priv key null"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE), "priv key rand generate failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE), "priv key xg yg a b p convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_XP_YP_A_B_P_CONVERT_TO_FB_FAILURE), "priv key xp yp a b p convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_CREATE_FAILURE), "pthread create failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_GETAFFINITY_FAILURE), "pthread getaffinity failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_JOIN_FAILURE), "pthread join failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_SETAFFINITY_FAILURE), "pthread setaffinity failure"}, {ERR_PACK(0, 0, QAT_R_PUB_KEY_DUPLICATE_FAILURE), "pub key duplicate failure"}, {ERR_PACK(0, 0, QAT_R_PUB_KEY_MALLOC_FAILURE), "pub key malloc failure"}, {ERR_PACK(0, 0, QAT_R_PUB_KEY_NULL), "pub key null"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XG_YG_MALLOC_FAILURE), "p a b xg yg malloc failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XG_YG_M_K_R_ORDER_MALLOC_FAILURE), "p a b xg yg m k r order malloc failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XG_YG_XP_YP_M_ORDER_FAILURE), "p a b xg yg xp yp m order failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XP_YP_FAILURE), "p a b xp yp failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XP_YP_MALLOC_FAILURE), "p a b xp yp malloc failure"}, {ERR_PACK(0, 0, QAT_R_P_G_PRIV_KEY_CONVERT_TO_FB_FAILURE), "p g priv key convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_PUB_PRIV_KEY_CONVERT_TO_FB_FAILURE), "p pub priv key convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE), "p q dmp dmq convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_Q_DMP_DMQ_IQMP_NULL), "p q dmp dmq iqmp null"}, {ERR_PACK(0, 0, QAT_R_P_Q_G_NULL), "p q g null"}, {ERR_PACK(0, 0, QAT_R_P_Q_G_X_K_CONVERT_TO_FB_FAILURE), "p q g x k convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_Q_G_Y_Z_R_S_CONVERT_TO_FB_FAILURE), "p q g y z r s convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_QAT_ALLOC_DH_METH_FAILURE), "qat alloc dh meth failure"}, {ERR_PACK(0, 0, QAT_R_QAT_CREATE_ENGINE_FAILURE), "qat create engine failure"}, {ERR_PACK(0, 0, QAT_R_QAT_ECDSA_DO_SIGN_FAIL), "qat ecdsa do sign fail"}, {ERR_PACK(0, 0, QAT_R_QAT_FREE_EC_METHOD_FAILURE), "qat free ec method failure"}, {ERR_PACK(0, 0, QAT_R_QAT_GET_EC_METHOD_MALLOC_FAILURE), "qat get ec method malloc failure"}, {ERR_PACK(0, 0, QAT_R_QAT_SET_DH_METH_FAILURE), "qat set dh meth failure"}, {ERR_PACK(0, 0, QAT_R_QCTX_CTX_NULL), "qctx ctx null"}, {ERR_PACK(0, 0, QAT_R_QCTX_NULL), "qctx null"}, {ERR_PACK(0, 0, QAT_R_RAND_BYTES_FAILURE), "rand bytes failure"}, {ERR_PACK(0, 0, QAT_R_RAND_FAILURE), "rand failure"}, {ERR_PACK(0, 0, QAT_R_RAND_GENERATE_FAILURE), "rand generate failure"}, {ERR_PACK(0, 0, QAT_R_RESULT_PDATA_ALLOC_FAIL), "result pdata alloc fail"}, {ERR_PACK(0, 0, QAT_R_RETRIEVE_EC_POINT_FAILURE), "retrieve ec point failure"}, {ERR_PACK(0, 0, QAT_R_RETRIEVE_ORDER_FAILURE), "retrieve order failure"}, {ERR_PACK(0, 0, QAT_R_RSA_FROM_TO_NULL), "rsa from to null"}, {ERR_PACK(0, 0, QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE), "rsa output buf pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_R_Q_COMPARE_FAILURE), "r q compare failure"}, {ERR_PACK(0, 0, QAT_R_SECRET_KEY_MALLOC_FAILURE), "secret key malloc failure"}, {ERR_PACK(0, 0, QAT_R_SECRET_KEY_PDATA_MALLOC_FAILURE), "secret key pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_SEM_POST_FAILURE), "sem post failure"}, {ERR_PACK(0, 0, QAT_R_SETUP_ASYNC_EVENT_FAILURE), "setup async event failure"}, {ERR_PACK(0, 0, QAT_R_SET_ADDRESS_TRANSLATION_FAILURE), "set address translation failure"}, {ERR_PACK(0, 0, QAT_R_SET_FILE_DESCRIPTOR_NONBLOCKING_FAILURE), "set file descriptor nonblocking failure"}, {ERR_PACK(0, 0, QAT_R_SET_INSTANCE_FAILURE), "set instance failure"}, {ERR_PACK(0, 0, QAT_R_SET_MULTIBUFF_RSA_METH_FAILURE), "set multibuff rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_SET_NOTIFICATION_CALLBACK_FAILURE), "set notification callback failure"}, {ERR_PACK(0, 0, QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE), "set polling thread affinity failure"}, {ERR_PACK(0, 0, QAT_R_SET_PRIV_KEY_FAILURE), "set priv key failure"}, {ERR_PACK(0, 0, QAT_R_SET_QAT_DSA_METH_FAILURE), "set qat dsa meth failure"}, {ERR_PACK(0, 0, QAT_R_SET_QAT_RSA_METH_FAILURE), "set qat rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_SET_TAG_INVALID_OP), "set tag invalid op"}, {ERR_PACK(0, 0, QAT_R_SHA3_CTX_NULL), "sha3 ctx null"}, {ERR_PACK(0, 0, QAT_R_SIG_GET_R_S_FAILURE), "sig get r s failure"}, {ERR_PACK(0, 0, QAT_R_SIG_MALLOC_FAILURE), "sig malloc failure"}, {ERR_PACK(0, 0, QAT_R_SM2_BAD_SIGNATURE), "sm2 bad signature"}, {ERR_PACK(0, 0, QAT_R_SM2_ID_TOO_LARGE), "sm2 id too large"}, {ERR_PACK(0, 0, QAT_R_SM2_INVALID_DIGEST), "sm2 invalid digest"}, {ERR_PACK(0, 0, QAT_R_SM2_SIGN_NULL), "sm2 sign null"}, {ERR_PACK(0, 0, QAT_R_SM2_SIG_GEN_MALLOC_FAILURE), "sm2 sig gen malloc failure"}, {ERR_PACK(0, 0, QAT_R_SM2_SIG_MALLOC_FAILURE), "sm2 sig malloc failure"}, {ERR_PACK(0, 0, QAT_R_SM2_SIG_SET_R_S_FAILURE), "sm2 sig set r s failure"}, {ERR_PACK(0, 0, QAT_R_SM2_VERIFY_NULL), "sm2 verify null"}, {ERR_PACK(0, 0, QAT_R_SM3_CTX_NULL), "sm3 ctx null"}, {ERR_PACK(0, 0, QAT_R_SM3_FINAL_FAILURE), "sm3 final failure"}, {ERR_PACK(0, 0, QAT_R_SM3_INIT_FAILURE), "sm3 init failure"}, {ERR_PACK(0, 0, QAT_R_SM3_UPDATE_FAILURE), "sm3 update failure"}, {ERR_PACK(0, 0, QAT_R_SM4_CCM_DECRYPT_FAILURE), "sm4 ccm decrypt failure"}, {ERR_PACK(0, 0, QAT_R_SM4_GCM_DECRYPT_FAILURE), "sm4 gcm decrypt failure"}, {ERR_PACK(0, 0, QAT_R_SM4_GCM_ENCRYPT_FAILURE), "sm4 gcm encrypt failure"}, {ERR_PACK(0, 0, QAT_R_SM4_GET_INSTANCE_FAILED), "sm4 get instance failed"}, {ERR_PACK(0, 0, QAT_R_SM4_GET_SESSIONCTX_SIZE_FAILED), "sm4 get sessionctx size failed"}, {ERR_PACK(0, 0, QAT_R_SM4_MALLOC_FAILED), "sm4 malloc failed"}, {ERR_PACK(0, 0, QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE), "sm4 no qat instance available"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_CKEY), "sm4 null ckey"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_CTX), "sm4 null ctx"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_CTX_OR_KEY), "sm4 null ctx or key"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_POINTER), "sm4 null pointer"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_QCTX), "sm4 null qctx"}, {ERR_PACK(0, 0, QAT_R_SM4_QAT_CONTEXT_NOT_INITIALISED), "sm4 qat context not initialised"}, {ERR_PACK(0, 0, QAT_R_SM4_QAT_INITSESSION_FAILED), "sm4 qat initsession failed"}, {ERR_PACK(0, 0, QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED), "sm4 qat submit request failed"}, {ERR_PACK(0, 0, QAT_R_SM4_REMOVE_SESSION_FAILED), "sm4 remove session failed"}, {ERR_PACK(0, 0, QAT_R_SM4_SETUP_META_DATA_FAILED), "sm4 setup meta data failed"}, {ERR_PACK(0, 0, QAT_R_SM4_SET_METHODS_FAILED), "sm4 set methods failed"}, {ERR_PACK(0, 0, QAT_R_SSD_MALLOC_FAILURE), "ssd malloc failure"}, {ERR_PACK(0, 0, QAT_R_SSD_NULL), "ssd null"}, {ERR_PACK(0, 0, QAT_R_START_INSTANCE_FAILURE), "start instance failure"}, {ERR_PACK(0, 0, QAT_R_STOP_INSTANCE_FAILURE), "stop instance failure"}, {ERR_PACK(0, 0, QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL), "sw get compute key pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_KEYGEN_PFUNC_NULL), "sw get keygen pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_SIGN_PFUNC_NULL), "sw get sign pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_SIGN_SETUP_PFUNC_NULL), "sw get sign setup pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL), "sw get sign sig pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_VERIFY_PFUNC_NULL), "sw get verify pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_VERIFY_SIG_PFUNC_NULL), "sw get verify sig pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_METHOD_NULL), "sw method null"}, {ERR_PACK(0, 0, QAT_R_S_NULL), "s null"}, {ERR_PACK(0, 0, QAT_R_S_Q_COMPARE_FAILURE), "s q compare failure"}, {ERR_PACK(0, 0, QAT_R_TAG_NOTSET), "tag notset"}, {ERR_PACK(0, 0, QAT_R_TAG_NOT_NEEDED), "tag not needed"}, {ERR_PACK(0, 0, QAT_R_UNKNOWN_PADDING), "unknown padding"}, {ERR_PACK(0, 0, QAT_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, {ERR_PACK(0, 0, QAT_R_WAKE_PAUSE_JOB_FAILURE), "wake pause job failure"}, {ERR_PACK(0, 0, QAT_R_X_Y_E_MALLOC_FAILURE), "x y e malloc failure"}, {ERR_PACK(0, 0, QAT_R_X_Y_TX_TY_BN_MALLOC_FAILURE), "x y tx ty bn malloc failure"}, {ERR_PACK(0, 0, QAT_R_X_Y_Z_MALLOC_FAILURE), "x y z malloc failure"}, {ERR_PACK(0, 0, QAT_R_ZALLOC_FAILURE), "zalloc failure"}, {ERR_PACK(0, 0, QAT_R_Z_ALLOCATE_FAILURE), "z allocate failure"}, {0, NULL} }; #endif static int lib_code = 0; static int error_loaded = 0; int ERR_load_QAT_strings(void) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); if (!error_loaded) { #ifndef OPENSSL_NO_ERR ERR_load_strings(lib_code, QAT_str_functs); ERR_load_strings(lib_code, QAT_str_reasons); #endif error_loaded = 1; } return 1; } void ERR_unload_QAT_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR ERR_unload_strings(lib_code, QAT_str_functs); ERR_unload_strings(lib_code, QAT_str_reasons); #endif error_loaded = 0; } } void ERR_QAT_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); ERR_PUT_error(lib_code, function, reason, file, line); } qatengine-1.9.0/qat_bssl_err.h000066400000000000000000000740011500416242000163210ustar00rootroot00000000000000/* * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #ifndef QAT_BSSL_ERR_H # define QAT_BSSL_ERR_H # define QATerr(f, r) ERR_QAT_error((f), (r), __FILE__, __LINE__) # define ERR_PUT_error(lib_code, function, reason, file, line) ERR_put_error(lib_code, function, reason, file, line) # ifdef __cplusplus extern "C" { # endif int ERR_load_QAT_strings(void); void ERR_unload_QAT_strings(void); void ERR_QAT_error(int function, int reason, char *file, int line); # ifdef __cplusplus } # endif /* * QAT function codes. */ # define QAT_F_AES_GCM_TLS_CIPHER 100 # define QAT_F_BUILD_DECRYPT_OP_BUF 101 # define QAT_F_BUILD_ENCRYPT_OP_BUF 102 # define QAT_F_ENGINE_FINISH_BEFORE_FORK_HANDLER 103 # define QAT_F_ENGINE_INIT_CHILD_AT_FORK_HANDLER 104 # define QAT_F_ENGINE_QAT 105 # define QAT_F_EVENT_POLL_FUNC 106 # define QAT_F_MB_ECDH_COMPUTE_KEY 107 # define QAT_F_MB_ECDH_GENERATE_KEY 108 # define QAT_F_MB_ECDSA_DO_VERIFY 109 # define QAT_F_MB_ECDSA_SIGN 110 # define QAT_F_MB_ECDSA_SIGN_SETUP 111 # define QAT_F_MB_ECDSA_SIGN_SIG 112 # define QAT_F_MB_ECDSA_SM2_SIGN 113 # define QAT_F_MB_ECDSA_SM2_VERIFY 114 # define QAT_F_MB_ECDSA_VERIFY 115 # define QAT_F_MB_SM2_CTRL 116 # define QAT_F_MB_SM2_INIT 117 # define QAT_F_MULTIBUFF_RSA_ADD_PADDING_PRIV_ENC 118 # define QAT_F_MULTIBUFF_RSA_ADD_PADDING_PUB_ENC 119 # define QAT_F_MULTIBUFF_RSA_PRIV_DEC 120 # define QAT_F_MULTIBUFF_RSA_PRIV_ENC 121 # define QAT_F_MULTIBUFF_RSA_PUB_DEC 122 # define QAT_F_MULTIBUFF_RSA_PUB_ENC 123 # define QAT_F_MULTIBUFF_VALIDATE_ECX_DERIVE 124 # define QAT_F_MULTIBUFF_X25519_DERIVE 125 # define QAT_F_MULTIBUFF_X25519_KEYGEN 126 # define QAT_F_POLL_INSTANCES 127 # define QAT_F_QAT_ADJUST_THREAD_AFFINITY 128 # define QAT_F_QAT_AES_CCM_CIPHER 129 # define QAT_F_QAT_AES_CCM_CLEANUP 130 # define QAT_F_QAT_AES_CCM_CTRL 131 # define QAT_F_QAT_AES_CCM_INIT 132 # define QAT_F_QAT_AES_CCM_SESSION_INIT 133 # define QAT_F_QAT_AES_CCM_TLS_CIPHER 134 # define QAT_F_QAT_AES_GCM_CIPHER 135 # define QAT_F_QAT_AES_GCM_CLEANUP 136 # define QAT_F_QAT_AES_GCM_CTRL 137 # define QAT_F_QAT_AES_GCM_INIT 138 # define QAT_F_QAT_AES_GCM_SESSION_INIT 139 # define QAT_F_QAT_AES_GCM_TLS_CIPHER 140 # define QAT_F_QAT_CHACHA20_POLY1305_CLEANUP 141 # define QAT_F_QAT_CHACHA20_POLY1305_CTRL 142 # define QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER 143 # define QAT_F_QAT_CHACHA20_POLY1305_INIT 144 # define QAT_F_QAT_CHACHA20_POLY1305_INIT_KEY_IV 145 # define QAT_F_QAT_CHACHA20_POLY1305_MAC_KEYGEN 146 # define QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER 147 # define QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT 148 # define QAT_F_QAT_CHACHAPOLY_SETUP_OP_PARAMS 149 # define QAT_F_QAT_CREATE_SM4_CBC_CIPHER_METH 150 # define QAT_F_QAT_CREATE_SM4_CCM_CIPHER_METH 151 # define QAT_F_QAT_CRYPTO_CALLBACKFN 152 # define QAT_F_QAT_DH_COMPUTE_KEY 153 # define QAT_F_QAT_DH_GENERATE_KEY 154 # define QAT_F_QAT_DSA_DO_SIGN 155 # define QAT_F_QAT_DSA_DO_VERIFY 156 # define QAT_F_QAT_DSA_SIGN_SETUP 157 # define QAT_F_QAT_ECDH_COMPUTE_KEY 158 # define QAT_F_QAT_ECDH_GENERATE_KEY 159 # define QAT_F_QAT_ECDSA_DO_SIGN 160 # define QAT_F_QAT_ECDSA_DO_VERIFY 161 # define QAT_F_QAT_ECDSA_SIGN 162 # define QAT_F_QAT_ECDSA_VERIFY 163 # define QAT_F_QAT_ENGINE_CTRL 164 # define QAT_F_QAT_ENGINE_ECDH_COMPUTE_KEY 165 # define QAT_F_QAT_FD_CLEANUP 166 # define QAT_F_QAT_GET_DH_METHODS 167 # define QAT_F_QAT_GET_DSA_METHODS 168 # define QAT_F_QAT_GET_EC_METHODS 169 # define QAT_F_QAT_GET_RSA_METHODS 170 # define QAT_F_QAT_HKDF_CTRL 171 # define QAT_F_QAT_HKDF_DERIVE 172 # define QAT_F_QAT_HKDF_INIT 173 # define QAT_F_QAT_HKDF_PMETH 174 # define QAT_F_QAT_HW_CREATE_SM3_METH 175 # define QAT_F_QAT_HW_FINISH_INT 176 # define QAT_F_QAT_HW_INIT 177 # define QAT_F_QAT_HW_SHA3_OFFLOAD 178 # define QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST 179 # define QAT_F_QAT_HW_SM3_CLEANUP 180 # define QAT_F_QAT_HW_SM3_COPY 181 # define QAT_F_QAT_HW_SM3_DO_OFFLOAD 182 # define QAT_F_QAT_HW_SM3_FINAL 183 # define QAT_F_QAT_HW_SM3_SETUP_PARAM 184 # define QAT_F_QAT_HW_SM3_UPDATE 185 # define QAT_F_QAT_INIT_OP_DONE 186 # define QAT_F_QAT_INIT_OP_DONE_PIPE 187 # define QAT_F_QAT_INIT_OP_DONE_RSA_CRT 188 # define QAT_F_QAT_MOD_EXP 189 # define QAT_F_QAT_PKEY_ECX_DERIVE25519 190 # define QAT_F_QAT_PKEY_ECX_DERIVE448 191 # define QAT_F_QAT_PKEY_ECX_KEYGEN 192 # define QAT_F_QAT_PRF_PMETH 193 # define QAT_F_QAT_PRF_TLS_DERIVE 194 # define QAT_F_QAT_REMAP_INSTANCES 195 # define QAT_F_QAT_RSA_DECRYPT 196 # define QAT_F_QAT_RSA_ENCRYPT 197 # define QAT_F_QAT_RSA_PRIV_DEC 198 # define QAT_F_QAT_RSA_PRIV_ENC 199 # define QAT_F_QAT_RSA_PUB_DEC 200 # define QAT_F_QAT_RSA_PUB_ENC 201 # define QAT_F_QAT_SESSION_DATA_INIT 202 # define QAT_F_QAT_SETUP_OP_PARAMS 203 # define QAT_F_QAT_SET_INSTANCE_FOR_THREAD 204 # define QAT_F_QAT_SHA3_CLEANUP 205 # define QAT_F_QAT_SHA3_CTRL 206 # define QAT_F_QAT_SHA3_FINAL 207 # define QAT_F_QAT_SHA3_SESSION_DATA_INIT 208 # define QAT_F_QAT_SHA3_SETUP_PARAM 209 # define QAT_F_QAT_SHA3_UPDATE 210 # define QAT_F_QAT_SM2_COMPUTE_Z_DIGEST 211 # define QAT_F_QAT_SM2_COPY 212 # define QAT_F_QAT_SM2_CTRL 213 # define QAT_F_QAT_SM2_DIGEST_CUSTOM 214 # define QAT_F_QAT_SM2_INIT 215 # define QAT_F_QAT_SM2_SIGN 216 # define QAT_F_QAT_SM2_VERIFY 217 # define QAT_F_QAT_SM4_CBC_CLEANUP 218 # define QAT_F_QAT_SM4_CBC_DO_CIPHER 219 # define QAT_F_QAT_SM4_CBC_INIT 220 # define QAT_F_QAT_SW_INIT 221 # define QAT_F_QAT_SW_SM3_FINAL 222 # define QAT_F_QAT_SW_SM3_INIT 223 # define QAT_F_QAT_SW_SM3_UPDATE 224 # define QAT_F_QAT_SW_SM4_CBC_CIPHER 225 # define QAT_F_QAT_SW_SM4_CBC_CLEANUP 226 # define QAT_F_QAT_SW_SM4_CBC_KEY_INIT 227 # define QAT_F_QAT_SW_SM4_CCM_CLEANUP 228 # define QAT_F_QAT_SW_SM4_CCM_CTRL 229 # define QAT_F_QAT_SW_SM4_CCM_DECRYPT 230 # define QAT_F_QAT_SW_SM4_CCM_DO_CIPHER 231 # define QAT_F_QAT_SW_SM4_CCM_ENCRYPT 232 # define QAT_F_QAT_SW_SM4_CCM_INIT 233 # define QAT_F_QAT_SW_SM4_GCM_CIPHER 234 # define QAT_F_QAT_SW_SM4_GCM_CLEANUP 235 # define QAT_F_QAT_SW_SM4_GCM_CTRL 236 # define QAT_F_QAT_SW_SM4_GCM_DECRYPT 237 # define QAT_F_QAT_SW_SM4_GCM_ENCRYPT 238 # define QAT_F_QAT_SW_SM4_GCM_INIT 239 # define QAT_F_QAT_SW_SM4_GCM_TLS_CIPHER 240 # define QAT_F_QAT_VALIDATE_ECX_DERIVE 241 # define QAT_F_QAT_X25519_PMETH 242 # define QAT_F_QAT_X448_PMETH 243 # define QAT_F_SM2_COMPUTE_MSG_HASH 244 # define QAT_F_VAESGCM_CIPHERS_CTRL 245 # define QAT_F_VAESGCM_CIPHERS_DO_CIPHER 246 # define QAT_F_VAESGCM_CIPHERS_INIT 247 # define QAT_F_VAESGCM_INIT_GCM 248 # define QAT_F_VAESGCM_INIT_IPSEC_MB_MGR 249 # define QAT_F_VAESGCM_INIT_KEY 250 /* * QAT reason codes. */ # define QAT_R_AAD_INVALID_PTR 100 # define QAT_R_AAD_LEN_INVALID 101 # define QAT_R_AAD_MALLOC_FAILURE 102 # define QAT_R_ADD_M2_FAILURE 103 # define QAT_R_ADJUST_DELTA_M1_M2_FAILURE 104 # define QAT_R_ALGO_TYPE_SUPPORTED 105 # define QAT_R_ALGO_TYPE_UNSUPPORTED 106 # define QAT_R_ALLOC_E_CHECK_FAILURE 107 # define QAT_R_ALLOC_MULTIBUFF_RSA_METH_FAILURE 108 # define QAT_R_ALLOC_QAT_DSA_METH_FAILURE 109 # define QAT_R_ALLOC_QAT_RSA_METH_FAILURE 110 # define QAT_R_ALLOC_QAT_X25519_METH_FAILURE 111 # define QAT_R_ALLOC_QAT_X448_METH_FAILURE 112 # define QAT_R_ALLOC_TAG_FAILURE 113 # define QAT_R_BAD_INPUT_PARAMS 114 # define QAT_R_BAD_LENGTH 115 # define QAT_R_BAD_TLS_CLIENT_VERSION 116 # define QAT_R_BN_LIB_FAILURE 117 # define QAT_R_BUFFER_TOO_SMALL 118 # define QAT_R_BUF_CONV_FAIL 119 # define QAT_R_CAPABILITY_FAILURE 120 # define QAT_R_CBC_OPERATION_FAILED 121 # define QAT_R_CHACHAPOLY_CTX_NULL 122 # define QAT_R_CIPHER_DATA_NULL 123 # define QAT_R_CIPHER_OPERATION_FAILED 124 # define QAT_R_CLOSE_READFD_FAILURE 125 # define QAT_R_COMPUTE_FAILURE 126 # define QAT_R_COMPUTE_H_MULTIPLY_Q_FAILURE 127 # define QAT_R_CP_BUF_MALLOC_FAILURE 128 # define QAT_R_CQ_BUF_MALLOC_FAILURE 129 # define QAT_R_CREATE_FREELIST_QUEUE_FAILURE 130 # define QAT_R_CTX_MALLOC_FAILURE 131 # define QAT_R_CTX_NULL 132 # define QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE 133 # define QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING 134 # define QAT_R_C_MODULO_P_FAILURE 135 # define QAT_R_C_MODULO_Q_FAILURE 136 # define QAT_R_C_P_Q_CP_CQ_MALLOC_FAILURE 137 # define QAT_R_DATA_TOO_LARGE_FOR_KEY_SIZE 138 # define QAT_R_DEC_OP_DATA_MALLOC_FAILURE 139 # define QAT_R_DERIVE_FAILURE 140 # define QAT_R_DGSTLEN_INVALID 141 # define QAT_R_DGST_BN_CONV_FAILURE 142 # define QAT_R_DH_NULL 143 # define QAT_R_DINIT_OPERATION_FAILED 144 # define QAT_R_DLEN_INVALID 145 # define QAT_R_DSA_DGST_NULL 146 # define QAT_R_DSA_DGST_SIG_NULL 147 # define QAT_R_ECDH_GET_AFFINE_COORD_FAILED 148 # define QAT_R_ECDH_GROUP_NULL 149 # define QAT_R_ECDH_PRIVATE_KEY_NULL 150 # define QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL 151 # define QAT_R_ECDH_SET_AFFINE_COORD_FAILED 152 # define QAT_R_ECDH_UNKNOWN_FIELD_TYPE 153 # define QAT_R_ECDSA_MALLOC_FAILURE 154 # define QAT_R_ECDSA_SIGN_FAILURE 155 # define QAT_R_ECDSA_SIGN_NULL 156 # define QAT_R_ECDSA_SIGN_SETUP_FAILURE 157 # define QAT_R_ECDSA_SIG_MALLOC_FAILURE 158 # define QAT_R_ECDSA_SIG_SET_R_S_FAILURE 159 # define QAT_R_ECDSA_VERIFY_FAILURE 160 # define QAT_R_ECDSA_VERIFY_NULL 161 # define QAT_R_ECKEY_GROUP_PUBKEY_SIG_NULL 162 # define QAT_R_EC_KEY_GROUP_PRIV_KEY_NULL 163 # define QAT_R_EC_LIB 164 # define QAT_R_EC_POINT_RETRIEVE_FAILURE 165 # define QAT_R_EINIT_OPERATION_FAILED 166 # define QAT_R_ENC_OP_DATA_MALLOC_FAILURE 167 # define QAT_R_ENGINE_CTRL_CMD_FAILURE 168 # define QAT_R_ENGINE_INIT_FAILURE 169 # define QAT_R_ENGINE_NULL 170 # define QAT_R_EPOLL_CREATE_FAILURE 171 # define QAT_R_EPOLL_CTL_FAILURE 172 # define QAT_R_EVENTS_MALLOC_FAILURE 173 # define QAT_R_EVP_LIB 174 # define QAT_R_FAILED_TO_DECRYPT 175 # define QAT_R_FAILED_TO_GET_PARAMETER 176 # define QAT_R_FAILED_TO_SET_PARAMETER 177 # define QAT_R_FALLBACK_INIT_FAILURE 178 # define QAT_R_FALLBACK_POINTER_NULL 179 # define QAT_R_FIELD_SIZE_INVALID 180 # define QAT_R_FREE_DH_METH_FAILURE 181 # define QAT_R_FREE_MULTIBUFF_RSA_METH_FAILURE 182 # define QAT_R_FREE_QAT_DSA_METH_FAILURE 183 # define QAT_R_FREE_QAT_RSA_METH_FAILURE 184 # define QAT_R_GCM_TAG_VERIFY_FAILURE 185 # define QAT_R_GET_COFACTOR_FAILURE 186 # define QAT_R_GET_FILE_DESCRIPTOR_FAILURE 187 # define QAT_R_GET_GROUP_FAILURE 188 # define QAT_R_GET_INSTANCE_FAILURE 189 # define QAT_R_GET_INSTANCE_INFO_FAILURE 190 # define QAT_R_GET_NUM_INSTANCE_FAILURE 191 # define QAT_R_GET_ORDER_FAILURE 192 # define QAT_R_GET_PQG_FAILURE 193 # define QAT_R_GET_PRIV_KEY_FAILURE 194 # define QAT_R_GROUP_NULL 195 # define QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL 196 # define QAT_R_GROUP_PUB_KEY_NULL 197 # define QAT_R_H_CONVERT_TO_FB_FAILURE 198 # define QAT_R_ICP_SAL_USERSTART_FAIL 199 # define QAT_R_ID_TOO_LARGE 200 # define QAT_R_INITIALIZE_CTX_FAILURE 201 # define QAT_R_INIT_FAIL 202 # define QAT_R_INIT_FAILURE 203 # define QAT_R_INPUT_DATA_MALLOC_FAILURE 204 # define QAT_R_INPUT_PARAM_INVALID 205 # define QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE 206 # define QAT_R_INSTANCE_UNAVAILABLE 207 # define QAT_R_INTERNAL_ERROR 208 # define QAT_R_INVALID_AAD 209 # define QAT_R_INVALID_ATTACHED_TAG 210 # define QAT_R_INVALID_CTRL_TYPE 211 # define QAT_R_INVALID_CURVE 212 # define QAT_R_INVALID_DATA 213 # define QAT_R_INVALID_DIGEST 214 # define QAT_R_INVALID_HASH_DATA 215 # define QAT_R_INVALID_INPUT 216 # define QAT_R_INVALID_INPUT_LENGTH 217 # define QAT_R_INVALID_INPUT_PARAMETER 218 # define QAT_R_INVALID_IVLEN 219 # define QAT_R_INVALID_IV_LENGTH 220 # define QAT_R_INVALID_KEY 221 # define QAT_R_INVALID_KEY_LENGTH 222 # define QAT_R_INVALID_L 223 # define QAT_R_INVALID_LEN 224 # define QAT_R_INVALID_LENGTH 225 # define QAT_R_INVALID_PEER_KEY 226 # define QAT_R_INVALID_PRIVATE_KEY 227 # define QAT_R_INVALID_PTR 228 # define QAT_R_INVALID_PTR_IV 229 # define QAT_R_INVALID_PUB_KEY 230 # define QAT_R_INVALID_QCTX_MEMORY 231 # define QAT_R_INVALID_TAG 232 # define QAT_R_INVALID_TAG_LEN 233 # define QAT_R_INVALID_TYPE 234 # define QAT_R_IN_KINV_CONVERT_TO_FB_FAILURE 235 # define QAT_R_IN_R_CONVERT_TO_FB_FAILURE 236 # define QAT_R_IPSEC_MGR_NULL 237 # define QAT_R_IV_ALLOC_FAILURE 238 # define QAT_R_IV_GEN_INVALID 239 # define QAT_R_IV_INVALID 240 # define QAT_R_IV_LEN_NOT_SUPPORTED 241 # define QAT_R_IV_MALLOC_FAILURE 242 # define QAT_R_IV_NOTSET 243 # define QAT_R_IV_NULL_PTR_INVALID 244 # define QAT_R_IV_NVALID 245 # define QAT_R_KEYGEN_FAILURE 246 # define QAT_R_KEYS_NOT_SET 247 # define QAT_R_KEY_IV_NOT_SET 248 # define QAT_R_KEY_MALLOC_FAILURE 249 # define QAT_R_KEY_NOTSET 250 # define QAT_R_KEY_NULL 251 # define QAT_R_KEY_SIZE_TOO_SMALL 252 # define QAT_R_K_ALLOCATE_FAILURE 253 # define QAT_R_K_CONVERT_TO_FB_FAILURE 254 # define QAT_R_K_E_ORDER_MALLOC_FAILURE 255 # define QAT_R_K_ORDER_CONVERT_TO_FB_FAILURE 256 # define QAT_R_K_RAND_GENERATE_FAILURE 257 # define QAT_R_M1_DEDUCT_M2_FAILURE 258 # define QAT_R_M1_M2_P_Q_QINV_TMP_MALLOC_FAILURE 259 # define QAT_R_MALLOC_FAILURE 260 # define QAT_R_MAX_RETRIES_EXCEEDED 261 # define QAT_R_MB_FREE_EC_METHOD_FAILURE 262 # define QAT_R_MB_GET_EC_METHOD_MALLOC_FAILURE 263 # define QAT_R_MODULO_P_FAILURE 264 # define QAT_R_MOD_GET_NEXT_INST_FAIL 265 # define QAT_R_MOD_LN_MOD_EXP_FAIL 266 # define QAT_R_MOD_SETUP_ASYNC_EVENT_FAIL 267 # define QAT_R_MSGLEN_NOTSET 268 # define QAT_R_MULTIPLY_QINV_FAILURE 269 # define QAT_R_NID_NOT_SUPPORTED 270 # define QAT_R_NO_PARAMETERS_SET 271 # define QAT_R_N_E_CONVERT_TO_FB_FAILURE 272 # define QAT_R_N_E_NULL 273 # define QAT_R_OP1_BASE_PDATA_MALLOC_FAILURE 274 # define QAT_R_OP2_BASE_PDATA_MALLOC_FAILURE 275 # define QAT_R_OPDATA_A_PDATA_MALLOC_FAILURE 276 # define QAT_R_OPDATA_DATA_MALLOC_FAILURE 277 # define QAT_R_OPDATA_D_MALLOC_FAILURE 278 # define QAT_R_OPDATA_E_MALLOC_FAILURE 279 # define QAT_R_OPDATA_K_MALLOC_FAILURE 280 # define QAT_R_OPDATA_MALLOC_FAILURE 281 # define QAT_R_OPDATA_PDATA_MALLOC_FAILURE 282 # define QAT_R_OPDATA_ZPDATA_MALLOC_FAILURE 283 # define QAT_R_OPDCRT_NULL 284 # define QAT_R_OPDONE_NULL 285 # define QAT_R_OPDPIPE_NULL 286 # define QAT_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 287 # define QAT_R_ORDER_MALLOC_FAILURE 288 # define QAT_R_OUT1_PDATA_MALLOC_FAILURE 289 # define QAT_R_OUT2_PDATA_MALLOC_FAILURE 290 # define QAT_R_OUTPUT_BUFFER_TOO_SMALL 291 # define QAT_R_OUTPUT_BUF_MALLOC_FAILURE 292 # define QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE 293 # define QAT_R_OUTX_MALLOC_FAILURE 294 # define QAT_R_OUTX_OUTY_LEN_NULL 295 # define QAT_R_OUTY_MALLOC_FAILURE 296 # define QAT_R_PADDING_UNKNOWN 297 # define QAT_R_PKCS_DECODING_ERROR 298 # define QAT_R_POLLING_THREAD_CREATE_FAILURE 299 # define QAT_R_POLLING_THREAD_SEM_INIT_FAILURE 300 # define QAT_R_POLLING_THREAD_SIGMASK_FAILURE 301 # define QAT_R_POLL_INSTANCE_FAILURE 302 # define QAT_R_POPDATA_A_PDATA_MALLOC_FAILURE 303 # define QAT_R_POPDATA_MALLOC_FAILURE 304 # define QAT_R_POPDATA_PCURVE_MALLOC_FAILURE 305 # define QAT_R_PPV_MALLOC_FAILURE 306 # define QAT_R_PPV_PDATA_MALLOC_FAILURE 307 # define QAT_R_PRESULTR_MALLOC_FAILURE 308 # define QAT_R_PRESULTR_PDATA_MALLOC_FAILURE 309 # define QAT_R_PRESULTS_MALLOC_FAILURE 310 # define QAT_R_PRESULTS_PDATA_MALLOC_FAILURE 311 # define QAT_R_PRESULTX_MALLOC_FAILURE 312 # define QAT_R_PRESULTX_PDATA_MALLOC_FAILURE 313 # define QAT_R_PRESULTY_LENGTH_CHECK_FAILURE 314 # define QAT_R_PRESULTY_MALLOC_FAILURE 315 # define QAT_R_PRESULTY_PDATA_MALLOC_FAILURE 316 # define QAT_R_PRIV_KEY_DUPLICATE_FAILURE 317 # define QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE 318 # define QAT_R_PRIV_KEY_MALLOC_FAILURE 319 # define QAT_R_PRIV_KEY_M_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE 320 # define QAT_R_PRIV_KEY_NULL 321 # define QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE 322 # define QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE 323 # define QAT_R_PRIV_KEY_XP_YP_A_B_P_CONVERT_TO_FB_FAILURE 324 # define QAT_R_PTHREAD_CREATE_FAILURE 325 # define QAT_R_PTHREAD_GETAFFINITY_FAILURE 326 # define QAT_R_PTHREAD_JOIN_FAILURE 327 # define QAT_R_PTHREAD_SETAFFINITY_FAILURE 328 # define QAT_R_PUB_KEY_DUPLICATE_FAILURE 329 # define QAT_R_PUB_KEY_MALLOC_FAILURE 330 # define QAT_R_PUB_KEY_NULL 331 # define QAT_R_P_A_B_XG_YG_MALLOC_FAILURE 332 # define QAT_R_P_A_B_XG_YG_M_K_R_ORDER_MALLOC_FAILURE 333 # define QAT_R_P_A_B_XG_YG_XP_YP_M_ORDER_FAILURE 334 # define QAT_R_P_A_B_XP_YP_FAILURE 335 # define QAT_R_P_A_B_XP_YP_MALLOC_FAILURE 336 # define QAT_R_P_G_PRIV_KEY_CONVERT_TO_FB_FAILURE 337 # define QAT_R_P_PUB_PRIV_KEY_CONVERT_TO_FB_FAILURE 338 # define QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE 339 # define QAT_R_P_Q_DMP_DMQ_IQMP_NULL 340 # define QAT_R_P_Q_G_NULL 341 # define QAT_R_P_Q_G_X_K_CONVERT_TO_FB_FAILURE 342 # define QAT_R_P_Q_G_Y_Z_R_S_CONVERT_TO_FB_FAILURE 343 # define QAT_R_QAT_ALLOC_DH_METH_FAILURE 344 # define QAT_R_QAT_CREATE_ENGINE_FAILURE 345 # define QAT_R_QAT_ECDSA_DO_SIGN_FAIL 346 # define QAT_R_QAT_FREE_EC_METHOD_FAILURE 347 # define QAT_R_QAT_GET_EC_METHOD_MALLOC_FAILURE 348 # define QAT_R_QAT_SET_DH_METH_FAILURE 349 # define QAT_R_QCTX_CTX_NULL 350 # define QAT_R_QCTX_NULL 351 # define QAT_R_RAND_BYTES_FAILURE 352 # define QAT_R_RAND_FAILURE 353 # define QAT_R_RAND_GENERATE_FAILURE 354 # define QAT_R_RESULT_PDATA_ALLOC_FAIL 355 # define QAT_R_RETRIEVE_EC_POINT_FAILURE 356 # define QAT_R_RETRIEVE_ORDER_FAILURE 357 # define QAT_R_RSA_FROM_TO_NULL 358 # define QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE 359 # define QAT_R_R_Q_COMPARE_FAILURE 360 # define QAT_R_SECRET_KEY_MALLOC_FAILURE 361 # define QAT_R_SECRET_KEY_PDATA_MALLOC_FAILURE 362 # define QAT_R_SEM_POST_FAILURE 363 # define QAT_R_SETUP_ASYNC_EVENT_FAILURE 364 # define QAT_R_SET_ADDRESS_TRANSLATION_FAILURE 365 # define QAT_R_SET_FILE_DESCRIPTOR_NONBLOCKING_FAILURE 366 # define QAT_R_SET_INSTANCE_FAILURE 367 # define QAT_R_SET_MULTIBUFF_RSA_METH_FAILURE 368 # define QAT_R_SET_NOTIFICATION_CALLBACK_FAILURE 369 # define QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE 370 # define QAT_R_SET_PRIV_KEY_FAILURE 371 # define QAT_R_SET_QAT_DSA_METH_FAILURE 372 # define QAT_R_SET_QAT_RSA_METH_FAILURE 373 # define QAT_R_SET_TAG_INVALID_OP 374 # define QAT_R_SHA3_CTX_NULL 375 # define QAT_R_SIG_GET_R_S_FAILURE 376 # define QAT_R_SIG_MALLOC_FAILURE 377 # define QAT_R_SM2_BAD_SIGNATURE 378 # define QAT_R_SM2_ID_TOO_LARGE 379 # define QAT_R_SM2_INVALID_DIGEST 380 # define QAT_R_SM2_SIGN_NULL 381 # define QAT_R_SM2_SIG_GEN_MALLOC_FAILURE 382 # define QAT_R_SM2_SIG_MALLOC_FAILURE 383 # define QAT_R_SM2_SIG_SET_R_S_FAILURE 384 # define QAT_R_SM2_VERIFY_NULL 385 # define QAT_R_SM3_CTX_NULL 386 # define QAT_R_SM3_FINAL_FAILURE 387 # define QAT_R_SM3_INIT_FAILURE 388 # define QAT_R_SM3_UPDATE_FAILURE 389 # define QAT_R_SM4_CCM_DECRYPT_FAILURE 390 # define QAT_R_SM4_GCM_DECRYPT_FAILURE 391 # define QAT_R_SM4_GCM_ENCRYPT_FAILURE 392 # define QAT_R_SM4_GET_INSTANCE_FAILED 393 # define QAT_R_SM4_GET_SESSIONCTX_SIZE_FAILED 394 # define QAT_R_SM4_MALLOC_FAILED 395 # define QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE 396 # define QAT_R_SM4_NULL_CKEY 397 # define QAT_R_SM4_NULL_CTX 398 # define QAT_R_SM4_NULL_CTX_OR_KEY 399 # define QAT_R_SM4_NULL_POINTER 400 # define QAT_R_SM4_NULL_QCTX 401 # define QAT_R_SM4_QAT_CONTEXT_NOT_INITIALISED 402 # define QAT_R_SM4_QAT_INITSESSION_FAILED 403 # define QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED 404 # define QAT_R_SM4_REMOVE_SESSION_FAILED 405 # define QAT_R_SM4_SETUP_META_DATA_FAILED 406 # define QAT_R_SM4_SET_METHODS_FAILED 407 # define QAT_R_SSD_MALLOC_FAILURE 408 # define QAT_R_SSD_NULL 409 # define QAT_R_START_INSTANCE_FAILURE 410 # define QAT_R_STOP_INSTANCE_FAILURE 411 # define QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL 412 # define QAT_R_SW_GET_KEYGEN_PFUNC_NULL 413 # define QAT_R_SW_GET_SIGN_PFUNC_NULL 414 # define QAT_R_SW_GET_SIGN_SETUP_PFUNC_NULL 415 # define QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL 416 # define QAT_R_SW_GET_VERIFY_PFUNC_NULL 417 # define QAT_R_SW_GET_VERIFY_SIG_PFUNC_NULL 418 # define QAT_R_SW_METHOD_NULL 419 # define QAT_R_S_NULL 420 # define QAT_R_S_Q_COMPARE_FAILURE 421 # define QAT_R_TAG_NOTSET 422 # define QAT_R_TAG_NOT_NEEDED 423 # define QAT_R_UNKNOWN_PADDING 424 # define QAT_R_UNKNOWN_PADDING_TYPE 425 # define QAT_R_WAKE_PAUSE_JOB_FAILURE 426 # define QAT_R_X_Y_E_MALLOC_FAILURE 427 # define QAT_R_X_Y_TX_TY_BN_MALLOC_FAILURE 428 # define QAT_R_X_Y_Z_MALLOC_FAILURE 429 # define QAT_R_ZALLOC_FAILURE 430 # define QAT_R_Z_ALLOCATE_FAILURE 431 #endif qatengine-1.9.0/qat_common.h000066400000000000000000000065461500416242000160070ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_common.h * * This file provides the common data structure for QAT_HW & QAT_SW * *****************************************************************************/ #ifndef QAT_COMMON_H # define QAT_COMMON_H /* Begin of ECX common data structures */ # define X25519_KEYLEN 32 # define X448_KEYLEN 56 # define QAT_X448_DATALEN 64 # define X448_DATA_KEY_DIFF 8 # define ED448_KEYLEN 57/* This is used for OpenSSL 3.0 ECX_KEY */ # define MAX_KEYLEN 57 # if OPENSSL_VERSION_NUMBER < 0x30200000 typedef int CRYPTO_REF_COUNT; # else typedef struct { int val; } CRYPTO_REF_COUNT; # endif /* Only for QAT_HW built with OpenSSL 1.1.1 Engine */ # ifndef QAT_OPENSSL_3 typedef struct { unsigned char pubkey[QAT_X448_DATALEN]; unsigned char *privkey; } ECX_KEY; # endif # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) typedef enum { ECX_KEY_TYPE_X25519, ECX_KEY_TYPE_X448, ECX_KEY_TYPE_ED25519, ECX_KEY_TYPE_ED448 } ECX_KEY_TYPE; typedef struct ecx_key_st { OSSL_LIB_CTX *libctx; char *propq; unsigned int haspubkey:1; unsigned char pubkey[ED448_KEYLEN]; unsigned char *privkey; size_t keylen; ECX_KEY_TYPE type; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif } QAT_SW_ECX_KEY, ECX_KEY; # else typedef struct { unsigned char pubkey[MAX_KEYLEN]; unsigned char *privkey; } QAT_SW_ECX_KEY; # endif /* End of ECX common data structures */ #endif qatengine-1.9.0/qat_constant_time.h000066400000000000000000000135651500416242000173650ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /* * This file is based on modified code from OpenSSL. * This is needed because the constant time functions are not exported * from OpenSSL forcing engines to have their own copy of the * functionality. * The code based on OpenSSL code is subject to the following license: */ /* * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ /***************************************************************************** * @file qat_constant_time.h * * This file provides constant time functions * *****************************************************************************/ #ifndef QAT_CONST_TIME_H # define QAT_CONST_TIME_H #ifdef __cplusplus extern "C" { #endif #pragma GCC push_options #pragma GCC optimize ("O0") static inline unsigned int value_barrier(unsigned int a) { volatile unsigned int r = a; return r; } static inline unsigned int qat_constant_time_select(unsigned int mask, unsigned int a, unsigned int b) { return (value_barrier(mask) & a) | (value_barrier(~mask) & b); } static inline unsigned char qat_constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b) { return (unsigned char)qat_constant_time_select(mask, a, b); } static inline unsigned int qat_constant_time_msb(unsigned int a) { return 0 - (a >> (sizeof(a) * 8 - 1)); } static inline unsigned int qat_constant_time_lt(unsigned int a, unsigned int b) { return qat_constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); } static inline unsigned int qat_constant_time_ge(unsigned int a, unsigned int b) { return ~qat_constant_time_lt(a, b); } static inline unsigned char qat_constant_time_ge_8(unsigned int a, unsigned int b) { return (unsigned char)(qat_constant_time_ge(a, b)); } static inline unsigned int qat_constant_time_is_zero(unsigned int a) { return qat_constant_time_msb(~a & (a - 1)); } static inline unsigned int qat_constant_time_eq(unsigned int a, unsigned int b) { return qat_constant_time_is_zero(a ^ b); } static inline unsigned char qat_constant_time_is_zero_8(unsigned int a) { return (unsigned char)qat_constant_time_is_zero(a); } static inline size_t value_barrier_s(size_t a) { volatile size_t r = a; return r; } static inline size_t qat_constant_time_select_s(size_t mask, size_t a, size_t b) { return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b); } static inline size_t qat_constant_time_msb_s(size_t a) { return 0 - (a >> (sizeof(a) * 8 - 1)); } static inline int qat_constant_time_select_int(unsigned int mask, int a, int b) { return (int)qat_constant_time_select(mask, (unsigned)(a), (unsigned)(b)); } /* This function works like qat_constant_time_select but * operates on pointer types. This would return either * "a" (if "i" is 1) or "b" (if "i" is 0). */ static inline void *qat_constant_time_select_ptr(int i, void *a, void *b) { /* i should be 0 or 1 to avoid running into pointer issues. */ i = i & 1; intptr_t time_int_result = ((~(i - 1)) & (intptr_t)a) | ((i - 1) & (intptr_t)b); return (void *)time_int_result; } /* This function returns 1 in case of a<=b else 0. */ static inline int qat_constant_time_le_int(int a, int b) { return !(((b + (~a + 1)) >> (sizeof(int) * 8 - 1)) & 1); } #pragma GCC pop_options #ifdef __cplusplus } #endif #endif /* QAT_CONST_TIME_H */ qatengine-1.9.0/qat_err.c000066400000000000000000000644701500416242000153020ustar00rootroot00000000000000/* * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include #include "qat_err.h" #ifndef OPENSSL_NO_ERR static ERR_STRING_DATA QAT_str_reasons[] = { {ERR_PACK(0, 0, QAT_R_AAD_INVALID_PTR), "aad invalid ptr"}, {ERR_PACK(0, 0, QAT_R_AAD_LEN_INVALID), "aad len invalid"}, {ERR_PACK(0, 0, QAT_R_AAD_MALLOC_FAILURE), "aad malloc failure"}, {ERR_PACK(0, 0, QAT_R_ADD_M2_FAILURE), "add m2 failure"}, {ERR_PACK(0, 0, QAT_R_ADJUST_DELTA_M1_M2_FAILURE), "adjust delta m1 m2 failure"}, {ERR_PACK(0, 0, QAT_R_ALGO_TYPE_SUPPORTED), "algo type supported"}, {ERR_PACK(0, 0, QAT_R_ALGO_TYPE_UNSUPPORTED), "algo type unsupported"}, {ERR_PACK(0, 0, QAT_R_ALLOC_E_CHECK_FAILURE), "alloc e check failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_MULTIBUFF_RSA_METH_FAILURE), "alloc multibuff rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_DSA_METH_FAILURE), "alloc qat dsa meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_RSA_METH_FAILURE), "alloc qat rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_X25519_METH_FAILURE), "alloc qat x25519 meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_QAT_X448_METH_FAILURE), "alloc qat x448 meth failure"}, {ERR_PACK(0, 0, QAT_R_ALLOC_TAG_FAILURE), "alloc tag failure"}, {ERR_PACK(0, 0, QAT_R_BAD_INPUT_PARAMS), "bad input params"}, {ERR_PACK(0, 0, QAT_R_BAD_LENGTH), "bad length"}, {ERR_PACK(0, 0, QAT_R_BAD_TLS_CLIENT_VERSION), "bad tls client version"}, {ERR_PACK(0, 0, QAT_R_BN_LIB_FAILURE), "bn lib failure"}, {ERR_PACK(0, 0, QAT_R_BUFFER_TOO_SMALL), "buffer too small"}, {ERR_PACK(0, 0, QAT_R_BUF_CONV_FAIL), "buf conv fail"}, {ERR_PACK(0, 0, QAT_R_CAPABILITY_FAILURE), "capability failure"}, {ERR_PACK(0, 0, QAT_R_CBC_OPERATION_FAILED), "cbc operation failed"}, {ERR_PACK(0, 0, QAT_R_CHACHAPOLY_CTX_NULL), "chachapoly ctx null"}, {ERR_PACK(0, 0, QAT_R_CIPHER_DATA_NULL), "cipher data null"}, {ERR_PACK(0, 0, QAT_R_CIPHER_OPERATION_FAILED), "cipher operation failed"}, {ERR_PACK(0, 0, QAT_R_CLOSE_READFD_FAILURE), "close readfd failure"}, {ERR_PACK(0, 0, QAT_R_COMPUTE_FAILURE), "compute failure"}, {ERR_PACK(0, 0, QAT_R_COMPUTE_H_MULTIPLY_Q_FAILURE), "compute h multiply q failure"}, {ERR_PACK(0, 0, QAT_R_CP_BUF_MALLOC_FAILURE), "cp buf malloc failure"}, {ERR_PACK(0, 0, QAT_R_CQ_BUF_MALLOC_FAILURE), "cq buf malloc failure"}, {ERR_PACK(0, 0, QAT_R_CREATE_FREELIST_QUEUE_FAILURE), "create freelist queue failure"}, {ERR_PACK(0, 0, QAT_R_CTX_MALLOC_FAILURE), "ctx malloc failure"}, {ERR_PACK(0, 0, QAT_R_CTX_NULL), "ctx null"}, {ERR_PACK(0, 0, QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE), "curve coordinate params convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING), "curve does not support signing"}, {ERR_PACK(0, 0, QAT_R_C_MODULO_P_FAILURE), "c modulo p failure"}, {ERR_PACK(0, 0, QAT_R_C_MODULO_Q_FAILURE), "c modulo q failure"}, {ERR_PACK(0, 0, QAT_R_C_P_Q_CP_CQ_MALLOC_FAILURE), "c p q cp cq malloc failure"}, {ERR_PACK(0, 0, QAT_R_DATA_TOO_LARGE_FOR_KEY_SIZE), "data too large for key size"}, {ERR_PACK(0, 0, QAT_R_DEC_OP_DATA_MALLOC_FAILURE), "dec op data malloc failure"}, {ERR_PACK(0, 0, QAT_R_DERIVE_FAILURE), "derive failure"}, {ERR_PACK(0, 0, QAT_R_DGSTLEN_INVALID), "dgstlen invalid"}, {ERR_PACK(0, 0, QAT_R_DGST_BN_CONV_FAILURE), "dgst bn conv failure"}, {ERR_PACK(0, 0, QAT_R_DH_NULL), "dh null"}, {ERR_PACK(0, 0, QAT_R_DINIT_OPERATION_FAILED), "dinit operation failed"}, {ERR_PACK(0, 0, QAT_R_DLEN_INVALID), "dlen invalid"}, {ERR_PACK(0, 0, QAT_R_DSA_DGST_NULL), "dsa dgst null"}, {ERR_PACK(0, 0, QAT_R_DSA_DGST_SIG_NULL), "dsa dgst sig null"}, {ERR_PACK(0, 0, QAT_R_ECDH_GET_AFFINE_COORD_FAILED), "ecdh get affine coord failed"}, {ERR_PACK(0, 0, QAT_R_ECDH_GROUP_NULL), "ecdh group null"}, {ERR_PACK(0, 0, QAT_R_ECDH_PRIVATE_KEY_NULL), "ecdh private key null"}, {ERR_PACK(0, 0, QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL), "ecdh priv key pub key null"}, {ERR_PACK(0, 0, QAT_R_ECDH_SET_AFFINE_COORD_FAILED), "ecdh set affine coord failed"}, {ERR_PACK(0, 0, QAT_R_ECDH_UNKNOWN_FIELD_TYPE), "ecdh unknown field type"}, {ERR_PACK(0, 0, QAT_R_ECDSA_MALLOC_FAILURE), "ecdsa malloc failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIGN_FAILURE), "ecdsa sign failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIGN_NULL), "ecdsa sign null"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIGN_SETUP_FAILURE), "ecdsa sign setup failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIG_MALLOC_FAILURE), "ecdsa sig malloc failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_SIG_SET_R_S_FAILURE), "ecdsa sig set r s failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_VERIFY_FAILURE), "ecdsa verify failure"}, {ERR_PACK(0, 0, QAT_R_ECDSA_VERIFY_NULL), "ecdsa verify null"}, {ERR_PACK(0, 0, QAT_R_ECKEY_GROUP_PUBKEY_SIG_NULL), "eckey group pubkey sig null"}, {ERR_PACK(0, 0, QAT_R_EC_KEY_GROUP_PRIV_KEY_NULL), "ec key group priv key null"}, {ERR_PACK(0, 0, QAT_R_EC_LIB), "ec lib"}, {ERR_PACK(0, 0, QAT_R_EC_POINT_RETRIEVE_FAILURE), "ec point retrieve failure"}, {ERR_PACK(0, 0, QAT_R_EINIT_OPERATION_FAILED), "einit operation failed"}, {ERR_PACK(0, 0, QAT_R_ENC_OP_DATA_MALLOC_FAILURE), "enc op data malloc failure"}, {ERR_PACK(0, 0, QAT_R_ENGINE_CTRL_CMD_FAILURE), "engine ctrl cmd failure"}, {ERR_PACK(0, 0, QAT_R_ENGINE_INIT_FAILURE), "engine init failure"}, {ERR_PACK(0, 0, QAT_R_ENGINE_NULL), "engine null"}, {ERR_PACK(0, 0, QAT_R_EPOLL_CREATE_FAILURE), "epoll create failure"}, {ERR_PACK(0, 0, QAT_R_EPOLL_CTL_FAILURE), "epoll ctl failure"}, {ERR_PACK(0, 0, QAT_R_EVENTS_MALLOC_FAILURE), "events malloc failure"}, {ERR_PACK(0, 0, QAT_R_EVP_LIB), "evp lib"}, {ERR_PACK(0, 0, QAT_R_FAILED_TO_DECRYPT), "failed to decrypt"}, {ERR_PACK(0, 0, QAT_R_FAILED_TO_GET_PARAMETER), "failed to get parameter"}, {ERR_PACK(0, 0, QAT_R_FAILED_TO_SET_PARAMETER), "failed to set parameter"}, {ERR_PACK(0, 0, QAT_R_FALLBACK_INIT_FAILURE), "fallback init failure"}, {ERR_PACK(0, 0, QAT_R_FALLBACK_POINTER_NULL), "fallback pointer null"}, {ERR_PACK(0, 0, QAT_R_FIELD_SIZE_INVALID), "field size invalid"}, {ERR_PACK(0, 0, QAT_R_FREE_DH_METH_FAILURE), "free dh meth failure"}, {ERR_PACK(0, 0, QAT_R_FREE_MULTIBUFF_RSA_METH_FAILURE), "free multibuff rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_FREE_QAT_DSA_METH_FAILURE), "free qat dsa meth failure"}, {ERR_PACK(0, 0, QAT_R_FREE_QAT_RSA_METH_FAILURE), "free qat rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_GCM_TAG_VERIFY_FAILURE), "gcm tag verify failure"}, {ERR_PACK(0, 0, QAT_R_GET_COFACTOR_FAILURE), "get cofactor failure"}, {ERR_PACK(0, 0, QAT_R_GET_FILE_DESCRIPTOR_FAILURE), "get file descriptor failure"}, {ERR_PACK(0, 0, QAT_R_GET_GROUP_FAILURE), "get group failure"}, {ERR_PACK(0, 0, QAT_R_GET_INSTANCE_FAILURE), "get instance failure"}, {ERR_PACK(0, 0, QAT_R_GET_INSTANCE_INFO_FAILURE), "get instance info failure"}, {ERR_PACK(0, 0, QAT_R_GET_NUM_INSTANCE_FAILURE), "get num instance failure"}, {ERR_PACK(0, 0, QAT_R_GET_ORDER_FAILURE), "get order failure"}, {ERR_PACK(0, 0, QAT_R_GET_PQG_FAILURE), "get pqg failure"}, {ERR_PACK(0, 0, QAT_R_GET_PRIV_KEY_FAILURE), "get priv key failure"}, {ERR_PACK(0, 0, QAT_R_GROUP_NULL), "group null"}, {ERR_PACK(0, 0, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL), "group priv key pub key null"}, {ERR_PACK(0, 0, QAT_R_GROUP_PUB_KEY_NULL), "group pub key null"}, {ERR_PACK(0, 0, QAT_R_H_CONVERT_TO_FB_FAILURE), "h convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_ICP_SAL_USERSTART_FAIL), "icp sal userstart fail"}, {ERR_PACK(0, 0, QAT_R_ID_TOO_LARGE), "id too large"}, {ERR_PACK(0, 0, QAT_R_INITIALIZE_CTX_FAILURE), "initialize ctx failure"}, {ERR_PACK(0, 0, QAT_R_INIT_FAIL), "init fail"}, {ERR_PACK(0, 0, QAT_R_INIT_FAILURE), "init failure"}, {ERR_PACK(0, 0, QAT_R_INPUT_DATA_MALLOC_FAILURE), "input data malloc failure"}, {ERR_PACK(0, 0, QAT_R_INPUT_PARAM_INVALID), "input param invalid"}, {ERR_PACK(0, 0, QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE), "instance handle malloc failure"}, {ERR_PACK(0, 0, QAT_R_INSTANCE_UNAVAILABLE), "instance unavailable"}, {ERR_PACK(0, 0, QAT_R_INTERNAL_ERROR), "internal error"}, {ERR_PACK(0, 0, QAT_R_INVALID_AAD), "invalid aad"}, {ERR_PACK(0, 0, QAT_R_INVALID_ATTACHED_TAG), "invalid attached tag"}, {ERR_PACK(0, 0, QAT_R_INVALID_CTRL_TYPE), "invalid ctrl type"}, {ERR_PACK(0, 0, QAT_R_INVALID_CURVE), "invalid curve"}, {ERR_PACK(0, 0, QAT_R_INVALID_DATA), "invalid data"}, {ERR_PACK(0, 0, QAT_R_INVALID_DIGEST), "invalid digest"}, {ERR_PACK(0, 0, QAT_R_INVALID_HASH_DATA), "invalid hash data"}, {ERR_PACK(0, 0, QAT_R_INVALID_INPUT), "invalid input"}, {ERR_PACK(0, 0, QAT_R_INVALID_INPUT_LENGTH), "invalid input length"}, {ERR_PACK(0, 0, QAT_R_INVALID_INPUT_PARAMETER), "invalid input parameter"}, {ERR_PACK(0, 0, QAT_R_INVALID_IVLEN), "invalid ivlen"}, {ERR_PACK(0, 0, QAT_R_INVALID_IV_LENGTH), "invalid iv length"}, {ERR_PACK(0, 0, QAT_R_INVALID_KEY), "invalid key"}, {ERR_PACK(0, 0, QAT_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_PACK(0, 0, QAT_R_INVALID_L), "invalid l"}, {ERR_PACK(0, 0, QAT_R_INVALID_LEN), "invalid len"}, {ERR_PACK(0, 0, QAT_R_INVALID_LENGTH), "invalid length"}, {ERR_PACK(0, 0, QAT_R_INVALID_PEER_KEY), "invalid peer key"}, {ERR_PACK(0, 0, QAT_R_INVALID_PRIVATE_KEY), "invalid private key"}, {ERR_PACK(0, 0, QAT_R_INVALID_PTR), "invalid ptr"}, {ERR_PACK(0, 0, QAT_R_INVALID_PTR_IV), "invalid ptr iv"}, {ERR_PACK(0, 0, QAT_R_INVALID_PUB_KEY), "invalid pub key"}, {ERR_PACK(0, 0, QAT_R_INVALID_QCTX_MEMORY), "invalid qctx memory"}, {ERR_PACK(0, 0, QAT_R_INVALID_TAG), "invalid tag"}, {ERR_PACK(0, 0, QAT_R_INVALID_TAG_LEN), "invalid tag len"}, {ERR_PACK(0, 0, QAT_R_INVALID_TYPE), "invalid type"}, {ERR_PACK(0, 0, QAT_R_IN_KINV_CONVERT_TO_FB_FAILURE), "in kinv convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_IN_R_CONVERT_TO_FB_FAILURE), "in r convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_IPSEC_MGR_NULL), "ipsec mgr null"}, {ERR_PACK(0, 0, QAT_R_IV_ALLOC_FAILURE), "iv alloc failure"}, {ERR_PACK(0, 0, QAT_R_IV_GEN_INVALID), "iv gen invalid"}, {ERR_PACK(0, 0, QAT_R_IV_INVALID), "iv invalid"}, {ERR_PACK(0, 0, QAT_R_IV_LEN_NOT_SUPPORTED), "iv len not supported"}, {ERR_PACK(0, 0, QAT_R_IV_MALLOC_FAILURE), "iv malloc failure"}, {ERR_PACK(0, 0, QAT_R_IV_NOTSET), "iv notset"}, {ERR_PACK(0, 0, QAT_R_IV_NULL_PTR_INVALID), "iv null ptr invalid"}, {ERR_PACK(0, 0, QAT_R_IV_NVALID), "iv nvalid"}, {ERR_PACK(0, 0, QAT_R_KEYGEN_FAILURE), "keygen failure"}, {ERR_PACK(0, 0, QAT_R_KEYS_NOT_SET), "keys not set"}, {ERR_PACK(0, 0, QAT_R_KEY_IV_NOT_SET), "key iv not set"}, {ERR_PACK(0, 0, QAT_R_KEY_MALLOC_FAILURE), "key malloc failure"}, {ERR_PACK(0, 0, QAT_R_KEY_NOTSET), "key notset"}, {ERR_PACK(0, 0, QAT_R_KEY_NULL), "key null"}, {ERR_PACK(0, 0, QAT_R_KEY_SIZE_TOO_SMALL), "key size too small"}, {ERR_PACK(0, 0, QAT_R_K_ALLOCATE_FAILURE), "k allocate failure"}, {ERR_PACK(0, 0, QAT_R_K_CONVERT_TO_FB_FAILURE), "k convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_K_E_ORDER_MALLOC_FAILURE), "k e order malloc failure"}, {ERR_PACK(0, 0, QAT_R_K_ORDER_CONVERT_TO_FB_FAILURE), "k order convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_K_RAND_GENERATE_FAILURE), "k rand generate failure"}, {ERR_PACK(0, 0, QAT_R_M1_DEDUCT_M2_FAILURE), "m1 deduct m2 failure"}, {ERR_PACK(0, 0, QAT_R_M1_M2_P_Q_QINV_TMP_MALLOC_FAILURE), "m1 m2 p q qinv tmp malloc failure"}, {ERR_PACK(0, 0, QAT_R_MALLOC_FAILURE), "malloc failure"}, {ERR_PACK(0, 0, QAT_R_MAX_RETRIES_EXCEEDED), "max retries exceeded"}, {ERR_PACK(0, 0, QAT_R_MB_FREE_EC_METHOD_FAILURE), "mb free ec method failure"}, {ERR_PACK(0, 0, QAT_R_MB_GET_EC_METHOD_MALLOC_FAILURE), "mb get ec method malloc failure"}, {ERR_PACK(0, 0, QAT_R_MODULO_P_FAILURE), "modulo p failure"}, {ERR_PACK(0, 0, QAT_R_MOD_GET_NEXT_INST_FAIL), "mod get next inst fail"}, {ERR_PACK(0, 0, QAT_R_MOD_LN_MOD_EXP_FAIL), "mod ln mod exp fail"}, {ERR_PACK(0, 0, QAT_R_MOD_SETUP_ASYNC_EVENT_FAIL), "mod setup async event fail"}, {ERR_PACK(0, 0, QAT_R_MSGLEN_NOTSET), "msglen notset"}, {ERR_PACK(0, 0, QAT_R_MULTIPLY_QINV_FAILURE), "multiply qinv failure"}, {ERR_PACK(0, 0, QAT_R_NID_NOT_SUPPORTED), "nid not supported"}, {ERR_PACK(0, 0, QAT_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_PACK(0, 0, QAT_R_N_E_CONVERT_TO_FB_FAILURE), "n e convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_N_E_NULL), "n e null"}, {ERR_PACK(0, 0, QAT_R_OP1_BASE_PDATA_MALLOC_FAILURE), "op1 base pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OP2_BASE_PDATA_MALLOC_FAILURE), "op2 base pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_A_PDATA_MALLOC_FAILURE), "opdata a pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_DATA_MALLOC_FAILURE), "opdata data malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_D_MALLOC_FAILURE), "opdata d malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_E_MALLOC_FAILURE), "opdata e malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_K_MALLOC_FAILURE), "opdata k malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_MALLOC_FAILURE), "opdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_PDATA_MALLOC_FAILURE), "opdata pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDATA_ZPDATA_MALLOC_FAILURE), "opdata zpdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OPDCRT_NULL), "opdcrt null"}, {ERR_PACK(0, 0, QAT_R_OPDONE_NULL), "opdone null"}, {ERR_PACK(0, 0, QAT_R_OPDPIPE_NULL), "opdpipe null"}, {ERR_PACK(0, 0, QAT_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"}, {ERR_PACK(0, 0, QAT_R_ORDER_MALLOC_FAILURE), "order malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUT1_PDATA_MALLOC_FAILURE), "out1 pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUT2_PDATA_MALLOC_FAILURE), "out2 pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTPUT_BUFFER_TOO_SMALL), "output buffer too small"}, {ERR_PACK(0, 0, QAT_R_OUTPUT_BUF_MALLOC_FAILURE), "output buf malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE), "output buf pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTX_MALLOC_FAILURE), "outx malloc failure"}, {ERR_PACK(0, 0, QAT_R_OUTX_OUTY_LEN_NULL), "outx outy len null"}, {ERR_PACK(0, 0, QAT_R_OUTY_MALLOC_FAILURE), "outy malloc failure"}, {ERR_PACK(0, 0, QAT_R_PADDING_UNKNOWN), "padding unknown"}, {ERR_PACK(0, 0, QAT_R_PKCS_DECODING_ERROR), "pkcs decoding error"}, {ERR_PACK(0, 0, QAT_R_POLLING_THREAD_CREATE_FAILURE), "polling thread create failure"}, {ERR_PACK(0, 0, QAT_R_POLLING_THREAD_SEM_INIT_FAILURE), "polling thread sem init failure"}, {ERR_PACK(0, 0, QAT_R_POLLING_THREAD_SIGMASK_FAILURE), "polling thread sigmask failure"}, {ERR_PACK(0, 0, QAT_R_POLL_INSTANCE_FAILURE), "poll instance failure"}, {ERR_PACK(0, 0, QAT_R_POPDATA_A_PDATA_MALLOC_FAILURE), "popdata a pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_POPDATA_MALLOC_FAILURE), "popdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_POPDATA_PCURVE_MALLOC_FAILURE), "popdata pcurve malloc failure"}, {ERR_PACK(0, 0, QAT_R_PPV_MALLOC_FAILURE), "ppv malloc failure"}, {ERR_PACK(0, 0, QAT_R_PPV_PDATA_MALLOC_FAILURE), "ppv pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTR_MALLOC_FAILURE), "presultr malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTR_PDATA_MALLOC_FAILURE), "presultr pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTS_MALLOC_FAILURE), "presults malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTS_PDATA_MALLOC_FAILURE), "presults pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTX_MALLOC_FAILURE), "presultx malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTX_PDATA_MALLOC_FAILURE), "presultx pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTY_LENGTH_CHECK_FAILURE), "presulty length check failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTY_MALLOC_FAILURE), "presulty malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRESULTY_PDATA_MALLOC_FAILURE), "presulty pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_DUPLICATE_FAILURE), "priv key duplicate failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE), "priv key k e d convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_MALLOC_FAILURE), "priv key malloc failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_M_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE), "priv key m xg yg a b p convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_NULL), "priv key null"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE), "priv key rand generate failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE), "priv key xg yg a b p convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PRIV_KEY_XP_YP_A_B_P_CONVERT_TO_FB_FAILURE), "priv key xp yp a b p convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_CREATE_FAILURE), "pthread create failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_GETAFFINITY_FAILURE), "pthread getaffinity failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_JOIN_FAILURE), "pthread join failure"}, {ERR_PACK(0, 0, QAT_R_PTHREAD_SETAFFINITY_FAILURE), "pthread setaffinity failure"}, {ERR_PACK(0, 0, QAT_R_PUB_KEY_DUPLICATE_FAILURE), "pub key duplicate failure"}, {ERR_PACK(0, 0, QAT_R_PUB_KEY_MALLOC_FAILURE), "pub key malloc failure"}, {ERR_PACK(0, 0, QAT_R_PUB_KEY_NULL), "pub key null"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XG_YG_MALLOC_FAILURE), "p a b xg yg malloc failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XG_YG_M_K_R_ORDER_MALLOC_FAILURE), "p a b xg yg m k r order malloc failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XG_YG_XP_YP_M_ORDER_FAILURE), "p a b xg yg xp yp m order failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XP_YP_FAILURE), "p a b xp yp failure"}, {ERR_PACK(0, 0, QAT_R_P_A_B_XP_YP_MALLOC_FAILURE), "p a b xp yp malloc failure"}, {ERR_PACK(0, 0, QAT_R_P_G_PRIV_KEY_CONVERT_TO_FB_FAILURE), "p g priv key convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_PUB_PRIV_KEY_CONVERT_TO_FB_FAILURE), "p pub priv key convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE), "p q dmp dmq convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_Q_DMP_DMQ_IQMP_NULL), "p q dmp dmq iqmp null"}, {ERR_PACK(0, 0, QAT_R_P_Q_G_NULL), "p q g null"}, {ERR_PACK(0, 0, QAT_R_P_Q_G_X_K_CONVERT_TO_FB_FAILURE), "p q g x k convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_P_Q_G_Y_Z_R_S_CONVERT_TO_FB_FAILURE), "p q g y z r s convert to fb failure"}, {ERR_PACK(0, 0, QAT_R_QAT_ALLOC_DH_METH_FAILURE), "qat alloc dh meth failure"}, {ERR_PACK(0, 0, QAT_R_QAT_CREATE_ENGINE_FAILURE), "qat create engine failure"}, {ERR_PACK(0, 0, QAT_R_QAT_ECDSA_DO_SIGN_FAIL), "qat ecdsa do sign fail"}, {ERR_PACK(0, 0, QAT_R_QAT_FREE_EC_METHOD_FAILURE), "qat free ec method failure"}, {ERR_PACK(0, 0, QAT_R_QAT_GET_EC_METHOD_MALLOC_FAILURE), "qat get ec method malloc failure"}, {ERR_PACK(0, 0, QAT_R_QAT_SET_DH_METH_FAILURE), "qat set dh meth failure"}, {ERR_PACK(0, 0, QAT_R_QCTX_CTX_NULL), "qctx ctx null"}, {ERR_PACK(0, 0, QAT_R_QCTX_NULL), "qctx null"}, {ERR_PACK(0, 0, QAT_R_RAND_BYTES_FAILURE), "rand bytes failure"}, {ERR_PACK(0, 0, QAT_R_RAND_FAILURE), "rand failure"}, {ERR_PACK(0, 0, QAT_R_RAND_GENERATE_FAILURE), "rand generate failure"}, {ERR_PACK(0, 0, QAT_R_RESULT_PDATA_ALLOC_FAIL), "result pdata alloc fail"}, {ERR_PACK(0, 0, QAT_R_RETRIEVE_EC_POINT_FAILURE), "retrieve ec point failure"}, {ERR_PACK(0, 0, QAT_R_RETRIEVE_ORDER_FAILURE), "retrieve order failure"}, {ERR_PACK(0, 0, QAT_R_RSA_FROM_TO_NULL), "rsa from to null"}, {ERR_PACK(0, 0, QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE), "rsa output buf pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_R_Q_COMPARE_FAILURE), "r q compare failure"}, {ERR_PACK(0, 0, QAT_R_SECRET_KEY_MALLOC_FAILURE), "secret key malloc failure"}, {ERR_PACK(0, 0, QAT_R_SECRET_KEY_PDATA_MALLOC_FAILURE), "secret key pdata malloc failure"}, {ERR_PACK(0, 0, QAT_R_SEM_POST_FAILURE), "sem post failure"}, {ERR_PACK(0, 0, QAT_R_SETUP_ASYNC_EVENT_FAILURE), "setup async event failure"}, {ERR_PACK(0, 0, QAT_R_SET_ADDRESS_TRANSLATION_FAILURE), "set address translation failure"}, {ERR_PACK(0, 0, QAT_R_SET_FILE_DESCRIPTOR_NONBLOCKING_FAILURE), "set file descriptor nonblocking failure"}, {ERR_PACK(0, 0, QAT_R_SET_INSTANCE_FAILURE), "set instance failure"}, {ERR_PACK(0, 0, QAT_R_SET_MULTIBUFF_RSA_METH_FAILURE), "set multibuff rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_SET_NOTIFICATION_CALLBACK_FAILURE), "set notification callback failure"}, {ERR_PACK(0, 0, QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE), "set polling thread affinity failure"}, {ERR_PACK(0, 0, QAT_R_SET_PRIV_KEY_FAILURE), "set priv key failure"}, {ERR_PACK(0, 0, QAT_R_SET_QAT_DSA_METH_FAILURE), "set qat dsa meth failure"}, {ERR_PACK(0, 0, QAT_R_SET_QAT_RSA_METH_FAILURE), "set qat rsa meth failure"}, {ERR_PACK(0, 0, QAT_R_SET_TAG_INVALID_OP), "set tag invalid op"}, {ERR_PACK(0, 0, QAT_R_SHA3_CTX_NULL), "sha3 ctx null"}, {ERR_PACK(0, 0, QAT_R_SIG_GET_R_S_FAILURE), "sig get r s failure"}, {ERR_PACK(0, 0, QAT_R_SIG_MALLOC_FAILURE), "sig malloc failure"}, {ERR_PACK(0, 0, QAT_R_SM2_BAD_SIGNATURE), "sm2 bad signature"}, {ERR_PACK(0, 0, QAT_R_SM2_ID_TOO_LARGE), "sm2 id too large"}, {ERR_PACK(0, 0, QAT_R_SM2_INVALID_DIGEST), "sm2 invalid digest"}, {ERR_PACK(0, 0, QAT_R_SM2_SIGN_NULL), "sm2 sign null"}, {ERR_PACK(0, 0, QAT_R_SM2_SIG_GEN_MALLOC_FAILURE), "sm2 sig gen malloc failure"}, {ERR_PACK(0, 0, QAT_R_SM2_SIG_MALLOC_FAILURE), "sm2 sig malloc failure"}, {ERR_PACK(0, 0, QAT_R_SM2_SIG_SET_R_S_FAILURE), "sm2 sig set r s failure"}, {ERR_PACK(0, 0, QAT_R_SM2_VERIFY_NULL), "sm2 verify null"}, {ERR_PACK(0, 0, QAT_R_SM3_CTX_NULL), "sm3 ctx null"}, {ERR_PACK(0, 0, QAT_R_SM3_FINAL_FAILURE), "sm3 final failure"}, {ERR_PACK(0, 0, QAT_R_SM3_INIT_FAILURE), "sm3 init failure"}, {ERR_PACK(0, 0, QAT_R_SM3_UPDATE_FAILURE), "sm3 update failure"}, {ERR_PACK(0, 0, QAT_R_SM4_CCM_DECRYPT_FAILURE), "sm4 ccm decrypt failure"}, {ERR_PACK(0, 0, QAT_R_SM4_GCM_DECRYPT_FAILURE), "sm4 gcm decrypt failure"}, {ERR_PACK(0, 0, QAT_R_SM4_GCM_ENCRYPT_FAILURE), "sm4 gcm encrypt failure"}, {ERR_PACK(0, 0, QAT_R_SM4_GET_INSTANCE_FAILED), "sm4 get instance failed"}, {ERR_PACK(0, 0, QAT_R_SM4_GET_SESSIONCTX_SIZE_FAILED), "sm4 get sessionctx size failed"}, {ERR_PACK(0, 0, QAT_R_SM4_MALLOC_FAILED), "sm4 malloc failed"}, {ERR_PACK(0, 0, QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE), "sm4 no qat instance available"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_CKEY), "sm4 null ckey"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_CTX), "sm4 null ctx"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_CTX_OR_KEY), "sm4 null ctx or key"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_POINTER), "sm4 null pointer"}, {ERR_PACK(0, 0, QAT_R_SM4_NULL_QCTX), "sm4 null qctx"}, {ERR_PACK(0, 0, QAT_R_SM4_QAT_CONTEXT_NOT_INITIALISED), "sm4 qat context not initialised"}, {ERR_PACK(0, 0, QAT_R_SM4_QAT_INITSESSION_FAILED), "sm4 qat initsession failed"}, {ERR_PACK(0, 0, QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED), "sm4 qat submit request failed"}, {ERR_PACK(0, 0, QAT_R_SM4_REMOVE_SESSION_FAILED), "sm4 remove session failed"}, {ERR_PACK(0, 0, QAT_R_SM4_SETUP_META_DATA_FAILED), "sm4 setup meta data failed"}, {ERR_PACK(0, 0, QAT_R_SM4_SET_METHODS_FAILED), "sm4 set methods failed"}, {ERR_PACK(0, 0, QAT_R_SSD_MALLOC_FAILURE), "ssd malloc failure"}, {ERR_PACK(0, 0, QAT_R_SSD_NULL), "ssd null"}, {ERR_PACK(0, 0, QAT_R_START_INSTANCE_FAILURE), "start instance failure"}, {ERR_PACK(0, 0, QAT_R_STOP_INSTANCE_FAILURE), "stop instance failure"}, {ERR_PACK(0, 0, QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL), "sw get compute key pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_KEYGEN_PFUNC_NULL), "sw get keygen pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_SIGN_PFUNC_NULL), "sw get sign pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_SIGN_SETUP_PFUNC_NULL), "sw get sign setup pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL), "sw get sign sig pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_VERIFY_PFUNC_NULL), "sw get verify pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_GET_VERIFY_SIG_PFUNC_NULL), "sw get verify sig pfunc null"}, {ERR_PACK(0, 0, QAT_R_SW_METHOD_NULL), "sw method null"}, {ERR_PACK(0, 0, QAT_R_S_NULL), "s null"}, {ERR_PACK(0, 0, QAT_R_S_Q_COMPARE_FAILURE), "s q compare failure"}, {ERR_PACK(0, 0, QAT_R_TAG_NOTSET), "tag notset"}, {ERR_PACK(0, 0, QAT_R_TAG_NOT_NEEDED), "tag not needed"}, {ERR_PACK(0, 0, QAT_R_UNKNOWN_PADDING), "unknown padding"}, {ERR_PACK(0, 0, QAT_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, {ERR_PACK(0, 0, QAT_R_WAKE_PAUSE_JOB_FAILURE), "wake pause job failure"}, {ERR_PACK(0, 0, QAT_R_X_Y_E_MALLOC_FAILURE), "x y e malloc failure"}, {ERR_PACK(0, 0, QAT_R_X_Y_TX_TY_BN_MALLOC_FAILURE), "x y tx ty bn malloc failure"}, {ERR_PACK(0, 0, QAT_R_X_Y_Z_MALLOC_FAILURE), "x y z malloc failure"}, {ERR_PACK(0, 0, QAT_R_ZALLOC_FAILURE), "zalloc failure"}, {ERR_PACK(0, 0, QAT_R_Z_ALLOCATE_FAILURE), "z allocate failure"}, {0, NULL} }; #endif static int lib_code = 0; static int error_loaded = 0; int ERR_load_QAT_strings(void) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); if (!error_loaded) { #ifndef OPENSSL_NO_ERR ERR_load_strings(lib_code, QAT_str_reasons); #endif error_loaded = 1; } return 1; } void ERR_unload_QAT_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR ERR_unload_strings(lib_code, QAT_str_reasons); #endif error_loaded = 0; } } void ERR_QAT_error(int function, int reason, const char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); ERR_raise(lib_code, reason); ERR_set_debug(file, line, NULL); } qatengine-1.9.0/qat_err.h000066400000000000000000000516561500416242000153110ustar00rootroot00000000000000/* * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #ifndef OSSL_QAT_ERR_H # define OSSL_QAT_ERR_H # pragma once # include # include # define QATerr(f, r) ERR_QAT_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) # ifdef __cplusplus extern "C" { # endif int ERR_load_QAT_strings(void); void ERR_unload_QAT_strings(void); void ERR_QAT_error(int function, int reason, const char *file, int line); # ifdef __cplusplus } # endif /* * QAT reason codes. */ # define QAT_R_AAD_INVALID_PTR 100 # define QAT_R_AAD_LEN_INVALID 101 # define QAT_R_AAD_MALLOC_FAILURE 102 # define QAT_R_ADD_M2_FAILURE 103 # define QAT_R_ADJUST_DELTA_M1_M2_FAILURE 104 # define QAT_R_ALGO_TYPE_SUPPORTED 105 # define QAT_R_ALGO_TYPE_UNSUPPORTED 106 # define QAT_R_ALLOC_E_CHECK_FAILURE 107 # define QAT_R_ALLOC_MULTIBUFF_RSA_METH_FAILURE 108 # define QAT_R_ALLOC_QAT_DSA_METH_FAILURE 109 # define QAT_R_ALLOC_QAT_RSA_METH_FAILURE 110 # define QAT_R_ALLOC_QAT_X25519_METH_FAILURE 111 # define QAT_R_ALLOC_QAT_X448_METH_FAILURE 112 # define QAT_R_ALLOC_TAG_FAILURE 113 # define QAT_R_BAD_INPUT_PARAMS 114 # define QAT_R_BAD_LENGTH 115 # define QAT_R_BAD_TLS_CLIENT_VERSION 116 # define QAT_R_BN_LIB_FAILURE 117 # define QAT_R_BUFFER_TOO_SMALL 118 # define QAT_R_BUF_CONV_FAIL 119 # define QAT_R_CAPABILITY_FAILURE 120 # define QAT_R_CBC_OPERATION_FAILED 121 # define QAT_R_CHACHAPOLY_CTX_NULL 122 # define QAT_R_CIPHER_DATA_NULL 123 # define QAT_R_CIPHER_OPERATION_FAILED 124 # define QAT_R_CLOSE_READFD_FAILURE 125 # define QAT_R_COMPUTE_FAILURE 126 # define QAT_R_COMPUTE_H_MULTIPLY_Q_FAILURE 127 # define QAT_R_CP_BUF_MALLOC_FAILURE 128 # define QAT_R_CQ_BUF_MALLOC_FAILURE 129 # define QAT_R_CREATE_FREELIST_QUEUE_FAILURE 130 # define QAT_R_CTX_MALLOC_FAILURE 131 # define QAT_R_CTX_NULL 132 # define QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE 133 # define QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING 134 # define QAT_R_C_MODULO_P_FAILURE 135 # define QAT_R_C_MODULO_Q_FAILURE 136 # define QAT_R_C_P_Q_CP_CQ_MALLOC_FAILURE 137 # define QAT_R_DATA_TOO_LARGE_FOR_KEY_SIZE 138 # define QAT_R_DEC_OP_DATA_MALLOC_FAILURE 139 # define QAT_R_DERIVE_FAILURE 140 # define QAT_R_DGSTLEN_INVALID 141 # define QAT_R_DGST_BN_CONV_FAILURE 142 # define QAT_R_DH_NULL 143 # define QAT_R_DINIT_OPERATION_FAILED 144 # define QAT_R_DLEN_INVALID 145 # define QAT_R_DSA_DGST_NULL 146 # define QAT_R_DSA_DGST_SIG_NULL 147 # define QAT_R_ECDH_GET_AFFINE_COORD_FAILED 148 # define QAT_R_ECDH_GROUP_NULL 149 # define QAT_R_ECDH_PRIVATE_KEY_NULL 150 # define QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL 151 # define QAT_R_ECDH_SET_AFFINE_COORD_FAILED 152 # define QAT_R_ECDH_UNKNOWN_FIELD_TYPE 153 # define QAT_R_ECDSA_MALLOC_FAILURE 154 # define QAT_R_ECDSA_SIGN_FAILURE 155 # define QAT_R_ECDSA_SIGN_NULL 156 # define QAT_R_ECDSA_SIGN_SETUP_FAILURE 157 # define QAT_R_ECDSA_SIG_MALLOC_FAILURE 158 # define QAT_R_ECDSA_SIG_SET_R_S_FAILURE 159 # define QAT_R_ECDSA_VERIFY_FAILURE 160 # define QAT_R_ECDSA_VERIFY_NULL 161 # define QAT_R_ECKEY_GROUP_PUBKEY_SIG_NULL 162 # define QAT_R_EC_KEY_GROUP_PRIV_KEY_NULL 163 # define QAT_R_EC_LIB 164 # define QAT_R_EC_POINT_RETRIEVE_FAILURE 165 # define QAT_R_EINIT_OPERATION_FAILED 166 # define QAT_R_ENC_OP_DATA_MALLOC_FAILURE 167 # define QAT_R_ENGINE_CTRL_CMD_FAILURE 168 # define QAT_R_ENGINE_INIT_FAILURE 169 # define QAT_R_ENGINE_NULL 170 # define QAT_R_EPOLL_CREATE_FAILURE 171 # define QAT_R_EPOLL_CTL_FAILURE 172 # define QAT_R_EVENTS_MALLOC_FAILURE 173 # define QAT_R_EVP_LIB 174 # define QAT_R_FAILED_TO_DECRYPT 175 # define QAT_R_FAILED_TO_GET_PARAMETER 176 # define QAT_R_FAILED_TO_SET_PARAMETER 177 # define QAT_R_FALLBACK_INIT_FAILURE 178 # define QAT_R_FALLBACK_POINTER_NULL 179 # define QAT_R_FIELD_SIZE_INVALID 180 # define QAT_R_FREE_DH_METH_FAILURE 181 # define QAT_R_FREE_MULTIBUFF_RSA_METH_FAILURE 182 # define QAT_R_FREE_QAT_DSA_METH_FAILURE 183 # define QAT_R_FREE_QAT_RSA_METH_FAILURE 184 # define QAT_R_GCM_TAG_VERIFY_FAILURE 185 # define QAT_R_GET_COFACTOR_FAILURE 186 # define QAT_R_GET_FILE_DESCRIPTOR_FAILURE 187 # define QAT_R_GET_GROUP_FAILURE 188 # define QAT_R_GET_INSTANCE_FAILURE 189 # define QAT_R_GET_INSTANCE_INFO_FAILURE 190 # define QAT_R_GET_NUM_INSTANCE_FAILURE 191 # define QAT_R_GET_ORDER_FAILURE 192 # define QAT_R_GET_PQG_FAILURE 193 # define QAT_R_GET_PRIV_KEY_FAILURE 194 # define QAT_R_GROUP_NULL 195 # define QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL 196 # define QAT_R_GROUP_PUB_KEY_NULL 197 # define QAT_R_H_CONVERT_TO_FB_FAILURE 198 # define QAT_R_ICP_SAL_USERSTART_FAIL 199 # define QAT_R_ID_TOO_LARGE 200 # define QAT_R_INITIALIZE_CTX_FAILURE 201 # define QAT_R_INIT_FAIL 202 # define QAT_R_INIT_FAILURE 203 # define QAT_R_INPUT_DATA_MALLOC_FAILURE 204 # define QAT_R_INPUT_PARAM_INVALID 205 # define QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE 206 # define QAT_R_INSTANCE_UNAVAILABLE 207 # define QAT_R_INTERNAL_ERROR 208 # define QAT_R_INVALID_AAD 209 # define QAT_R_INVALID_ATTACHED_TAG 210 # define QAT_R_INVALID_CTRL_TYPE 211 # define QAT_R_INVALID_CURVE 212 # define QAT_R_INVALID_DATA 213 # define QAT_R_INVALID_DIGEST 214 # define QAT_R_INVALID_HASH_DATA 215 # define QAT_R_INVALID_INPUT 216 # define QAT_R_INVALID_INPUT_LENGTH 217 # define QAT_R_INVALID_INPUT_PARAMETER 218 # define QAT_R_INVALID_IVLEN 219 # define QAT_R_INVALID_IV_LENGTH 220 # define QAT_R_INVALID_KEY 221 # define QAT_R_INVALID_KEY_LENGTH 222 # define QAT_R_INVALID_L 223 # define QAT_R_INVALID_LEN 224 # define QAT_R_INVALID_LENGTH 225 # define QAT_R_INVALID_PEER_KEY 226 # define QAT_R_INVALID_PRIVATE_KEY 227 # define QAT_R_INVALID_PTR 228 # define QAT_R_INVALID_PTR_IV 229 # define QAT_R_INVALID_PUB_KEY 230 # define QAT_R_INVALID_QCTX_MEMORY 231 # define QAT_R_INVALID_TAG 232 # define QAT_R_INVALID_TAG_LEN 233 # define QAT_R_INVALID_TYPE 234 # define QAT_R_IN_KINV_CONVERT_TO_FB_FAILURE 235 # define QAT_R_IN_R_CONVERT_TO_FB_FAILURE 236 # define QAT_R_IPSEC_MGR_NULL 237 # define QAT_R_IV_ALLOC_FAILURE 238 # define QAT_R_IV_GEN_INVALID 239 # define QAT_R_IV_INVALID 240 # define QAT_R_IV_LEN_NOT_SUPPORTED 241 # define QAT_R_IV_MALLOC_FAILURE 242 # define QAT_R_IV_NOTSET 243 # define QAT_R_IV_NULL_PTR_INVALID 244 # define QAT_R_IV_NVALID 245 # define QAT_R_KEYGEN_FAILURE 246 # define QAT_R_KEYS_NOT_SET 247 # define QAT_R_KEY_IV_NOT_SET 248 # define QAT_R_KEY_MALLOC_FAILURE 249 # define QAT_R_KEY_NOTSET 250 # define QAT_R_KEY_NULL 251 # define QAT_R_KEY_SIZE_TOO_SMALL 252 # define QAT_R_K_ALLOCATE_FAILURE 253 # define QAT_R_K_CONVERT_TO_FB_FAILURE 254 # define QAT_R_K_E_ORDER_MALLOC_FAILURE 255 # define QAT_R_K_ORDER_CONVERT_TO_FB_FAILURE 256 # define QAT_R_K_RAND_GENERATE_FAILURE 257 # define QAT_R_M1_DEDUCT_M2_FAILURE 258 # define QAT_R_M1_M2_P_Q_QINV_TMP_MALLOC_FAILURE 259 # define QAT_R_MALLOC_FAILURE 260 # define QAT_R_MAX_RETRIES_EXCEEDED 261 # define QAT_R_MB_FREE_EC_METHOD_FAILURE 262 # define QAT_R_MB_GET_EC_METHOD_MALLOC_FAILURE 263 # define QAT_R_MODULO_P_FAILURE 264 # define QAT_R_MOD_GET_NEXT_INST_FAIL 265 # define QAT_R_MOD_LN_MOD_EXP_FAIL 266 # define QAT_R_MOD_SETUP_ASYNC_EVENT_FAIL 267 # define QAT_R_MSGLEN_NOTSET 268 # define QAT_R_MULTIPLY_QINV_FAILURE 269 # define QAT_R_NID_NOT_SUPPORTED 270 # define QAT_R_NO_PARAMETERS_SET 271 # define QAT_R_N_E_CONVERT_TO_FB_FAILURE 272 # define QAT_R_N_E_NULL 273 # define QAT_R_OP1_BASE_PDATA_MALLOC_FAILURE 274 # define QAT_R_OP2_BASE_PDATA_MALLOC_FAILURE 275 # define QAT_R_OPDATA_A_PDATA_MALLOC_FAILURE 276 # define QAT_R_OPDATA_DATA_MALLOC_FAILURE 277 # define QAT_R_OPDATA_D_MALLOC_FAILURE 278 # define QAT_R_OPDATA_E_MALLOC_FAILURE 279 # define QAT_R_OPDATA_K_MALLOC_FAILURE 280 # define QAT_R_OPDATA_MALLOC_FAILURE 281 # define QAT_R_OPDATA_PDATA_MALLOC_FAILURE 282 # define QAT_R_OPDATA_ZPDATA_MALLOC_FAILURE 283 # define QAT_R_OPDCRT_NULL 284 # define QAT_R_OPDONE_NULL 285 # define QAT_R_OPDPIPE_NULL 286 # define QAT_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 287 # define QAT_R_ORDER_MALLOC_FAILURE 288 # define QAT_R_OUT1_PDATA_MALLOC_FAILURE 289 # define QAT_R_OUT2_PDATA_MALLOC_FAILURE 290 # define QAT_R_OUTPUT_BUFFER_TOO_SMALL 291 # define QAT_R_OUTPUT_BUF_MALLOC_FAILURE 292 # define QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE 293 # define QAT_R_OUTX_MALLOC_FAILURE 294 # define QAT_R_OUTX_OUTY_LEN_NULL 295 # define QAT_R_OUTY_MALLOC_FAILURE 296 # define QAT_R_PADDING_UNKNOWN 297 # define QAT_R_PKCS_DECODING_ERROR 298 # define QAT_R_POLLING_THREAD_CREATE_FAILURE 299 # define QAT_R_POLLING_THREAD_SEM_INIT_FAILURE 300 # define QAT_R_POLLING_THREAD_SIGMASK_FAILURE 301 # define QAT_R_POLL_INSTANCE_FAILURE 302 # define QAT_R_POPDATA_A_PDATA_MALLOC_FAILURE 303 # define QAT_R_POPDATA_MALLOC_FAILURE 304 # define QAT_R_POPDATA_PCURVE_MALLOC_FAILURE 305 # define QAT_R_PPV_MALLOC_FAILURE 306 # define QAT_R_PPV_PDATA_MALLOC_FAILURE 307 # define QAT_R_PRESULTR_MALLOC_FAILURE 308 # define QAT_R_PRESULTR_PDATA_MALLOC_FAILURE 309 # define QAT_R_PRESULTS_MALLOC_FAILURE 310 # define QAT_R_PRESULTS_PDATA_MALLOC_FAILURE 311 # define QAT_R_PRESULTX_MALLOC_FAILURE 312 # define QAT_R_PRESULTX_PDATA_MALLOC_FAILURE 313 # define QAT_R_PRESULTY_LENGTH_CHECK_FAILURE 314 # define QAT_R_PRESULTY_MALLOC_FAILURE 315 # define QAT_R_PRESULTY_PDATA_MALLOC_FAILURE 316 # define QAT_R_PRIV_KEY_DUPLICATE_FAILURE 317 # define QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE 318 # define QAT_R_PRIV_KEY_MALLOC_FAILURE 319 # define QAT_R_PRIV_KEY_M_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE 320 # define QAT_R_PRIV_KEY_NULL 321 # define QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE 322 # define QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE 323 # define QAT_R_PRIV_KEY_XP_YP_A_B_P_CONVERT_TO_FB_FAILURE 324 # define QAT_R_PTHREAD_CREATE_FAILURE 325 # define QAT_R_PTHREAD_GETAFFINITY_FAILURE 326 # define QAT_R_PTHREAD_JOIN_FAILURE 327 # define QAT_R_PTHREAD_SETAFFINITY_FAILURE 328 # define QAT_R_PUB_KEY_DUPLICATE_FAILURE 329 # define QAT_R_PUB_KEY_MALLOC_FAILURE 330 # define QAT_R_PUB_KEY_NULL 331 # define QAT_R_P_A_B_XG_YG_MALLOC_FAILURE 332 # define QAT_R_P_A_B_XG_YG_M_K_R_ORDER_MALLOC_FAILURE 333 # define QAT_R_P_A_B_XG_YG_XP_YP_M_ORDER_FAILURE 334 # define QAT_R_P_A_B_XP_YP_FAILURE 335 # define QAT_R_P_A_B_XP_YP_MALLOC_FAILURE 336 # define QAT_R_P_G_PRIV_KEY_CONVERT_TO_FB_FAILURE 337 # define QAT_R_P_PUB_PRIV_KEY_CONVERT_TO_FB_FAILURE 338 # define QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE 339 # define QAT_R_P_Q_DMP_DMQ_IQMP_NULL 340 # define QAT_R_P_Q_G_NULL 341 # define QAT_R_P_Q_G_X_K_CONVERT_TO_FB_FAILURE 342 # define QAT_R_P_Q_G_Y_Z_R_S_CONVERT_TO_FB_FAILURE 343 # define QAT_R_QAT_ALLOC_DH_METH_FAILURE 344 # define QAT_R_QAT_CREATE_ENGINE_FAILURE 345 # define QAT_R_QAT_ECDSA_DO_SIGN_FAIL 346 # define QAT_R_QAT_FREE_EC_METHOD_FAILURE 347 # define QAT_R_QAT_GET_EC_METHOD_MALLOC_FAILURE 348 # define QAT_R_QAT_SET_DH_METH_FAILURE 349 # define QAT_R_QCTX_CTX_NULL 350 # define QAT_R_QCTX_NULL 351 # define QAT_R_RAND_BYTES_FAILURE 352 # define QAT_R_RAND_FAILURE 353 # define QAT_R_RAND_GENERATE_FAILURE 354 # define QAT_R_RESULT_PDATA_ALLOC_FAIL 355 # define QAT_R_RETRIEVE_EC_POINT_FAILURE 356 # define QAT_R_RETRIEVE_ORDER_FAILURE 357 # define QAT_R_RSA_FROM_TO_NULL 358 # define QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE 359 # define QAT_R_R_Q_COMPARE_FAILURE 360 # define QAT_R_SECRET_KEY_MALLOC_FAILURE 361 # define QAT_R_SECRET_KEY_PDATA_MALLOC_FAILURE 362 # define QAT_R_SEM_POST_FAILURE 363 # define QAT_R_SETUP_ASYNC_EVENT_FAILURE 364 # define QAT_R_SET_ADDRESS_TRANSLATION_FAILURE 365 # define QAT_R_SET_FILE_DESCRIPTOR_NONBLOCKING_FAILURE 366 # define QAT_R_SET_INSTANCE_FAILURE 367 # define QAT_R_SET_MULTIBUFF_RSA_METH_FAILURE 368 # define QAT_R_SET_NOTIFICATION_CALLBACK_FAILURE 369 # define QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE 370 # define QAT_R_SET_PRIV_KEY_FAILURE 371 # define QAT_R_SET_QAT_DSA_METH_FAILURE 372 # define QAT_R_SET_QAT_RSA_METH_FAILURE 373 # define QAT_R_SET_TAG_INVALID_OP 374 # define QAT_R_SHA3_CTX_NULL 375 # define QAT_R_SIG_GET_R_S_FAILURE 376 # define QAT_R_SIG_MALLOC_FAILURE 377 # define QAT_R_SM2_BAD_SIGNATURE 378 # define QAT_R_SM2_ID_TOO_LARGE 379 # define QAT_R_SM2_INVALID_DIGEST 380 # define QAT_R_SM2_SIGN_NULL 381 # define QAT_R_SM2_SIG_GEN_MALLOC_FAILURE 382 # define QAT_R_SM2_SIG_MALLOC_FAILURE 383 # define QAT_R_SM2_SIG_SET_R_S_FAILURE 384 # define QAT_R_SM2_VERIFY_NULL 385 # define QAT_R_SM3_CTX_NULL 386 # define QAT_R_SM3_FINAL_FAILURE 387 # define QAT_R_SM3_INIT_FAILURE 388 # define QAT_R_SM3_UPDATE_FAILURE 389 # define QAT_R_SM4_CCM_DECRYPT_FAILURE 390 # define QAT_R_SM4_GCM_DECRYPT_FAILURE 391 # define QAT_R_SM4_GCM_ENCRYPT_FAILURE 392 # define QAT_R_SM4_GET_INSTANCE_FAILED 393 # define QAT_R_SM4_GET_SESSIONCTX_SIZE_FAILED 394 # define QAT_R_SM4_MALLOC_FAILED 395 # define QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE 396 # define QAT_R_SM4_NULL_CKEY 397 # define QAT_R_SM4_NULL_CTX 398 # define QAT_R_SM4_NULL_CTX_OR_KEY 399 # define QAT_R_SM4_NULL_POINTER 400 # define QAT_R_SM4_NULL_QCTX 401 # define QAT_R_SM4_QAT_CONTEXT_NOT_INITIALISED 402 # define QAT_R_SM4_QAT_INITSESSION_FAILED 403 # define QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED 404 # define QAT_R_SM4_REMOVE_SESSION_FAILED 405 # define QAT_R_SM4_SETUP_META_DATA_FAILED 406 # define QAT_R_SM4_SET_METHODS_FAILED 407 # define QAT_R_SSD_MALLOC_FAILURE 408 # define QAT_R_SSD_NULL 409 # define QAT_R_START_INSTANCE_FAILURE 410 # define QAT_R_STOP_INSTANCE_FAILURE 411 # define QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL 412 # define QAT_R_SW_GET_KEYGEN_PFUNC_NULL 413 # define QAT_R_SW_GET_SIGN_PFUNC_NULL 414 # define QAT_R_SW_GET_SIGN_SETUP_PFUNC_NULL 415 # define QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL 416 # define QAT_R_SW_GET_VERIFY_PFUNC_NULL 417 # define QAT_R_SW_GET_VERIFY_SIG_PFUNC_NULL 418 # define QAT_R_SW_METHOD_NULL 419 # define QAT_R_S_NULL 420 # define QAT_R_S_Q_COMPARE_FAILURE 421 # define QAT_R_TAG_NOTSET 422 # define QAT_R_TAG_NOT_NEEDED 423 # define QAT_R_UNKNOWN_PADDING 424 # define QAT_R_UNKNOWN_PADDING_TYPE 425 # define QAT_R_WAKE_PAUSE_JOB_FAILURE 426 # define QAT_R_X_Y_E_MALLOC_FAILURE 427 # define QAT_R_X_Y_TX_TY_BN_MALLOC_FAILURE 428 # define QAT_R_X_Y_Z_MALLOC_FAILURE 429 # define QAT_R_ZALLOC_FAILURE 430 # define QAT_R_Z_ALLOCATE_FAILURE 431 #endif qatengine-1.9.0/qat_events.c000066400000000000000000000226211500416242000160060ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_events.c * * This file provides implementation for async events in engine * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Standard Includes */ #include #include #include #include #ifndef __FreeBSD__ # include # include #else # include # include #endif #include #include /* OpenSSL Includes */ #include /* QAT includes */ #ifdef QAT_HW # include "cpa.h" # include "cpa_types.h" #endif /* Local Includes */ #include "e_qat.h" #include "qat_events.h" #include "qat_utils.h" #ifdef QAT_HW int qat_is_event_driven() { return enable_event_driven_polling; } #endif static void qat_fd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, OSSL_ASYNC_FD readfd, void *custom) { #ifdef QAT_OPENSSL_3 int (*callback)(void *arg); void *args; if (ASYNC_WAIT_CTX_get_callback(ctx, &callback, &args)) { return; } #endif if (close(readfd) != 0) { WARN("Failed to close readfd: %d - error: %d\n", readfd, errno); QATerr(QAT_F_QAT_FD_CLEANUP, QAT_R_CLOSE_READFD_FAILURE); } } int qat_setup_async_event_notification(volatile ASYNC_JOB *job) { ASYNC_WAIT_CTX *waitctx; #ifdef QAT_OPENSSL_3 int (*callback)(void *arg); void *args; #endif OSSL_ASYNC_FD efd; void *custom = NULL; #ifdef __FreeBSD__ struct kevent event; #endif if ((waitctx = ASYNC_get_wait_ctx((ASYNC_JOB *)job)) == NULL) { WARN("Could not obtain wait context for job\n"); return 0; } #ifdef QAT_OPENSSL_3 if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &args)) { return 1; } #endif if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_qat_id, &efd, &custom) == 0) { #ifdef __FreeBSD__ efd = kqueue(); if (efd == -1) { WARN("Failed to get kqueue fd = %d\n", errno); return 0; } /* Initialize the event */ EV_SET(&event, QAT_EVENT_NUM, EVFILT_USER, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, NULL); if (kevent(efd, &event, QAT_EVENT_NUM, NULL, 0, NULL) == -1) { WARN("Failed to register event for the fd = %d\n", efd); close(efd); return 0; } #else efd = eventfd(0, EFD_NONBLOCK); if (efd == -1) { WARN("Failed to get eventfd = %d\n", errno); return 0; } #endif if (ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_qat_id, efd, custom, qat_fd_cleanup) == 0) { WARN("failed to set the fd in the ASYNC_WAIT_CTX\n"); qat_fd_cleanup(waitctx, engine_qat_id, efd, NULL); return 0; } } return 1; } int qat_clear_async_event_notification(volatile ASYNC_JOB *job) { ASYNC_WAIT_CTX *waitctx; size_t num_add_fds = 0; size_t num_del_fds = 0; #ifdef QAT_OPENSSL_3 int (*callback)(void *arg); void *args; #endif OSSL_ASYNC_FD efd; void *custom = NULL; #ifdef QAT_BORINGSSL if (ASYNC_current_job_last_check_and_get()) { /* Do nothing */ } #endif /* QAT_BORINGSSL */ if ((waitctx = ASYNC_get_wait_ctx((ASYNC_JOB *)job)) == NULL) { WARN("Could not obtain wait context for job\n"); return 0; } #ifdef QAT_OPENSSL_3 if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &args)) { return 1; } #endif if (ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &num_add_fds, NULL, &num_del_fds) == 0) { WARN("Failure in ASYNC_WAIT_CTX_get_changed_async_fds\n"); return 0; } if (num_add_fds > 0) { /* Only close the fd and remove it from the ASYNC_WAIT_CTX if it is a new fd. If it is an existing fd then leave it open and in the ASYNC_WAIT_CTX and it will be cleaned up when the ASYNC_WAIT_CTX is cleaned up.*/ if (ASYNC_WAIT_CTX_get_fd(waitctx, engine_qat_id, &efd, &custom) == 0) { WARN("Failure in ASYNC_WAIT_CTX_get_fd\n"); return 0; } qat_fd_cleanup(waitctx, engine_qat_id, efd, NULL); if (ASYNC_WAIT_CTX_clear_fd(waitctx, engine_qat_id) == 0) { WARN("Failure in ASYNC_WAIT_CTX_clear_fd\n"); return 0; } } return 1; } int qat_pause_job(volatile ASYNC_JOB *job, int jobStatus) { ASYNC_WAIT_CTX *waitctx; int ret = 0; #ifdef QAT_OPENSSL_3 int callback_set = 0; int (*callback)(void *arg); void *args; #endif OSSL_ASYNC_FD readfd; void *custom = NULL; #ifdef __FreeBSD__ struct kevent event; #else uint64_t buf = 0; #endif if ((waitctx = ASYNC_get_wait_ctx((ASYNC_JOB *)job)) == NULL) { WARN("waitctx == NULL\n"); return ret; } #ifdef QAT_OPENSSL_3 if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &args)) { callback_set = 1; ASYNC_WAIT_CTX_set_status(waitctx, jobStatus); } #endif if (ASYNC_pause_job() == 0) { WARN("Failed to pause the job\n"); return ret; } #ifdef QAT_OPENSSL_3 if (callback_set) { return 1; } #endif if ((ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_qat_id, &readfd, &custom)) > 0) { #ifndef __FreeBSD__ if (read(readfd, &buf, sizeof(uint64_t)) == -1) { if (errno != EAGAIN) { WARN("Failed to read from fd: %d - error: %d\n", readfd, errno); } /* Not resumed by the expected qat_wake_job() */ return QAT_JOB_RESUMED_UNEXPECTEDLY; } #else if (kevent(readfd, NULL, 0, &event, QAT_EVENT_NUM, NULL) == -1) { WARN("Failed to get event from fd: %d - error: %d\n", readfd, errno); /* Not resumed by the expected qat_wake_job() */ return QAT_JOB_RESUMED_UNEXPECTEDLY; } #endif } return ret; } int qat_wake_job(volatile ASYNC_JOB *job, int jobStatus) { ASYNC_WAIT_CTX *waitctx; int ret = 0; #ifdef QAT_OPENSSL_3 int (*callback)(void *arg); void *args; #endif OSSL_ASYNC_FD efd; void *custom = NULL; #ifdef __FreeBSD__ struct kevent event; #else /* Arbitrary value '1' to write down the pipe to trigger event */ uint64_t buf = 1; #endif if ((waitctx = ASYNC_get_wait_ctx((ASYNC_JOB *)job)) == NULL) { WARN("waitctx == NULL\n"); return ret; } #ifdef QAT_OPENSSL_3 if (ASYNC_WAIT_CTX_get_callback(waitctx, &callback, &args)) { /* We will go through callback mechanism */ if (ASYNC_STATUS_OK == jobStatus) { (*callback)(args); } else { /* In this case, we assume that a possible retry happened */ ASYNC_WAIT_CTX_set_status(waitctx, jobStatus); } return 1; } #endif if ((ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_qat_id, &efd, &custom)) > 0) { #ifndef __FreeBSD__ if (write(efd, &buf, sizeof(uint64_t)) == -1) { WARN("Failed to write to fd: %d - error: %d\n", efd, errno); } #else EV_SET(&event, QAT_EVENT_NUM, EVFILT_USER, EV_ADD, NOTE_TRIGGER, 0, NULL); if (kevent(efd, &event, QAT_EVENT_NUM, NULL, 0, NULL) == -1) { WARN("Failed to trigger event to fd: %d - error: %d\n", efd, errno); } #endif } return ret; } qatengine-1.9.0/qat_events.h000066400000000000000000000063411500416242000160140ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_events.h * * This file provides an interface for async events in engine * *****************************************************************************/ #ifndef QAT_EVENTS_H # define QAT_EVENTS_H # include # include /* This value is defined as one possible return value * of qat_pause_job() which means paused async job is * not resumed by async event but some other events * such as socket events. * NOTE THAT the unexpected event will be thrown away * effectively and quietly. The application should be * aware of this case. */ #define QAT_JOB_RESUMED_UNEXPECTEDLY -1 #define QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(x) \ (x == QAT_JOB_RESUMED_UNEXPECTEDLY) /* * These #defines ensure backward compatibility with OpenSSL versions 1.1.0 * and 1.1.1 which do not have asynchronous callback mode. */ #ifndef OPENSSL_3 # define ASYNC_STATUS_UNSUPPORTED 0 # define ASYNC_STATUS_ERR 1 # define ASYNC_STATUS_OK 2 # define ASYNC_STATUS_EAGAIN 3 #endif #ifdef __FreeBSD__ # define QAT_EVENT_NUM 1 #endif int qat_is_event_driven(); int qat_setup_async_event_notification(volatile ASYNC_JOB *job); int qat_clear_async_event_notification(volatile ASYNC_JOB *job); int qat_pause_job(volatile ASYNC_JOB *job, int jobStatus); int qat_wake_job(volatile ASYNC_JOB *job, int jobStatus); #endif /* QAT_EVENTS_H */ qatengine-1.9.0/qat_evp.c000066400000000000000000002011441500416242000152730ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2019-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_evp.c * * This file provides an initialisation of the various operations at the EVP * layer for an OpenSSL engine. * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include "openssl/ossl_typ.h" #ifndef QAT_BORINGSSL #include "openssl/kdf.h" #endif #include "openssl/evp.h" #include "e_qat.h" #include "qat_evp.h" #include "qat_utils.h" #ifdef QAT_HW # include "qat_hw_rsa.h" # include "qat_hw_sm4_cbc.h" # ifndef QAT_BORINGSSL # include "qat_hw_ciphers.h" # endif /* QAT_BORINGSSL */ # include "qat_hw_ec.h" # ifndef QAT_BORINGSSL # include "qat_hw_gcm.h" # include "qat_hw_ccm.h" # include "qat_hw_sha3.h" # include "qat_hw_chachapoly.h" # include "qat_hw_sm3.h" # include "qat_hw_sm2.h" # endif /* QAT_BORINGSSL */ #endif #ifdef ENABLE_QAT_SW_GCM # ifndef QAT_BORINGSSL # include "qat_sw_gcm.h" # endif /* QAT_BORINGSSL */ #endif #ifdef QAT_SW # ifndef QAT_BORINGSSL # include "qat_sw_ecx.h" # include "qat_sw_sm3.h" # endif /* QAT_BORINGSSL */ # include "qat_sw_ec.h" # include "qat_sw_rsa.h" # include "qat_sw_sm3.h" # include "qat_sw_sm2.h" # ifndef QAT_BORINGSSL # include "qat_sw_sm4_cbc.h" # endif /* QAT_BORINGSSL */ # include "crypto_mb/cpu_features.h" # ifndef QAT_BORINGSSL # ifdef ENABLE_QAT_SW_SM4_GCM # include "qat_sw_sm4_gcm.h" # include "crypto_mb/sm4_gcm.h" # endif # ifdef ENABLE_QAT_SW_SM4_CCM # include "qat_sw_sm4_ccm.h" # include "crypto_mb/sm4_ccm.h" # endif # endif /* QAT_BORINGSSL */ #endif #ifdef QAT_HW_INTREE # ifndef ENABLE_QAT_HW_SHA3 # define ENABLE_QAT_HW_SHA3 # endif # ifndef ENABLE_QAT_HW_CHACHAPOLY # define ENABLE_QAT_HW_CHACHAPOLY # endif #endif #ifndef SM4_BLOCK_SIZE # define SM4_BLOCK_SIZE 16 #endif # ifndef QAT_BORINGSSL typedef struct _chained_info { const int nid; EVP_CIPHER *cipher; const int keylen; } chained_info; static chained_info info[] = { #ifdef ENABLE_QAT_HW_CIPHERS # ifdef QAT_INSECURE_ALGO {NID_aes_128_cbc_hmac_sha1, NULL, AES_KEY_SIZE_128}, {NID_aes_256_cbc_hmac_sha1, NULL, AES_KEY_SIZE_256}, {NID_aes_128_cbc_hmac_sha256, NULL, AES_KEY_SIZE_128}, # endif {NID_aes_256_cbc_hmac_sha256, NULL, AES_KEY_SIZE_256}, #endif #ifdef ENABLE_QAT_HW_CHACHAPOLY {NID_chacha20_poly1305, NULL, CHACHA_KEY_SIZE}, #endif #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) {NID_aes_128_gcm, NULL, AES_KEY_SIZE_128}, {NID_aes_192_gcm, NULL, AES_KEY_SIZE_192}, {NID_aes_256_gcm, NULL, AES_KEY_SIZE_256}, #endif #if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) /* sm4-cbc key size is fixed to 128 bits (16 bytes) */ {NID_sm4_cbc, NULL, SM4_KEY_SIZE}, #endif #ifdef ENABLE_QAT_SW_SM4_GCM {NID_sm4_gcm, NULL, SM4_KEY_SIZE}, #endif #ifdef ENABLE_QAT_SW_SM4_CCM {NID_sm4_ccm, NULL, SM4_KEY_SIZE}, #endif #ifdef ENABLE_QAT_HW_CCM {NID_aes_128_ccm, NULL, AES_KEY_SIZE_128}, {NID_aes_192_ccm, NULL, AES_KEY_SIZE_192}, {NID_aes_256_ccm, NULL, AES_KEY_SIZE_256}, #endif }; static const unsigned int num_cc = sizeof(info) / sizeof(chained_info); /* Qat Symmetric cipher function register */ int qat_cipher_nids[] = { #ifdef ENABLE_QAT_HW_CIPHERS # ifdef QAT_INSECURE_ALGO NID_aes_128_cbc_hmac_sha1, NID_aes_256_cbc_hmac_sha1, NID_aes_128_cbc_hmac_sha256, # endif NID_aes_256_cbc_hmac_sha256, #endif #ifdef ENABLE_QAT_HW_CHACHAPOLY NID_chacha20_poly1305, #endif #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) NID_aes_128_gcm, NID_aes_192_gcm, NID_aes_256_gcm, #endif #if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) NID_sm4_cbc, #endif #ifdef ENABLE_QAT_SW_SM4_GCM NID_sm4_gcm, #endif #ifdef ENABLE_QAT_SW_SM4_CCM NID_sm4_ccm, #endif #ifdef ENABLE_QAT_HW_CCM NID_aes_128_ccm, NID_aes_192_ccm, NID_aes_256_ccm, #endif }; /* Supported EVP nids */ int qat_evp_nids[] = { # ifdef ENABLE_QAT_HW_PRF EVP_PKEY_TLS1_PRF, # endif # ifdef ENABLE_QAT_HW_HKDF EVP_PKEY_HKDF, # endif # if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) EVP_PKEY_X25519, # endif # ifdef ENABLE_QAT_HW_ECX EVP_PKEY_X448, # endif # if defined(ENABLE_QAT_SW_SM2) || defined(ENABLE_QAT_HW_SM2) EVP_PKEY_SM2 # endif }; const int num_evp_nids = sizeof(qat_evp_nids) / sizeof(qat_evp_nids[0]); typedef struct _digest_data { const int m_type; EVP_MD *md; const int pkey_type; } digest_data; static digest_data digest_info[] = { #ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO { NID_sha3_224, NULL, NID_RSA_SHA3_224}, # endif { NID_sha3_256, NULL, NID_RSA_SHA3_256}, { NID_sha3_384, NULL, NID_RSA_SHA3_384}, { NID_sha3_512, NULL, NID_RSA_SHA3_512}, #endif #if defined(ENABLE_QAT_SW_SM3) || defined(ENABLE_QAT_HW_SM3) { NID_sm3, NULL, NID_sm3WithRSAEncryption}, #endif }; /* QAT Hash Algorithm register */ int qat_digest_nids[] = { #ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO NID_sha3_224, # endif NID_sha3_256, NID_sha3_384, NID_sha3_512, # endif #if defined(ENABLE_QAT_SW_SM3) || defined(ENABLE_QAT_HW_SM3) NID_sm3, #endif }; const int num_digest_nids = sizeof(qat_digest_nids) / sizeof(qat_digest_nids[0]); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD typedef struct cipher_threshold_table_s { int nid; int threshold; } PKT_THRESHOLD; static PKT_THRESHOLD qat_pkt_threshold_table[] = { # ifdef ENABLE_QAT_HW_CIPHERS # ifdef QAT_INSECURE_ALGO {NID_aes_128_cbc_hmac_sha1, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, {NID_aes_256_cbc_hmac_sha1, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, {NID_aes_128_cbc_hmac_sha256, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, # endif {NID_aes_256_cbc_hmac_sha256, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, # endif # ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO {NID_sha3_224, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, # endif {NID_sha3_256, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, {NID_sha3_384, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, {NID_sha3_512, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, # endif # ifdef ENABLE_QAT_HW_CHACHAPOLY {NID_chacha20_poly1305, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, # endif # if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) {NID_sm4_cbc, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_SM4_CBC}, # endif # ifdef ENABLE_QAT_HW_SM3 {NID_sm3, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_HW_SM3}, # endif # ifdef ENABLE_QAT_HW_CCM {NID_aes_128_ccm, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, {NID_aes_192_ccm, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, {NID_aes_256_ccm, CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT}, # endif }; static int pkt_threshold_table_size = (sizeof(qat_pkt_threshold_table) / sizeof(qat_pkt_threshold_table[0])); # endif #endif /* QAT_BORINGSSL */ #ifndef QAT_OPENSSL_PROVIDER static EC_KEY_METHOD *qat_ec_method = NULL; static RSA_METHOD *qat_rsa_method = NULL; #endif #ifdef QAT_BORINGSSL static RSA_METHOD null_rsa_method = {.common={.is_static = 1}}; static EC_KEY_METHOD null_ecdsa_method = {.common={.is_static = 1}}; #endif /* QAT_BORINGSSL */ #ifndef QAT_BORINGSSL # ifndef QAT_OPENSSL_PROVIDER static EVP_PKEY_METHOD *_hidden_x25519_pmeth = NULL; static EVP_PKEY_METHOD *_hidden_x448_pmeth = NULL; # endif /* Have a store of the s/w EVP_PKEY_METHOD for software fallback purposes. */ const EVP_PKEY_METHOD *sw_x25519_pmeth = NULL; /* Have a store of the s/w EVP_PKEY_METHOD for software fallback purposes. */ const EVP_PKEY_METHOD *sw_x448_pmeth = NULL; #if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) static EVP_PKEY_METHOD *_hidden_sm2_pmeth = NULL; const EVP_PKEY_METHOD *sw_sm2_pmeth = NULL; #endif #if defined(ENABLE_QAT_SW_SM3) int qat_sw_sm3_md_methods(EVP_MD *c) { int res = 1; res &= EVP_MD_meth_set_result_size(c, 32); res &= EVP_MD_meth_set_input_blocksize(c, SM3_MSG_BLOCK_SIZE); res &= EVP_MD_meth_set_app_datasize(c, sizeof(EVP_MD *) + sizeof(QAT_SM3_CTX_mb)); res &= EVP_MD_meth_set_flags(c, EVP_MD_CTX_FLAG_REUSE); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_MD_meth_set_init(c, qat_sw_sm3_init); res &= EVP_MD_meth_set_update(c, qat_sw_sm3_update); res &= EVP_MD_meth_set_final(c, qat_sw_sm3_final); #endif return res; } #endif const EVP_MD *qat_sw_create_sm3_meth(int nid , int key_type) { #ifdef ENABLE_QAT_SW_SM3 int res = 1; EVP_MD *qat_sw_sm3_meth = NULL; if ((qat_sw_sm3_meth = EVP_MD_meth_new(nid, key_type)) == NULL) { WARN("Failed to allocate digest methods for nid %d\n", nid); return NULL; } if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM3) && mbx_get_algo_info(MBX_ALGO_SM3)) { res = qat_sw_sm3_md_methods(qat_sw_sm3_meth); if (0 == res) { WARN("Failed to set MD methods for nid %d\n", nid); EVP_MD_meth_free(qat_sw_sm3_meth); return NULL; } qat_sw_sm3_offload = 1; DEBUG("QAT SW SM3 Registration succeeded\n"); return qat_sw_sm3_meth; } else { qat_sw_sm3_offload = 0; DEBUG("QAT SW SM3 is disabled, using OpenSSL SW\n"); # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) qat_openssl3_sm3_fallback = 1; res = qat_sw_sm3_md_methods(qat_sw_sm3_meth); if (0 == res) { WARN("Failed to set MD methods for nid %d\n", nid); EVP_MD_meth_free(qat_sw_sm3_meth); return NULL; } return qat_sw_sm3_meth; # else return (EVP_MD *)EVP_sm3(); # endif } #else qat_sw_sm3_offload = 0; DEBUG("QAT SW SM3 is disabled, using OpenSSL SW\n"); # ifdef OPENSSL_NO_SM2_SM3 return NULL; # else return (EVP_MD *)EVP_sm3(); # endif #endif } /****************************************************************************** * function: * qat_create_digest_meth(void) * * description: * Creates qat EVP MD methods. ******************************************************************************/ void qat_create_digest_meth(void) { int i; /* free the old method while algorithm reload */ if (qat_reload_algo) qat_free_digest_meth(); for (i = 0; i < num_digest_nids; i++) { if (digest_info[i].md == NULL) { switch (digest_info[i].m_type) { #ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO case NID_sha3_224: # endif case NID_sha3_256: case NID_sha3_384: case NID_sha3_512: digest_info[i].md = (EVP_MD *) qat_create_sha3_meth(digest_info[i].m_type , digest_info[i].pkey_type); break; #endif #ifdef ENABLE_QAT_SW_SM3 case NID_sm3: digest_info[i].md = (EVP_MD *) qat_sw_create_sm3_meth(digest_info[i].m_type , digest_info[i].pkey_type); break; #endif #ifdef ENABLE_QAT_HW_SM3 case NID_sm3: digest_info[i].md = (EVP_MD *) qat_hw_create_sm3_meth(digest_info[i].m_type , digest_info[i].pkey_type); break; #endif default: break; } } } } void qat_free_digest_meth(void) { int i; for (i = 0; i < num_digest_nids; i++) { if (digest_info[i].md != NULL) { switch (digest_info[i].m_type) { #ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO case NID_sha3_224: # endif case NID_sha3_256: case NID_sha3_384: case NID_sha3_512: if (qat_hw_sha_offload) EVP_MD_meth_free(digest_info[i].md); break; #endif #ifdef ENABLE_QAT_SW_SM3 case NID_sm3: if (qat_sw_sm3_offload) EVP_MD_meth_free(digest_info[i].md); break; #endif #ifdef ENABLE_QAT_HW_SM3 case NID_sm3: if (qat_hw_sm3_offload) EVP_MD_meth_free(digest_info[i].md); break; #endif } digest_info[i].md = NULL; } } qat_hw_sha_offload = 0; qat_sw_sm3_offload = 0; qat_hw_sm3_offload = 0; } /****************************************************************************** * function: * qat_digest_methods(ENGINE *e, * const EVP_MD **md, * const int **nids, * int nid) * * @param e [IN] - OpenSSL engine pointer * @param pmeth [IN] - EVP methods structure pointer * @param nids [IN] - EVP function nids * @param nid [IN] - EVP operation id * * description: * QAT engine digest operations register. ******************************************************************************/ #ifndef QAT_OPENSSL_PROVIDER int qat_digest_methods(ENGINE *e, const EVP_MD **md, const int **nids, int nid) { int i; if (md == NULL) { if (unlikely(nids == NULL)) { WARN("Invalid input params.\n"); return 0; } *nids = qat_digest_nids; return num_digest_nids; } for (i = 0; i < num_digest_nids; i++) { if (nid == qat_digest_nids[i]) { if (digest_info[i].md == NULL) qat_create_digest_meth(); *md = digest_info[i].md; return 1; } } WARN("NID %d not supported\n", nid); *md = NULL; return 0; } #endif #ifdef QAT_OPENSSL_3 /* The following 3 functions are only used for * TLSv1.3 with OpenSSL 3 Engine API. */ int qat_ecx_paramgen_init(EVP_PKEY_CTX *ctx) { return 1; } int qat_ecx25519_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { if (pkey == NULL) { pkey = EVP_PKEY_new(); if (pkey == NULL) { WARN("Couldn't allocate pkey.\n"); return -1; } } return EVP_PKEY_set_type(pkey, NID_X25519); } int qat_ecx448_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { if (pkey == NULL) { pkey = EVP_PKEY_new(); if (pkey == NULL) { WARN("Couldn't allocate pkey.\n"); return -1; } } return EVP_PKEY_set_type(pkey, NID_X448); } #endif #ifdef ENABLE_QAT_SW_ECX # ifndef QAT_OPENSSL_PROVIDER static void qat_ecx25519_pkey_methods(void) { EVP_PKEY_meth_set_keygen(_hidden_x25519_pmeth, NULL, multibuff_x25519_keygen); EVP_PKEY_meth_set_derive(_hidden_x25519_pmeth, NULL, multibuff_x25519_derive); # ifdef QAT_OPENSSL_3 EVP_PKEY_meth_set_paramgen(_hidden_x25519_pmeth, qat_ecx_paramgen_init, qat_ecx25519_paramgen); # endif /* QAT_OPENSSL_3 */ EVP_PKEY_meth_set_ctrl(_hidden_x25519_pmeth, multibuff_x25519_ctrl, NULL); } # endif #endif # ifndef QAT_OPENSSL_PROVIDER EVP_PKEY_METHOD *qat_x25519_pmeth(void) { if (_hidden_x25519_pmeth) { if (!qat_reload_algo) return _hidden_x25519_pmeth; EVP_PKEY_meth_free(_hidden_x25519_pmeth); _hidden_x25519_pmeth = NULL; } if ((_hidden_x25519_pmeth = EVP_PKEY_meth_new(EVP_PKEY_X25519, 0)) == NULL) { QATerr(QAT_F_QAT_X25519_PMETH, QAT_R_ALLOC_QAT_X25519_METH_FAILURE); return NULL; } /* Now save the current (non-offloaded) x25519 pmeth to sw_x25519_pmeth */ /* for software fallback purposes */ if ((sw_x25519_pmeth = EVP_PKEY_meth_find(EVP_PKEY_X25519)) == NULL) { QATerr(QAT_F_QAT_X25519_PMETH, ERR_R_INTERNAL_ERROR); return NULL; } #ifdef ENABLE_QAT_HW_ECX # ifndef QAT_OPENSSL_PROVIDER if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_ECX25519)) { EVP_PKEY_meth_set_keygen(_hidden_x25519_pmeth, NULL, qat_pkey_ecx25519_keygen); EVP_PKEY_meth_set_derive(_hidden_x25519_pmeth, NULL, qat_pkey_ecx_derive25519); # ifdef QAT_OPENSSL_3 EVP_PKEY_meth_set_paramgen(_hidden_x25519_pmeth, qat_ecx_paramgen_init, qat_ecx25519_paramgen); # endif /* QAT_OPENSSL_3 */ EVP_PKEY_meth_set_ctrl(_hidden_x25519_pmeth, qat_pkey_ecx_ctrl, NULL); qat_hw_ecx_offload = 1; DEBUG("QAT HW X25519 registration succeeded\n"); # ifdef ENABLE_QAT_SW_ECX if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECX25519) && mbx_get_algo_info(MBX_ALGO_X25519)) { qat_ecx_coexist = 1; DEBUG("QAT ECX25519 HW&SW Coexistence is enabled \n"); } # endif } else { qat_hw_ecx_offload = 0; DEBUG("QAT HW X25519 is disabled\n"); } # endif #endif #ifdef ENABLE_QAT_SW_ECX if (qat_sw_offload && !qat_hw_ecx_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECX25519) && mbx_get_algo_info(MBX_ALGO_X25519)) { qat_ecx25519_pkey_methods(); qat_sw_ecx_offload = 1; DEBUG("QAT SW X25519 registration succeeded\n"); } else { qat_sw_ecx_offload = 0; DEBUG("QAT SW X25519 disabled\n"); } # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (!qat_sw_offload) { fallback_to_openssl = 1; qat_ecx25519_pkey_methods(); return _hidden_x25519_pmeth; } # endif #endif if (qat_hw_ecx_offload == 0 && qat_sw_ecx_offload == 0) { EVP_PKEY_meth_copy(_hidden_x25519_pmeth, sw_x25519_pmeth); #ifdef QAT_OPENSSL_3 EVP_PKEY_meth_set_paramgen(_hidden_x25519_pmeth, qat_ecx_paramgen_init, qat_ecx25519_paramgen); #endif DEBUG("QAT HW & SW X25519 are not supported, using OpenSSL SW.\n"); } return _hidden_x25519_pmeth; } EVP_PKEY_METHOD *qat_x448_pmeth(void) { if (_hidden_x448_pmeth) { if (!qat_reload_algo) return _hidden_x448_pmeth; EVP_PKEY_meth_free(_hidden_x448_pmeth); _hidden_x448_pmeth = NULL; } if ((_hidden_x448_pmeth = EVP_PKEY_meth_new(EVP_PKEY_X448, 0)) == NULL) { QATerr(QAT_F_QAT_X448_PMETH, QAT_R_ALLOC_QAT_X448_METH_FAILURE); return NULL; } /* Now save the current (non-offloaded) x448 pmeth to sw_x448_pmeth */ /* for software fallback purposes */ if ((sw_x448_pmeth = EVP_PKEY_meth_find(EVP_PKEY_X448)) == NULL) { QATerr(QAT_F_QAT_X448_PMETH, ERR_R_INTERNAL_ERROR); return NULL; } #ifdef ENABLE_QAT_HW_ECX # ifndef QAT_OPENSSL_PROVIDER if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_ECX448)) { EVP_PKEY_meth_set_keygen(_hidden_x448_pmeth, NULL, qat_pkey_ecx448_keygen); EVP_PKEY_meth_set_derive(_hidden_x448_pmeth, NULL, qat_pkey_ecx_derive448); # ifdef QAT_OPENSSL_3 EVP_PKEY_meth_set_paramgen(_hidden_x448_pmeth, qat_ecx_paramgen_init, qat_ecx448_paramgen); # endif /* QAT_OPENSSL_3 */ EVP_PKEY_meth_set_ctrl(_hidden_x448_pmeth, qat_pkey_ecx_ctrl, NULL); qat_hw_ecx_offload = 1; DEBUG("QAT HW ECDH X448 Registration succeeded\n"); } else { qat_hw_ecx_offload = 0; } # endif #else qat_hw_ecx_offload = 0; #endif if (!qat_hw_ecx_offload) { EVP_PKEY_meth_copy(_hidden_x448_pmeth, sw_x448_pmeth); DEBUG("QAT HW ECDH X448 is disabled, using OpenSSL SW\n"); } return _hidden_x448_pmeth; } /****************************************************************************** * function: * qat_create_pkey_meth(int nid) * * @param nid [IN] - EVP operation id * * description: * Creates qat EVP Pkey methods for the nid ******************************************************************************/ static EVP_PKEY_METHOD *qat_create_pkey_meth(int nid) { switch (nid) { #ifdef ENABLE_QAT_HW_PRF case EVP_PKEY_TLS1_PRF: return qat_prf_pmeth(); #endif #ifdef ENABLE_QAT_HW_HKDF case EVP_PKEY_HKDF: return qat_hkdf_pmeth(); #endif #if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) case EVP_PKEY_X25519: return qat_x25519_pmeth(); #endif #ifdef ENABLE_QAT_HW_ECX case EVP_PKEY_X448: return qat_x448_pmeth(); #endif #if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) case EVP_PKEY_SM2: return qat_create_sm2_pmeth(); #endif default: WARN("Invalid nid %d\n", nid); return NULL; } } /****************************************************************************** * function: * qat_pkey_methods(ENGINE *e, * const EVP_PKEY_METHOD **pmeth, * const int **nids, * int nid) * * @param e [IN] - OpenSSL engine pointer * @param pmeth [IN] - EVP methods structure pointer * @param nids [IN] - EVP functions nids * @param nid [IN] - EVP operation id * * description: * QAT engine digest operations registrar ******************************************************************************/ int qat_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids, int nid) { int i = 0; if (pmeth == NULL) { if (unlikely(nids == NULL)) { WARN("Invalid input params.\n"); return 0; } *nids = qat_evp_nids; return num_evp_nids; } for (i = 0; i < num_evp_nids; i++) { if (nid == qat_evp_nids[i]) { *pmeth = qat_create_pkey_meth(nid); return 1; } } WARN("NID %d not supported\n", nid); *pmeth = NULL; return 0; } #endif const EVP_CIPHER *qat_gcm_cipher_sw_impl(int nid) { switch (nid) { case NID_aes_128_gcm: return EVP_aes_128_gcm(); case NID_aes_192_gcm: return EVP_aes_192_gcm(); case NID_aes_256_gcm: return EVP_aes_256_gcm(); default: WARN("Invalid nid %d\n", nid); return NULL; } } #ifdef ENABLE_QAT_HW_CCM const EVP_CIPHER *qat_ccm_cipher_sw_impl(int nid) { switch (nid) { case NID_aes_128_ccm: return EVP_aes_128_ccm(); case NID_aes_192_ccm: return EVP_aes_192_ccm(); case NID_aes_256_ccm: return EVP_aes_256_ccm(); default: WARN("Invalid nid %d\n", nid); return NULL; } } #endif /****************************************************************************** * function: * qat_create_gcm_cipher_meth(int nid, int keylen) * * @param nid [IN] - Cipher NID to be created * @param keylen [IN] - Key length of cipher [128|192|256] * @retval - EVP_CIPHER * to created cipher * @retval - NULL if failure * * description: * Create a new EVP_CIPHER based on requested nid for qat_hw or qat_sw ******************************************************************************/ const EVP_CIPHER *qat_create_gcm_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; #if defined(ENABLE_QAT_SW_GCM) || defined(ENABLE_QAT_HW_GCM) int res = 1; #endif if ((c = EVP_CIPHER_meth_new(nid, AES_GCM_BLOCK_SIZE, keylen)) == NULL) { WARN("Failed to allocate cipher methods for nid %d\n", nid); return NULL; } #ifdef ENABLE_QAT_SW_GCM if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_AES_GCM)) { #ifndef QAT_INSECURE_ALGO if (nid == NID_aes_128_gcm) { EVP_CIPHER_meth_free(c); DEBUG("OpenSSL SW AES_GCM_%d registration succeeded\n", keylen*8); return qat_gcm_cipher_sw_impl(nid); } #endif res &= EVP_CIPHER_meth_set_iv_length(c, IMB_GCM_IV_DATA_LEN); res &= EVP_CIPHER_meth_set_flags(c, VAESGCM_FLAG); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, vaesgcm_ciphers_init); res &= EVP_CIPHER_meth_set_do_cipher(c, vaesgcm_ciphers_do_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, vaesgcm_ciphers_cleanup); #endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(vaesgcm_ctx)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, NULL); res &= EVP_CIPHER_meth_set_get_asn1_params(c, NULL); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, vaesgcm_ciphers_ctrl); #endif if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_CIPHER_meth_free(c); return NULL; } qat_sw_gcm_offload = 1; DEBUG("QAT SW AES_GCM_%d registration succeeded\n", keylen*8); } else { qat_sw_gcm_offload = 0; DEBUG("QAT SW AES_GCM_%d is disabled\n", keylen*8); } #endif #ifdef ENABLE_QAT_HW_GCM if (!qat_sw_gcm_offload && qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_AES_GCM)) { # ifdef QAT_INSECURE_ALGO if (nid == NID_aes_192_gcm) { # else if (nid == NID_aes_192_gcm || nid == NID_aes_128_gcm) { # endif EVP_CIPHER_meth_free(c); DEBUG("OpenSSL SW AES_GCM_%d registration succeeded\n", keylen*8); return qat_gcm_cipher_sw_impl(nid); } res &= EVP_CIPHER_meth_set_iv_length(c, AES_GCM_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, QAT_GCM_FLAGS); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_aes_gcm_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_aes_gcm_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_aes_gcm_cleanup); #endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(qat_gcm_ctx)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv); res &= EVP_CIPHER_meth_set_get_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, qat_aes_gcm_ctrl); #endif if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_CIPHER_meth_free(c); return NULL; } qat_hw_gcm_offload = 1; DEBUG("QAT HW AES_GCM_%d registration succeeded\n", keylen*8); } else { qat_hw_gcm_offload = 0; DEBUG("QAT HW AES_GCM_%d is disabled\n", keylen*8); } #endif if (!qat_sw_gcm_offload && !qat_hw_gcm_offload) { DEBUG("OpenSSL SW AES_GCM_%d registration succeeded\n", keylen*8); EVP_CIPHER_meth_free(c); return qat_gcm_cipher_sw_impl(nid); } return c; } /****************************************************************************** * function: * qat_create_ccm_cipher_meth(int nid, int keylen) * * @param nid [IN] - Cipher NID to be created * @param keylen [IN] - Key length of cipher [128|192|256] * @retval - EVP_CIPHER * to created cipher * @retval - NULL if failure * * description: * Create a new EVP_CIPHER based on requested nid for qat_hw ******************************************************************************/ #ifdef ENABLE_QAT_HW_CCM const EVP_CIPHER *qat_create_ccm_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; int res = 1; if ((c = EVP_CIPHER_meth_new(nid, AES_CCM_BLOCK_SIZE, keylen)) == NULL) { WARN("Failed to allocate cipher methods for nid %d\n", nid); return NULL; } if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_AES_CCM)) { #ifndef QAT_INSECURE_ALGO if (nid == NID_aes_128_ccm || nid == NID_aes_192_ccm) { EVP_CIPHER_meth_free(c); DEBUG("OpenSSL SW AES_CCM_%d registration succeeded\n", keylen*8); return qat_ccm_cipher_sw_impl(nid); } #endif #if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) # ifdef QAT_INSECURE_ALGO if (nid == NID_aes_192_ccm || nid == NID_aes_256_ccm) { # else if (nid == NID_aes_256_ccm) { # endif EVP_CIPHER_meth_free(c); DEBUG("OpenSSL SW AES_CCM_%d registration succeeded\n", keylen*8); return qat_ccm_cipher_sw_impl(nid); } #endif res &= EVP_CIPHER_meth_set_iv_length(c, AES_CCM_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, QAT_CCM_FLAGS); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_aes_ccm_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_aes_ccm_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_aes_ccm_cleanup); #endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(qat_ccm_ctx)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv); res &= EVP_CIPHER_meth_set_get_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, qat_aes_ccm_ctrl); #endif if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_CIPHER_meth_free(c); return NULL; } qat_hw_aes_ccm_offload = 1; DEBUG("QAT HW AES_CCM_%d registration succeeded\n", keylen*8); } else { qat_hw_aes_ccm_offload = 0; DEBUG("QAT HW AES_CCM_%d is disabled\n", keylen*8); } if (!qat_hw_aes_ccm_offload) { DEBUG("OpenSSL SW AES_CCM_%d registration succeeded\n", keylen*8); EVP_CIPHER_meth_free(c); return qat_ccm_cipher_sw_impl(nid); } return c; } #endif /****************************************************************************** * function: * qat_create_sm4_cbc_cipher_meth(void) * * @param nid [IN] - Cipher NID to be created * @param keylen [IN] - Key length of cipher [128|192|256] * @retval - EVP_CIPHER * to created cipher * @retval - EVP_CIPHER * EVP_sm4_cbc * @retval - NULL if failure * * description: * Create a new EVP_CIPHER based on requested nid for qat_hw or qat_sw ******************************************************************************/ const EVP_CIPHER *qat_create_sm4_cbc_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; #if defined(ENABLE_QAT_SW_SM4_CBC) || defined(ENABLE_QAT_HW_SM4_CBC) int res = 1; #endif if ((c = EVP_CIPHER_meth_new(nid, SM4_BLOCK_SIZE, keylen)) == NULL) { WARN("Failed to allocate cipher methods for nid %d\n", nid); QATerr(QAT_F_QAT_CREATE_SM4_CBC_CIPHER_METH, QAT_R_SM4_MALLOC_FAILED); return NULL; } #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_SM4_CBC)) { res &= EVP_CIPHER_meth_set_iv_length(c, SM4_CBC_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, QAT_CBC_FLAGS); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_sm4_cbc_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_sm4_cbc_do_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_sm4_cbc_cleanup); #endif res &= EVP_CIPHER_meth_set_set_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv); res &= EVP_CIPHER_meth_set_get_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv); #ifndef QAT_OPENSSL_PROVIDER /* SM4 CBC has no ctrl function. */ res &= EVP_CIPHER_meth_set_ctrl(c, NULL); #endif qat_hw_sm4_cbc_offload = 1; DEBUG("QAT HW SM4_CBC registration succeeded\n"); #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM4_CBC) && mbx_get_algo_info(MBX_ALGO_SM4)) { res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(qat_sm4_ctx) + sizeof(SM4_CBC_CTX)); qat_sm4_cbc_coexist = 1; DEBUG("QAT SM4_CBC HW&SW Coexistence is enabled \n"); } # endif if (!qat_sm4_cbc_coexist) { res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(qat_sm4_ctx)); } if (res == 0) { WARN("Failed to set SM4 methods for nid %d\n", nid); QATerr(QAT_F_QAT_CREATE_SM4_CBC_CIPHER_METH, QAT_R_SM4_SET_METHODS_FAILED); qat_hw_sm4_cbc_offload = 0; return NULL; } } else { qat_hw_sm4_cbc_offload = 0; DEBUG("OpenSSL SW SM4 CBC registration\n"); } #endif #ifdef ENABLE_QAT_SW_SM4_CBC if (!qat_hw_sm4_cbc_offload && qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM4_CBC) && mbx_get_algo_info(MBX_ALGO_SM4)) { res &= EVP_CIPHER_meth_set_iv_length(c, SM4_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, SM4_CBC_CUSTOM_FLAGS); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_sw_sm4_cbc_key_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_sw_sm4_cbc_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_sw_sm4_cbc_cleanup); #endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(SM4_CBC_CTX)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, NULL); res &= EVP_CIPHER_meth_set_get_asn1_params(c, NULL); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, NULL); #endif if (res == 0) { WARN("Failed to set SM4 methods for nid %d\n", nid); QATerr(QAT_F_QAT_CREATE_SM4_CBC_CIPHER_METH, QAT_R_SM4_SET_METHODS_FAILED); qat_sw_sm4_cbc_offload = 0; return NULL; } qat_sw_sm4_cbc_offload = 1; DEBUG("QAT SW SM4-CBC registration succeeded\n"); } else { qat_sw_sm4_cbc_offload = 0; DEBUG("OpenSSL SW SM4 CBC registration\n"); } #endif if ((qat_hw_sm4_cbc_offload == 0) && (qat_sw_sm4_cbc_offload == 0)) { DEBUG("QAT_HW and QAT_SW SM4-CBC not supported! Using OpenSSL SW method\n"); EVP_CIPHER_meth_free(c); #if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) return (const EVP_CIPHER *)EVP_sm4_cbc(); #endif } return c; } /****************************************************************************** * function: * qat_create_sm4_gcm_cipher_meth(int nid, int keylen) * * @retval - EVP_CIPHER * to created cipher * @retval - EVP_CIPHER * EVP_sm4_gcm * @retval - NULL if failure * * description: * Create a new EVP_CIPHER based on requested nid for qat_sw ******************************************************************************/ #ifdef ENABLE_QAT_SW_SM4_GCM const EVP_CIPHER *qat_create_sm4_gcm_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; int res = 1; if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM4_GCM) && mbx_get_algo_info(MBX_ALGO_SM4)) { #ifdef QAT_NTLS if ((c = EVP_CIPHER_meth_new(nid, 1, keylen)) == NULL) { #else if ((c = EVP_CIPHER_meth_new(nid, SM4_BLOCK_SIZE, keylen)) == NULL) { #endif WARN("Failed to generate meth\n"); return NULL; } res &= EVP_CIPHER_meth_set_iv_length(c, QAT_SM4_TLS_TOTAL_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, CUSTOM_FLAGS); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_sw_sm4_gcm_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_sw_sm4_gcm_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_sw_sm4_gcm_cleanup); #endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(QAT_SM4_GCM_CTX)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, NULL); res &= EVP_CIPHER_meth_set_get_asn1_params(c, NULL); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, qat_sw_sm4_gcm_ctrl); #endif if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", NID_sm4_gcm); EVP_CIPHER_meth_free(c); c = NULL; } qat_sw_sm4_gcm_offload = 1; DEBUG("QAT SW SM4 GCM registration succeeded, res=%d\n", res); } else { qat_sw_sm4_gcm_offload = 0; DEBUG("OpenSSL SW SM4 GCM registration\n"); return (const EVP_CIPHER *)EVP_sm4_gcm(); } return c; } #endif /* ENABLE_QAT_SW_SM4_GCM */ /****************************************************************************** * function: * qat_create_sm4_ccm_cipher_meth(int nid, in keylen) * * @retval - EVP_CIPHER * to created cipher * @retval - EVP_CIPHER * EVP_sm4_ccm * @retval - NULL if failure * * description: * Create a new EVP_CIPHER based on requested nid for qat_sw ******************************************************************************/ #ifdef ENABLE_QAT_SW_SM4_CCM const EVP_CIPHER *qat_create_sm4_ccm_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; int res = 1; if ((c = EVP_CIPHER_meth_new(nid, SM4_BLOCK_SIZE, keylen)) == NULL) { QATerr(QAT_F_QAT_CREATE_SM4_CCM_CIPHER_METH, QAT_R_SM4_MALLOC_FAILED); WARN("Failed to generate meth\n"); return NULL; } if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM4_CCM) && mbx_get_algo_info(MBX_ALGO_SM4)) { res &= EVP_CIPHER_meth_set_flags(c, CUSTOM_CCM_FLAGS); res &= EVP_CIPHER_meth_set_iv_length(c, EVP_CCM_TLS_IV_LEN); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_init(c, qat_sw_sm4_ccm_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_sw_sm4_ccm_do_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_sw_sm4_ccm_cleanup); #endif res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(QAT_SM4_CCM_CTX)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, NULL); res &= EVP_CIPHER_meth_set_get_asn1_params(c, NULL); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_ctrl(c, qat_sw_sm4_ccm_ctrl); #endif if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", NID_sm4_ccm); EVP_CIPHER_meth_free(c); return NULL; } qat_sw_sm4_ccm_offload = 1; DEBUG("QAT SW SM4 CCM registration succeeded, res=%d\n", res); } else { qat_sw_sm4_ccm_offload = 0; DEBUG("QAT SW SM4-CCM disabled\n"); } if (!qat_sw_sm4_ccm_offload) { DEBUG("OpenSSL SW SM4 CCM registration\n"); EVP_CIPHER_meth_free(c); return (const EVP_CIPHER *)EVP_sm4_ccm(); } return c; } #endif /* ENABLE_QAT_SW_SM4_CCM */ #if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { int (*pkeygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) = NULL; if ((sw_sm2_pmeth = EVP_PKEY_meth_find(EVP_PKEY_EC)) == NULL) { WARN("Failed to generate hw_pmeth\n"); return -1; } EVP_PKEY_meth_get_keygen((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &pkeygen); pkeygen(ctx, pkey); *(int *)pkey = EVP_PKEY_SM2; return 1; } #endif #if defined(ENABLE_QAT_SW_SM2) && !defined(QAT_OPENSSL_PROVIDER) void qat_sm2_pkey_methods(void) { EVP_PKEY_meth_set_init(_hidden_sm2_pmeth, mb_sm2_init); # ifdef QAT_OPENSSL_3 /* Only used for OpenSSL 3 legacy engine API */ EVP_PKEY_meth_set_keygen(_hidden_sm2_pmeth, NULL, pkey_ec_keygen); # endif EVP_PKEY_meth_set_cleanup(_hidden_sm2_pmeth, mb_sm2_cleanup); EVP_PKEY_meth_set_ctrl(_hidden_sm2_pmeth, mb_sm2_ctrl, NULL); EVP_PKEY_meth_set_digest_custom(_hidden_sm2_pmeth, mb_digest_custom); EVP_PKEY_meth_set_digestsign(_hidden_sm2_pmeth, mb_ecdsa_sm2_sign); EVP_PKEY_meth_set_digestverify(_hidden_sm2_pmeth, mb_ecdsa_sm2_verify); } #endif EVP_PKEY_METHOD *qat_create_sm2_pmeth(void) { #if defined(ENABLE_QAT_HW_SM2) && defined(QAT_NTLS) int (*pencrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) = NULL; int (*pdecrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) = NULL; #endif # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (_hidden_sm2_pmeth && (qat_hw_sm2_offload || qat_sw_sm2_offload || qat_openssl3_sm2_fallback)) { #else if (_hidden_sm2_pmeth && (qat_hw_sm2_offload || qat_sw_sm2_offload)) { #endif if (!qat_reload_algo) return _hidden_sm2_pmeth; EVP_PKEY_meth_free(_hidden_sm2_pmeth); } #ifndef QAT_OPENSSL_PROVIDER if (sw_sm2_pmeth && !qat_hw_sm2_offload && !qat_reload_algo) return (EVP_PKEY_METHOD *)sw_sm2_pmeth; if ((_hidden_sm2_pmeth = EVP_PKEY_meth_new(EVP_PKEY_SM2, 0)) == NULL) { WARN("Failed to generate pmeth\n"); return NULL; } # ifndef QAT_OPENSSL_3 if ((sw_sm2_pmeth = EVP_PKEY_meth_find(EVP_PKEY_SM2)) == NULL) { WARN("Failed to generate sw_pmeth\n"); return NULL; } # endif # ifdef ENABLE_QAT_HW_SM2 if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_SM2)) { EVP_PKEY_meth_set_init(_hidden_sm2_pmeth, qat_sm2_init); # ifdef QAT_OPENSSL_3 /* Only used for OpenSSL 3 legacy engine API */ EVP_PKEY_meth_set_keygen(_hidden_sm2_pmeth, NULL, pkey_ec_keygen); # endif EVP_PKEY_meth_set_copy(_hidden_sm2_pmeth, qat_sm2_copy); EVP_PKEY_meth_set_cleanup(_hidden_sm2_pmeth, qat_sm2_cleanup); EVP_PKEY_meth_set_ctrl(_hidden_sm2_pmeth, qat_sm2_ctrl, NULL); EVP_PKEY_meth_set_digest_custom(_hidden_sm2_pmeth, qat_sm2_digest_custom); EVP_PKEY_meth_set_sign(_hidden_sm2_pmeth, NULL, qat_sm2_sign); EVP_PKEY_meth_set_verify(_hidden_sm2_pmeth, NULL, qat_sm2_verify); # ifdef QAT_NTLS EVP_PKEY_meth_get_encrypt((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &pencrypt); EVP_PKEY_meth_get_decrypt((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &pdecrypt); EVP_PKEY_meth_set_encrypt(_hidden_sm2_pmeth, NULL, pencrypt); EVP_PKEY_meth_set_decrypt(_hidden_sm2_pmeth, NULL, pdecrypt); # endif qat_hw_sm2_offload = 1; DEBUG("QAT HW SM2 registration succeeded\n"); } else { qat_hw_sm2_offload = 0; DEBUG("QAT HW SM2 disabled\n"); } # endif /* ENABLE_QAT_HW_SM2 */ # ifdef ENABLE_QAT_SW_SM2 if (qat_sw_offload && !qat_hw_sm2_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_SM2) && mbx_get_algo_info(MBX_ALGO_X25519)) { qat_sm2_pkey_methods(); qat_sw_sm2_offload = 1; DEBUG("QAT SW SM2 registration succeeded\n"); } else { qat_sw_sm2_offload = 0; } if (!qat_sw_sm2_offload && !qat_hw_sm2_offload) { DEBUG("QAT SW SM2 is disabled, using OpenSSL SW"); # ifndef QAT_OPENSSL_3 return (EVP_PKEY_METHOD *)sw_sm2_pmeth; # else /* Although QAT Engine supports software fallback to the default provider when * using the OpenSSL 3 legacy engine API, if it fails during the registration * phase, the pkey method cannot be set correctly because the OpenSSL3 legacy * engine framework no longer provides a standard method for HKDF, PRF and SM2. * https://github.com/openssl/openssl/issues/19047 */ qat_openssl3_sm2_fallback = 1; qat_sm2_pkey_methods(); # endif } # endif /* ENABLE_QAT_SW_SM2 */ #endif /* QAT_OPENSSL_PROVIDER */ return _hidden_sm2_pmeth; } #endif void qat_create_ciphers(void) { int i; /* free the old method while algorithm reload */ if (qat_reload_algo) qat_free_ciphers(); for (i = 0; i < num_cc; i++) { if (info[i].cipher == NULL) { switch (info[i].nid) { # if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) case NID_aes_128_gcm: case NID_aes_192_gcm: case NID_aes_256_gcm: info[i].cipher = (EVP_CIPHER *) qat_create_gcm_cipher_meth(info[i].nid, info[i].keylen); break; #endif # if defined(ENABLE_QAT_SW_SM4_CBC) || defined(ENABLE_QAT_HW_SM4_CBC) case NID_sm4_cbc: info[i].cipher = (EVP_CIPHER *) qat_create_sm4_cbc_cipher_meth(info[i].nid, info[i].keylen); break; #endif # ifdef ENABLE_QAT_SW_SM4_GCM case NID_sm4_gcm: info[i].cipher = (EVP_CIPHER *) qat_create_sm4_gcm_cipher_meth(info[i].nid, info[i].keylen); break; #endif #ifdef ENABLE_QAT_SW_SM4_CCM case NID_sm4_ccm: info[i].cipher = (EVP_CIPHER *) qat_create_sm4_ccm_cipher_meth(info[i].nid, info[i].keylen); break; #endif #ifdef QAT_HW # ifdef ENABLE_QAT_HW_CHACHAPOLY case NID_chacha20_poly1305: info[i].cipher = (EVP_CIPHER *) chachapoly_cipher_meth(info[i].nid, info[i].keylen); break; # endif # ifdef ENABLE_QAT_HW_CIPHERS # ifdef QAT_INSECURE_ALGO case NID_aes_128_cbc_hmac_sha1: case NID_aes_256_cbc_hmac_sha1: case NID_aes_128_cbc_hmac_sha256: # endif case NID_aes_256_cbc_hmac_sha256: info[i].cipher = (EVP_CIPHER *) qat_create_cipher_meth(info[i].nid, info[i].keylen); break; # endif # ifdef ENABLE_QAT_HW_CCM case NID_aes_128_ccm: case NID_aes_192_ccm: case NID_aes_256_ccm: info[i].cipher = (EVP_CIPHER *) qat_create_ccm_cipher_meth(info[i].nid, info[i].keylen); break; # endif #endif default: /* Do nothing */ break; } } } } void qat_free_ciphers(void) { int i; for (i = 0; i < num_cc; i++) { if (info[i].cipher != NULL) { switch (info[i].nid) { case NID_aes_128_gcm: case NID_aes_192_gcm: case NID_aes_256_gcm: #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) EVP_CIPHER_meth_free(info[i].cipher); #endif #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload && info[i].nid != NID_aes_192_gcm) EVP_CIPHER_meth_free(info[i].cipher); #endif break; #if (defined ENABLE_QAT_SW_SM4_CBC) || (defined ENABLE_QAT_HW_SM4_CBC) case NID_sm4_cbc: if (qat_sw_sm4_cbc_offload || qat_hw_sm4_cbc_offload) EVP_CIPHER_meth_free(info[i].cipher); break; #endif #ifdef ENABLE_QAT_SW_SM4_GCM case NID_sm4_gcm: if (qat_sw_sm4_gcm_offload) EVP_CIPHER_meth_free(info[i].cipher); break; #endif #ifdef ENABLE_QAT_SW_SM4_CCM case NID_sm4_ccm: if (qat_sw_sm4_ccm_offload) EVP_CIPHER_meth_free(info[i].cipher); break; #endif #ifdef ENABLE_QAT_HW_CHACHAPOLY case NID_chacha20_poly1305: if (qat_hw_chacha_poly_offload) EVP_CIPHER_meth_free(info[i].cipher); break; #endif #ifdef ENABLE_QAT_HW_CIPHERS # ifdef QAT_INSECURE_ALGO case NID_aes_128_cbc_hmac_sha1: case NID_aes_256_cbc_hmac_sha1: case NID_aes_128_cbc_hmac_sha256: # endif case NID_aes_256_cbc_hmac_sha256: if (qat_hw_aes_cbc_hmac_sha_offload) EVP_CIPHER_meth_free(info[i].cipher); break; #endif #ifdef ENABLE_QAT_HW_CCM case NID_aes_128_ccm: #if defined(QAT20_OOT) || defined(QAT_HW_INTREE) \ || defined(QAT_HW_FBSD_OOT) || defined(QAT_HW_FBSD_INTREE) case NID_aes_192_ccm: case NID_aes_256_ccm: #endif if (qat_hw_aes_ccm_offload) EVP_CIPHER_meth_free(info[i].cipher); break; #endif } info[i].cipher = NULL; } } qat_hw_gcm_offload = 0; qat_sw_gcm_offload = 0; qat_hw_chacha_poly_offload = 0; qat_hw_aes_cbc_hmac_sha_offload = 0; qat_hw_sm4_cbc_offload = 0; qat_sw_sm4_cbc_offload = 0; qat_sm4_cbc_coexist = 0; qat_sw_sm4_gcm_offload = 0; qat_sw_sm4_ccm_offload = 0; qat_hw_aes_ccm_offload = 0; } /****************************************************************************** * function: * qat_ciphers(ENGINE *e, * const EVP_CIPHER **cipher, * const int **nids, * int nid) * * @param e [IN] - OpenSSL engine pointer * @param cipher [IN] - cipher structure pointer * @param nids [IN] - cipher function nids * @param nid [IN] - cipher operation id * * description: * Qat engine cipher operations registrar ******************************************************************************/ # ifndef QAT_OPENSSL_PROVIDER int qat_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid) { int i; if (unlikely((nids == NULL) && ((cipher == NULL) || (nid < 0)))) { WARN("Invalid input param.\n"); if (cipher != NULL) *cipher = NULL; return 0; } /* No specific cipher => return a list of supported nids ... */ if (cipher == NULL) { *nids = qat_cipher_nids; /* num ciphers supported (size of array/size of 1 element) */ return (sizeof(qat_cipher_nids) / sizeof(qat_cipher_nids[0])); } for (i = 0; i < num_cc; i++) { if (nid == info[i].nid) { if (info[i].cipher == NULL) qat_create_ciphers(); *cipher = info[i].cipher; return 1; } } WARN("NID %d not supported\n", nid); *cipher = NULL; return 0; } # endif #endif # ifndef QAT_OPENSSL_PROVIDER EC_KEY_METHOD *qat_get_EC_methods(void) { if (qat_ec_method != NULL && !qat_reload_algo) return qat_ec_method; EC_KEY_METHOD *def_ec_meth = (EC_KEY_METHOD *)EC_KEY_get_default_method(); PFUNC_SIGN sign_pfunc = NULL; #ifndef QAT_BORINGSSL PFUNC_SIGN_SETUP sign_setup_pfunc = NULL; #endif /* QAT_BORINGSSL */ PFUNC_SIGN_SIG sign_sig_pfunc = NULL; PFUNC_VERIFY verify_pfunc = NULL; PFUNC_VERIFY_SIG verify_sig_pfunc = NULL; #ifndef QAT_BORINGSSL PFUNC_COMP_KEY comp_key_pfunc = NULL; PFUNC_GEN_KEY gen_key_pfunc = NULL; #endif /* QAT_BORINGSSL */ qat_free_EC_methods(); if ((qat_ec_method = EC_KEY_METHOD_new(qat_ec_method)) == NULL) { WARN("Unable to allocate qat EC_KEY_METHOD\n"); QATerr(QAT_F_QAT_GET_EC_METHODS, QAT_R_QAT_GET_EC_METHOD_MALLOC_FAILURE); return NULL; } #ifdef ENABLE_QAT_HW_ECDSA if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_ECDSA)) { #ifndef QAT_BORINGSSL EC_KEY_METHOD_set_sign(qat_ec_method, qat_ecdsa_sign, NULL, qat_ecdsa_do_sign); #else /* QAT_BORINGSSL */ EC_KEY_METHOD_set_sign(qat_ec_method, qat_ecdsa_sign_bssl, NULL, qat_ecdsa_do_sign); #endif /* QAT_BORINGSSL */ EC_KEY_METHOD_set_verify(qat_ec_method, qat_ecdsa_verify, qat_ecdsa_do_verify); qat_hw_ecdsa_offload = 1; DEBUG("QAT HW ECDSA Registration succeeded\n"); # ifdef ENABLE_QAT_SW_ECDSA if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECDSA) && (mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P384) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P384))) { qat_ecdsa_coexist = 1; DEBUG("QAT ECDSA HW&SW Coexistence is enabled \n"); } # endif } else { qat_hw_ecdsa_offload = 0; DEBUG("QAT HW ECDSA is disabled\n"); } #endif #ifdef ENABLE_QAT_SW_ECDSA if (qat_sw_offload && !qat_hw_ecdsa_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECDSA) && (mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P384) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P384))) { #ifndef QAT_BORINGSSL EC_KEY_METHOD_set_sign(qat_ec_method, mb_ecdsa_sign, mb_ecdsa_sign_setup, mb_ecdsa_sign_sig); #else /* QAT_BORINGSSL */ EC_KEY_METHOD_set_sign(qat_ec_method, mb_ecdsa_sign_bssl, NULL, NULL); #endif #ifdef QAT_BORINGSSL EC_KEY_METHOD_get_verify(def_ec_meth, &verify_pfunc, &verify_sig_pfunc); EC_KEY_METHOD_set_verify(qat_ec_method, verify_pfunc, verify_sig_pfunc); #else EC_KEY_METHOD_set_verify(qat_ec_method, mb_ecdsa_verify, mb_ecdsa_do_verify); #endif qat_sw_ecdsa_offload = 1; DEBUG("QAT SW ECDSA registration succeeded\n"); } else { qat_sw_ecdsa_offload = 0; DEBUG("QAT SW ECDSA is disabled\n"); } #endif if ((qat_hw_ecdsa_offload == 0) && (qat_sw_ecdsa_offload == 0)) { EC_KEY_METHOD_get_sign(def_ec_meth, &sign_pfunc, &sign_setup_pfunc, &sign_sig_pfunc); EC_KEY_METHOD_set_sign(qat_ec_method, sign_pfunc, sign_setup_pfunc, sign_sig_pfunc); EC_KEY_METHOD_get_verify(def_ec_meth, &verify_pfunc, &verify_sig_pfunc); EC_KEY_METHOD_set_verify(qat_ec_method, verify_pfunc, verify_sig_pfunc); DEBUG("QAT_HW and QAT_SW ECDSA not supported! Using OpenSSL SW method\n"); } #ifndef QAT_BORINGSSL #ifdef ENABLE_QAT_HW_ECDH if (qat_hw_offload&& (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_ECDH)) { EC_KEY_METHOD_set_keygen(qat_ec_method, qat_ecdh_generate_key); EC_KEY_METHOD_set_compute_key(qat_ec_method, qat_engine_ecdh_compute_key); qat_hw_ecdh_offload = 1; DEBUG("QAT HW ECDH Registration succeeded\n"); # ifdef ENABLE_QAT_SW_ECDH if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECDH) && (mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P384) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P384))) { qat_ecdh_coexist = 1; DEBUG("QAT ECDH HW&SW Coexistence is enabled \n"); } # endif } else { qat_hw_ecdh_offload = 0; DEBUG("QAT HW ECDH disabled\n"); } #endif #ifdef ENABLE_QAT_SW_ECDH if (qat_sw_offload && !qat_hw_ecdh_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECDH) && (mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDHE_NIST_P384) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P256) && mbx_get_algo_info(MBX_ALGO_ECDSA_NIST_P384))) { EC_KEY_METHOD_set_keygen(qat_ec_method, mb_ecdh_generate_key); EC_KEY_METHOD_set_compute_key(qat_ec_method, mb_ecdh_compute_key); qat_sw_ecdh_offload = 1; DEBUG("QAT SW ECDH registration succeeded\n"); } else { qat_sw_ecdh_offload = 0; DEBUG("QAT SW ECDH disabled\n"); } #endif if ((qat_hw_ecdh_offload == 0) && (qat_sw_ecdh_offload == 0)) { EC_KEY_METHOD_get_keygen(def_ec_meth, &gen_key_pfunc); EC_KEY_METHOD_set_keygen(qat_ec_method, gen_key_pfunc); EC_KEY_METHOD_get_compute_key(def_ec_meth, &comp_key_pfunc); EC_KEY_METHOD_set_compute_key(qat_ec_method, comp_key_pfunc); DEBUG("QAT_HW and QAT_SW ECDH not supported! Using OpenSSL SW method\n"); } #endif /* QAT_BORINGSSL */ return qat_ec_method; } void qat_free_EC_methods(void) { if (NULL != qat_ec_method) { EC_KEY_METHOD_free(qat_ec_method); qat_ec_method = NULL; qat_hw_ecdh_offload = 0; qat_hw_ecdsa_offload = 0; qat_sw_ecdh_offload = 0; qat_sw_ecdsa_offload = 0; qat_ecdsa_coexist = 0; qat_ecdh_coexist = 0; } } RSA_METHOD *qat_get_RSA_methods(void) { #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) int res = 1; #endif RSA_METHOD *def_rsa_method = NULL; if (qat_rsa_method != NULL && !qat_reload_algo) return qat_rsa_method; qat_free_RSA_methods(); if ((qat_rsa_method = RSA_meth_new("QAT RSA method", 0)) == NULL) { WARN("Failed to allocate QAT RSA methods\n"); QATerr(QAT_F_QAT_GET_RSA_METHODS, QAT_R_ALLOC_QAT_RSA_METH_FAILURE); return NULL; } #ifdef ENABLE_QAT_HW_RSA if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_RSA)) { #ifdef QAT_BORINGSSL res &= RSA_meth_set_priv_bssl(qat_rsa_method, qat_rsa_priv_sign, qat_rsa_priv_decrypt); #else /* QAT OpenSSL */ res &= RSA_meth_set_pub_enc(qat_rsa_method, qat_rsa_pub_enc); res &= RSA_meth_set_pub_dec(qat_rsa_method, qat_rsa_pub_dec); res &= RSA_meth_set_priv_enc(qat_rsa_method, qat_rsa_priv_enc); res &= RSA_meth_set_priv_dec(qat_rsa_method, qat_rsa_priv_dec); res &= RSA_meth_set_mod_exp(qat_rsa_method, qat_rsa_mod_exp); res &= RSA_meth_set_bn_mod_exp(qat_rsa_method, BN_mod_exp_mont); res &= RSA_meth_set_init(qat_rsa_method, qat_rsa_init); res &= RSA_meth_set_finish(qat_rsa_method, qat_rsa_finish); #endif /* QAT_BORINGSSL */ if (!res) { WARN("Failed to set QAT RSA methods\n"); QATerr(QAT_F_QAT_GET_RSA_METHODS, QAT_R_SET_QAT_RSA_METH_FAILURE); qat_hw_rsa_offload = 0; return NULL; } qat_hw_rsa_offload = 1; DEBUG("QAT HW RSA Registration succeeded\n"); # ifdef ENABLE_QAT_SW_RSA if (qat_sw_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_RSA) && mbx_get_algo_info(MBX_ALGO_RSA_2K) && mbx_get_algo_info(MBX_ALGO_RSA_3K) && mbx_get_algo_info(MBX_ALGO_RSA_4K)) { qat_rsa_coexist = 1; DEBUG("QAT RSA HW&SW Coexistence is enabled \n"); } # endif } else { qat_hw_rsa_offload = 0; DEBUG("QAT HW RSA is disabled\n"); } #endif #ifdef ENABLE_QAT_SW_RSA if (qat_sw_offload && !qat_hw_rsa_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_RSA) && mbx_get_algo_info(MBX_ALGO_RSA_2K) && mbx_get_algo_info(MBX_ALGO_RSA_3K) && mbx_get_algo_info(MBX_ALGO_RSA_4K)) { #ifdef QAT_BORINGSSL res &= RSA_meth_set_priv_bssl(qat_rsa_method, mb_bssl_rsa_priv_sign, mb_bssl_rsa_priv_decrypt); #else res &= RSA_meth_set_priv_enc(qat_rsa_method, multibuff_rsa_priv_enc); res &= RSA_meth_set_priv_dec(qat_rsa_method, multibuff_rsa_priv_dec); res &= RSA_meth_set_pub_enc(qat_rsa_method, multibuff_rsa_pub_enc); res &= RSA_meth_set_pub_dec(qat_rsa_method, multibuff_rsa_pub_dec); res &= RSA_meth_set_bn_mod_exp(qat_rsa_method, RSA_meth_get_bn_mod_exp(RSA_PKCS1_OpenSSL())); res &= RSA_meth_set_mod_exp(qat_rsa_method, RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL())); res &= RSA_meth_set_init(qat_rsa_method, multibuff_rsa_init); res &= RSA_meth_set_finish(qat_rsa_method, multibuff_rsa_finish); #endif /* QAT_BORINGSSL */ if (!res) { WARN("Failed to set SW RSA methods\n"); QATerr(QAT_F_QAT_GET_RSA_METHODS, QAT_R_SET_MULTIBUFF_RSA_METH_FAILURE); qat_sw_rsa_offload = 0; return NULL; } qat_sw_rsa_offload = 1; DEBUG("QAT SW RSA Registration succeeded\n"); } else { qat_sw_rsa_offload = 0; DEBUG("QAT SW RSA is disabled\n"); } #endif if ((qat_hw_rsa_offload == 0) && (qat_sw_rsa_offload == 0)) { def_rsa_method = (RSA_METHOD *)RSA_get_default_method(); DEBUG("QAT_HW and QAT_SW RSA not supported! Using OpenSSL SW method\n"); return def_rsa_method; } return qat_rsa_method; } void qat_free_RSA_methods(void) { if (qat_rsa_method != NULL) { RSA_meth_free(qat_rsa_method); qat_rsa_method = NULL; qat_hw_rsa_offload = 0; qat_sw_rsa_offload = 0; qat_rsa_coexist = 0; } } #endif #ifdef QAT_BORINGSSL EC_KEY_METHOD *bssl_get_default_EC_methods(void) { return &null_ecdsa_method; } RSA_METHOD *bssl_get_default_RSA_methods(void) { return &null_rsa_method; } int RSA_private_encrypt_default(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding) { int ret = 0; size_t rsa_len = 0; rsa_len = RSA_size(rsa); RSA_METHOD *origin_meth = rsa->meth; rsa->meth = bssl_get_default_RSA_methods(); ret = RSA_sign_raw(rsa, &rsa_len, to, rsa_len, from, flen, padding); rsa->meth = origin_meth; if (ret == 0) { return -1; } return rsa_len; } int RSA_private_decrypt_default(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding) { int ret = 0; size_t rsa_len = 0; rsa_len = RSA_size(rsa); RSA_METHOD *origin_meth = rsa->meth; rsa->meth = bssl_get_default_RSA_methods(); ret = RSA_decrypt(rsa, &rsa_len, to, rsa_len, from, flen, padding); rsa->meth = origin_meth; if (ret == 0) { return -1; } return rsa_len; } #endif /* QAT_BORINGSSL */ #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifndef QAT_BORINGSSL /****************************************************************************** * function: * qat_pkt_threshold_table_set_threshold(const char *cn, int threshold) * * @param cn [IN] - Object contains EVP operation id * @param threshold [IN] - Threshold packet size * * description: * Sets Threshold Packet Size for Small Packet Offload ******************************************************************************/ int qat_pkt_threshold_table_set_threshold(const char *cn , int threshold) { int i = 0; int nid; if(threshold < 0) threshold = 0; else if (threshold > 16384) threshold = 16384; DEBUG("Set small packet threshold for %s: %d\n", cn, threshold); nid = OBJ_sn2nid(cn); for (i = 0; i < pkt_threshold_table_size; i++) { if (qat_pkt_threshold_table[i].nid == nid) { qat_pkt_threshold_table[i].threshold = threshold; return 1; } } WARN("nid %d not found in threshold table\n", nid); return 0; } /****************************************************************************** * function: * qat_pkt_threshold_table_get_threshold(int nid) * * @param nid [IN] - EVP operation id * * description: * Gets Threshold Packet Size for Small Packet Offload ******************************************************************************/ int qat_pkt_threshold_table_get_threshold(int nid) { int i = 0; for (i = 0; i < pkt_threshold_table_size; i++) { if (qat_pkt_threshold_table[i].nid == nid) { return qat_pkt_threshold_table[i].threshold; } } WARN("nid %d not found in threshold table", nid); return 0; } # endif /* QAT_BORINGSSL */ #endif qatengine-1.9.0/qat_evp.h000066400000000000000000000174201500416242000153020ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2019-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_evp.h * * This file provides an interface for PRF and HKDF operations * *****************************************************************************/ #ifndef QAT_EVP_H # define QAT_EVP_H # include # include "e_qat.h" # define AES_KEY_SIZE_128 16 # define AES_KEY_SIZE_192 24 # define AES_KEY_SIZE_256 32 # define AES_GCM_BLOCK_SIZE 1 # define AES_CCM_BLOCK_SIZE 1 # define CHACHA_KEY_SIZE 32 typedef int (*PFUNC_COMP_KEY)(unsigned char **, size_t *, const EC_POINT *, const EC_KEY *); typedef int (*PFUNC_GEN_KEY)(EC_KEY *); #ifdef QAT_BORINGSSL typedef int (*PFUNC_SIGN)(const uint8_t *, size_t, uint8_t *, unsigned int *, EC_KEY *); #else /* QAT_BORINGSSL */ typedef int (*PFUNC_SIGN)(int, const unsigned char *, int, unsigned char *, unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *); #endif /* QAT_BORINGSSL */ typedef int (*PFUNC_SIGN_SETUP)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **); typedef ECDSA_SIG *(*PFUNC_SIGN_SIG)(const unsigned char *, int, const BIGNUM *, const BIGNUM *, EC_KEY *); typedef int (*PFUNC_VERIFY)(int, const unsigned char *, int, const unsigned char *, int, EC_KEY *); typedef int (*PFUNC_VERIFY_SIG)(const unsigned char *, int, const ECDSA_SIG *, EC_KEY *eckey); #ifndef QAT_BORINGSSL extern const EVP_PKEY_METHOD *sw_x25519_pmeth; extern const EVP_PKEY_METHOD *sw_x448_pmeth; # ifdef ENABLE_QAT_HW_ECX # ifndef QAT_OPENSSL_PROVIDER int qat_pkey_ecx25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); int qat_pkey_ecx448_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); int qat_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); int qat_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); int qat_pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); # else void *qat_pkey_ecx25519_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg); void *qat_pkey_ecx448_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg); int qat_pkey_ecx_derive25519(void *ctx, unsigned char *key, size_t *keylen, size_t outlen); int qat_pkey_ecx_derive448(void *ctx, unsigned char *key, size_t *keylen, size_t outlen); # endif # endif # ifdef ENABLE_QAT_SW_ECX # ifndef QAT_OPENSSL_PROVIDER int multibuff_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); int multibuff_x25519_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); int multibuff_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); # else void* multibuff_x25519_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg); int multibuff_x25519_derive(void *ctx, unsigned char *key, size_t *keylen, size_t outlen); # endif # endif # ifdef ENABLE_QAT_SW_SM3 # ifndef QAT_OPENSSL_PROVIDER int qat_sw_sm3_init(EVP_MD_CTX *ctx); int qat_sw_sm3_update(EVP_MD_CTX *ctx, const void *in, size_t len); int qat_sw_sm3_final(EVP_MD_CTX *ctx, unsigned char *md); # else int qat_sw_sm3_init(QAT_SM3_CTX_mb *ctx); int qat_sw_sm3_update(QAT_SM3_CTX_mb *ctx, const void *in, size_t len); int qat_sw_sm3_final(QAT_SM3_CTX_mb *ctx, unsigned char *md); # endif # endif # if defined(ENABLE_QAT_SW_SM2) || defined(ENABLE_QAT_HW_SM2) extern const EVP_PKEY_METHOD *sw_sm2_pmeth; EVP_PKEY_METHOD *qat_create_sm2_pmeth(void); # endif int qat_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids, int nid); EVP_PKEY_METHOD *qat_prf_pmeth(void); EVP_PKEY_METHOD *qat_hkdf_pmeth(void); EVP_PKEY_METHOD *qat_x25519_pmeth(void); EVP_PKEY_METHOD *qat_x448_pmeth(void); void qat_create_digest_meth(void); void qat_free_digest_meth(void); int qat_digest_methods(ENGINE *e, const EVP_MD **md, const int **nids, int nid); void qat_create_ciphers(void); void qat_free_ciphers(void); int qat_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); const EVP_CIPHER *qat_create_gcm_cipher_meth(int nid, int keylen); const EVP_CIPHER *qat_create_ccm_cipher_meth(int nid, int keylen); const EVP_CIPHER *qat_gcm_cipher_sw_impl(int nid); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # define CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT 2048 # define CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_SM4_CBC 64 # define CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_HW_SM3 1024 int qat_pkt_threshold_table_set_threshold(const char *cn , int threshold); int qat_pkt_threshold_table_get_threshold(int nid); # endif #endif /* QAT_BORINGSSL */ EC_KEY_METHOD *qat_get_EC_methods(void); void qat_free_EC_methods(void); RSA_METHOD *qat_get_RSA_methods(void); void qat_free_RSA_methods(void); #ifdef QAT_BORINGSSL EC_KEY_METHOD *bssl_get_default_EC_methods(void); RSA_METHOD *bssl_get_default_RSA_methods(void); int RSA_private_encrypt_default(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding); int RSA_private_decrypt_default(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding); #endif /* QAT_BORINGSSL */ #ifdef ENABLE_QAT_HW_CCM const EVP_CIPHER *qat_ccm_cipher_sw_impl(int nid); #endif /* ENABLE_QAT_HW_CCM */ #endif /* QAT_EVP_H */ qatengine-1.9.0/qat_fips.c000066400000000000000000001357521500416242000154550ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_fips.c * * This file provides an implementation to perform qat fips test * *****************************************************************************/ #include "qat_fips.h" #define ENABLE_FIPS 1 #define ASYNC_JOBS 8 #define BUFFERSIZE 8192 #define SM_KEY 0x00102F #ifdef ENABLE_QAT_FIPS char *prov_id = "qatprovider"; static OSSL_PROVIDER *provider = NULL; OSSL_LIB_CTX *provctx = NULL; OSSL_SELF_TEST *st = NULL; OSSL_CALLBACK *cb = self_test_events; void *cbarg; static int enable_ondemand = 0; static int enable_async = 0; static int async_jobs = 1; static int sign_only = 0; static int verify_only = 0; static int encrypt_only = 0; static int decrypt_only = 0; int integrity_status = 1; void *smem_ptr; int smem_id; static char *self_test_corrupt_desc = NULL; static char *self_test_corrupt_type = NULL; QAT_SELF_TEST_RESULT *qat_signature_result; QAT_SELF_TEST_RESULT *qat_kas_result; QAT_SELF_TEST_RESULT *qat_cipher_result; QAT_SELF_TEST_RESULT *qat_digest_result; QAT_SELF_TEST_RESULT *qat_kdf_result; QAT_SELF_TEST_RESULT *qat_async_signature_result; QAT_SELF_TEST_RESULT *qat_async_kas_result; QAT_SELF_TEST_RESULT *qat_async_cipher_result; QAT_SELF_TEST_RESULT *qat_async_digest_result; QAT_SELF_TEST_RESULT *qat_async_kdf_result; void fips_result(void) { int i; # ifdef QAT_DEBUG INFO("\nQAT Provider FIPS Self Test Application"); if (enable_ondemand) INFO("\n=================== On-demand self tests result ===========\n"); INFO("\nOperation type: %s\n\n", "Synchronous"); # endif for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_dsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "DSA")) || (qat_hw_rsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "RSA")) || (qat_hw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP256")) || (qat_hw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP384"))) continue; } else { if ((qat_hw_dsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "DSA")) || (qat_sw_rsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "RSA")) || (qat_sw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP256")) || (qat_sw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP384"))) continue; } # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_signature_result->desc[i], qat_signature_result->type[i], qat_signature_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_signature_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_kas_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_dh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "DH")) || (qat_hw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP256")) || (qat_hw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP384")) || (qat_hw_ecx_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX25519")) || (qat_hw_ecx_448_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX448"))) continue; } else { if ((qat_hw_dh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "DH")) || (qat_sw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP256")) || (qat_sw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP384")) || (qat_sw_ecx_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX25519")) || (qat_hw_ecx_448_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX448"))) continue; } # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_kas_result->desc[i], qat_kas_result->type[i], qat_kas_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_kas_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_gcm_offload == 0 && !strcmp(st_kat_cipher_tests[i].base.desc, "AES_GCM"))) continue; } else { if ((qat_sw_gcm_offload == 0 && !strcmp(st_kat_cipher_tests[i].base.desc, "AES_GCM"))) continue; } # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_cipher_result->desc[i], qat_cipher_result->type[i], qat_cipher_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_cipher_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) { if ((qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXTRACT_256")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXPAND_256")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXTRACT_384")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXPAND_384")) || (qat_hw_prf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS12_PRF_256")) || (qat_hw_prf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS12_PRF_384"))) continue; # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_kdf_result->desc[i], qat_kdf_result->type[i], qat_kdf_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_kdf_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) { if (qat_hw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA3")) continue; if (qat_sw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA256")) continue; if (qat_sw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA512")) continue; # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_digest_result->desc[i], qat_digest_result->type[i], qat_digest_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_digest_result->result[i]) integrity_status = 0; } if (enable_async) { # ifdef QAT_DEBUG INFO("\nOperation type: %s\n", "Asynchronous"); INFO("Number of jobs: %d\n\n", async_jobs); # endif for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_dsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "DSA")) || (qat_hw_rsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "RSA")) || (qat_hw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP256")) || (qat_hw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP384"))) continue; } else { if ((qat_hw_dsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "DSA")) || (qat_sw_rsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "RSA")) || (qat_sw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP256")) || (qat_sw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP384"))) continue; } # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_async_signature_result->desc[i], qat_async_signature_result->type[i], qat_async_signature_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_async_signature_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_kas_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_dh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "DH")) || (qat_hw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP256")) || (qat_hw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP384")) || (qat_hw_ecx_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX25519")) || (qat_hw_ecx_448_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX448"))) continue; } else { if ((qat_hw_dh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "DH")) || (qat_sw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP256")) || (qat_sw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP384")) || (qat_sw_ecx_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX25519")) || (qat_hw_ecx_448_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX448"))) continue; } # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_async_kas_result->desc[i], qat_async_kas_result->type[i], qat_async_kas_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_async_kas_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_gcm_offload == 0 && !strcmp(st_kat_cipher_tests[i].base.desc, "AES_GCM"))) continue; } else { if ((qat_sw_gcm_offload == 0 && !strcmp(st_kat_cipher_tests[i].base.desc, "AES_GCM"))) continue; } # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_async_cipher_result->desc[i], qat_async_cipher_result->type[i], qat_async_cipher_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_async_cipher_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) { if ((qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXTRACT_256")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXPAND_256")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXTRACT_384")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXPAND_384")) || (qat_hw_prf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS12_PRF_256")) || (qat_hw_prf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS12_PRF_384"))) continue; # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_async_kdf_result->desc[i], qat_async_kdf_result->type[i], qat_async_kdf_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_async_kdf_result->result[i]) integrity_status = 0; } for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) { if (qat_hw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA3")) continue; if (qat_sw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA256")) continue; if (qat_sw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA512")) continue; # ifdef QAT_DEBUG INFO("\t%s : (%s) : %s\n", qat_async_digest_result->desc[i], qat_async_digest_result->type[i], qat_async_digest_result->result[i] ? "PASS" : "FAIL"); # endif if (!qat_async_digest_result->result[i]) integrity_status = 0; } } # ifdef QAT_DEBUG if (!enable_ondemand) INFO("\n===================QAT_SELF_TEST RESULT=====================\n"); else INFO("\n=================== On-demand self tests completed===========\n"); # endif free(qat_signature_result); free(qat_kas_result); free(qat_cipher_result); free(qat_digest_result); free(qat_kdf_result); if (enable_async) { free(qat_async_signature_result); free(qat_async_kas_result); free(qat_async_cipher_result); free(qat_async_digest_result); free(qat_async_kdf_result); } enable_async = 0; async_jobs = 1; ERR_clear_error(); } void removeChar(char *s, char c) { int j, n = strlen(s); for (int i = j = 0; i < n; i++) { if (s[i] != c) s[j++] = s[i]; } s[j] = '\0'; } int readFileToHexString(char **hex_string, const char *filepath, int *len) { FILE *fp = fopen(filepath, "r"); if (fp == NULL) { WARN("Input file:%s don't exist \n", filepath); return 1; } if (fseek(fp, 0L, SEEK_END) == 0) { /* Set position at end of file */ long hex_string_size = ftell(fp); if (hex_string_size == -1) { WARN("Input file corrupted\n"); return 2; } (*hex_string) = (char *)malloc(sizeof(char) * (hex_string_size + 1)); /* Set position at befining of file */ fseek(fp, 0L, SEEK_SET); size_t newLen = fread((*hex_string), sizeof(unsigned char), hex_string_size, fp); if (ferror(fp) != 0) { WARN("Error while reading file\n"); return 3; } (*hex_string)[newLen] = '\0'; /* to make sure it's NULL-terminated */ *len = hex_string_size; } fclose(fp); return 0; } int get_pub_key_from_file(char *in_name, unsigned char *out) { FILE *in_file = NULL, *fp = NULL; char word[500]; char pub_fname[16] = "pub.txt"; int flag = 0; int i = 0, msg_len = 0, result = 0, size;; char *msg; int sys_ret = 0; in_file = fopen(in_name, "r"); if (in_file == NULL) WARN("Can't open %s for reading.\n", in_name); else { while (fscanf(in_file, "%s", word) != EOF) { if (!strcmp(word, "pub:")) { flag = 1; fp = fopen(pub_fname, "w+"); } if (!strcmp(word, "ASN1")) { flag = 0; if (fp) fclose(fp); } if (flag && strcmp(word, "pub:")) { removeChar(word, ':'); fprintf(fp, "%s", word); } } fclose(in_file); } result = readFileToHexString(&msg, pub_fname, &msg_len); sys_ret = remove("pub.txt"); if (sys_ret != 0) WARN("System process failure\n"); if (result != 0) return result; size = (msg_len + 1) / 2; for (i = 0; i < size; i++) { sscanf(msg, "%02hhx", &out[i]); msg = msg + 2; } return 1; } int self_test_events(const OSSL_PARAM params[], void *arg) { const OSSL_PARAM *p = NULL; const char *phase = NULL, *type = NULL, *desc = NULL; int ret = 0; p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE); if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) goto err; phase = (const char *)p->data; p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC); if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) goto err; desc = (const char *)p->data; p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE); if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) goto err; type = (const char *)p->data; if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0) DEBUG("Self test start phase %s : (%s)\n", desc, type); else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0 || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0) DEBUG("Self test phase : %s \n", phase); /* * The self test code will internally corrupt the KAT test result if an * error is returned during the corrupt phase. */ if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0 && (self_test_corrupt_desc != NULL || self_test_corrupt_type != NULL)) { if (self_test_corrupt_desc != NULL && strcmp(self_test_corrupt_desc, desc) != 0) goto end; if (self_test_corrupt_type != NULL && strcmp(self_test_corrupt_type, type) != 0) goto end; WARN("Error in oncorrupt phase : %s \n", phase); goto err; } end: ret = 1; err: return ret; } int FMT_istext(int format) { return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT; } BIO *dup_bio_in(int format) { return BIO_new_fp(stdin, BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); } BIO *dup_bio_out(int format) { BIO *b = BIO_new_fp(stdout, BIO_NOCLOSE | (FMT_istext(format) ? BIO_FP_TEXT : 0)); void *prefix = NULL; if (FMT_istext(format) && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) { b = BIO_push(BIO_new(BIO_f_prefix()), b); BIO_set_prefix(b, prefix); } return b; } static const char *modestr(char mode, int format) { OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w'); switch (mode) { case 'a': return FMT_istext(format) ? "a" : "ab"; case 'r': return FMT_istext(format) ? "r" : "rb"; case 'w': return FMT_istext(format) ? "w" : "wb"; } /* The assert above should make sure we never reach this point */ return NULL; } static BIO *bio_open_default_(const char *filename, char mode, int format, int quiet) { BIO *ret; if (filename == NULL || strcmp(filename, "-") == 0) { ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format); if (quiet) { ERR_clear_error(); return ret; } if (ret != NULL) return ret; } else { ret = BIO_new_file(filename, modestr(mode, format)); if (quiet) { return ret; } if (ret != NULL) return ret; } return NULL; } BIO *bio_open_default(const char *filename, char mode, int format) { return bio_open_default_(filename, mode, format, 0); } static int test_callback(void *arg) { struct async_args_callback *args = (struct async_args_callback *)arg; DEBUG("test_callback start for async_job %d - job_ready = %d\n", args->i, args->job_ready); args->job_ready = 1; DEBUG("test_callback finish for async_job %d - job_ready = %d\n", args->i, args->job_ready); return 1; } int start_async_job(TEST_PARAMS *args, int (*func)(void *)) { int ret = 0; int jobs_inprogress = 0; int i = 0; OSSL_ASYNC_FD job_fd = 0; OSSL_ASYNC_FD max_fd = 0; int select_result = 0; size_t numfds; fd_set waitfdset; struct timeval select_timeout; FD_ZERO(&waitfdset); select_timeout.tv_sec = 0; select_timeout.tv_usec = 0; struct async_args_callback **ptr_async_args_callback = NULL; DEBUG("start_async_job() - start\n"); if (args->use_callback_mode == 1) { ptr_async_args_callback = (struct async_args_callback **) OPENSSL_zalloc(sizeof(struct async_args_callback *) * args->async_jobs); if (ptr_async_args_callback == NULL) { WARN("Error allocating memory for ptr_async_args_callback.\n"); return ret; } for (i = 0; i < args->async_jobs; i++) { ptr_async_args_callback[i] = (struct async_args_callback *) OPENSSL_zalloc(sizeof(struct async_args_callback)); if (ptr_async_args_callback[i] == NULL) { WARN("Error allocating memory for ptr_async_args_callback.\n"); return ret; } } } for (i = 0; i < args->async_jobs; i++) { if (args->use_callback_mode == 1) { ptr_async_args_callback[i]->i = i; if (ASYNC_WAIT_CTX_set_callback(args->awcs[i], test_callback, (void *)ptr_async_args_callback[i]) != 1) { WARN("# FAIL: Error setting callback.\n"); return ret; } } switch (ASYNC_start_job(&args->jobs[i], args->awcs[i], &ret, func, args, sizeof(TEST_PARAMS))) { case ASYNC_ERR: case ASYNC_NO_JOBS: DEBUG("ASYNC_ERR \n"); break; case ASYNC_PAUSE: ++jobs_inprogress; DEBUG("ASYNC_PAUSE \n"); break; case ASYNC_FINISH: DEBUG("ASYNC_FINISH \n"); break; } } while (jobs_inprogress > 0) { if (args->use_callback_mode != 1) { /* Not callback mode so use fd's */ for (i = 0; i < args->async_jobs && jobs_inprogress > 0; i++) { if (args->jobs[i] == NULL) continue; if (!ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], NULL, &numfds) || numfds > 1) { WARN("# FAIL: Too Many FD's in Use\n"); break; } ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], &job_fd, &numfds); FD_SET(job_fd, &waitfdset); if (job_fd > max_fd) max_fd = job_fd; } if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) { WARN("# FAIL: Too many FD's in use in the system already\n"); break; } select_result = select(max_fd + 1, &waitfdset, NULL, NULL, &select_timeout); if (select_result == -1 && errno == EINTR) continue; if (select_result == -1) { WARN("# FAIL: Select Failure \n"); break; } } for (i = 0; i < args->async_jobs; i++) { if (args->jobs[i] == NULL) continue; if (args->use_callback_mode != 1) { /* Not callback mode so use fd's */ if (!ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], NULL, &numfds) || numfds > 1) { WARN("# FAIL: Too Many FD's in Use\n"); break; } ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], &job_fd, &numfds); if (numfds == 1 && !FD_ISSET(job_fd, &waitfdset)) continue; } else { /* in callback mode */ if (ptr_async_args_callback[i]->job_ready == 0) continue; } if (args->use_callback_mode == 1) { /* reset the jobs_ready flag */ DEBUG("Resetting job_ready flag for async_job %d\n", i); ptr_async_args_callback[i]->job_ready = 0; } switch (ASYNC_start_job(&args->jobs[i], args->awcs[i], &ret, func, args, sizeof(TEST_PARAMS))) { case ASYNC_PAUSE: break; case ASYNC_FINISH: --jobs_inprogress; args->jobs[i] = NULL; break; case ASYNC_NO_JOBS: case ASYNC_ERR: --jobs_inprogress; args->jobs[i] = NULL; break; } } } /* while (jobs_inprogress > 0) */ if (ptr_async_args_callback != NULL) { for (i = 0; i < args->async_jobs; i++) { if (ptr_async_args_callback[i] != NULL) OPENSSL_free(ptr_async_args_callback[i]); } OPENSSL_free(ptr_async_args_callback); } DEBUG("start_async_job() returning status = %d\n", ret); return ret; } void kat_tests_run(TEST_PARAMS *args) { struct async_additional_args_rsa extra_args; args->additional_args = &extra_args; extra_args.sign_only = sign_only; extra_args.verify_only = verify_only; extra_args.encrypt_only = encrypt_only; extra_args.decrypt_only = decrypt_only; st = (OSSL_SELF_TEST *) calloc(1, sizeof(OSSL_SELF_TEST)); if (st == NULL) { WARN("Error in OSSL_SELF_TEST memory creation\n"); } st->cb = cb; st->cb_arg = cbarg; st->phase = "start"; args->st = st; if (!args->ondemand) { if (!args->enable_async) QAT_SELF_TEST_kats(args); else start_async_job(args, QAT_SELF_TEST_kats); } if (args->ondemand || integrity_status == 0) { if (!(args->enable_async)) { if (!QAT_SELF_TEST_kats(args)) { INFO("\nQAT On-demand Synch KAT tests failure\n"); } } else { if ((!start_async_job(args, QAT_SELF_TEST_kats))) { INFO("\nQAT On-demand Asynch KAT tests failure\n"); } } } } void kat_self_test_init(int ondemand, int co_existence) { int i; TEST_PARAMS args; args.prov_id = prov_id; args.enable_async = enable_async; args.prov = provider; args.async_jobs = async_jobs; args.cb = cb; args.cb_arg = cbarg; args.phase = "start"; args.provctx = provctx; args.sign_only = sign_only; args.verify_only = verify_only; args.encrypt_only = encrypt_only; args.decrypt_only = decrypt_only; args.ondemand = ondemand; args.co_existence = co_existence; args.jobs = OPENSSL_malloc(sizeof(ASYNC_JOB *) * async_jobs); if (args.jobs == NULL) { WARN("# FAIL: Unable to allocate args.jobs\n"); exit(EXIT_FAILURE); } args.awcs = OPENSSL_malloc(sizeof(ASYNC_WAIT_CTX *) * async_jobs); if (args.awcs == NULL) { WARN("# FAIL: Unable to allocate args.awcs\n"); exit(EXIT_FAILURE); } memset(args.jobs, 0, sizeof(ASYNC_JOB *) * async_jobs); memset(args.awcs, 0, sizeof(ASYNC_WAIT_CTX *) * async_jobs); for (i = 0; i < async_jobs; i++) { args.awcs[i] = ASYNC_WAIT_CTX_new(); if (args.awcs[i] == NULL) { WARN("# FAIL: Unable to allocate args.awcs[%d]\n", i); exit(EXIT_FAILURE); } } kat_tests_run(&args); for (i = 0; i < async_jobs; i++) ASYNC_WAIT_CTX_free(args.awcs[i]); OPENSSL_free(args.awcs); OPENSSL_free(args.jobs); free(args.st); } int qat_fips_self_test(void *qatctx, int ondemand, int co_ex_enabled) { int i, j, sys_ret = 0; BIO *module_bio = NULL, *sig_bio = NULL; char pubkey_file[256] = "public_key.txt"; sys_ret = system ("cp -f /usr/lib64/ossl-modules/qatprovider.so qatprovider_temp.so"); sys_ret = system ("objcopy --dump-section .pub_key=public_key.txt qatprovider_temp.so"); sys_ret = system("objcopy --remove-section .pub_key qatprovider_temp.so"); EVP_MD *md = NULL; int nfile = 0; char *src_files[10] = { 0 }; char *sig_files[10] = { 0 }; char *dump_cmd[10] = { 0 }; char *rmv_cmd[10] = { 0 }; # ifdef QAT_HW char *srmv_cmd[7] = { 0 }; # endif if (co_ex_enabled) { nfile = 10; src_files[0] = "/usr/lib64/build/qat_4xxx.ko"; src_files[1] = "/usr/lib64/build/usdm_drv.ko"; src_files[2] = "/usr/lib64/build/intel_qat.ko"; src_files[3] = "/usr/lib64/libusdm_drv_s.so"; src_files[4] = "/usr/lib64/libqat_s.so"; src_files[5] = "/lib/firmware/qat_4xxx.bin"; src_files[6] = "/lib/firmware/qat_4xxx_mmp.bin"; src_files[7] = "/usr/lib64/libIPSec_MB.so"; src_files[8] = "/usr/lib64/libcrypto_mb.so"; src_files[9] = "qatprovider_temp.so"; sig_files[0] = "qat_4xxx_signature.bin"; sig_files[1] = "usdm_drv_signature.bin"; sig_files[2] = "intel_qat_signature.bin"; sig_files[3] = "usdm_signature.bin"; sig_files[4] = "libqat_signature.bin"; sig_files[5] = "qat_4xxx_bin_signature.bin"; sig_files[6] = "qat_4xxx_mmp_signature.bin"; sig_files[7] = "ipsec_mb_signature.bin"; sig_files[8] = "libcrypto_mb_signature.bin"; sig_files[9] = "qat_signature.bin"; dump_cmd[0] = "objcopy --dump-section .qat_4xxx_sig=qat_4xxx_signature.bin qatprovider_temp.so"; dump_cmd[1] = "objcopy --dump-section .usdm_drv_sig=usdm_drv_signature.bin qatprovider_temp.so"; dump_cmd[2] = "objcopy --dump-section .iqat_sig=intel_qat_signature.bin qatprovider_temp.so"; dump_cmd[3] = "objcopy --dump-section .usdm_sig=usdm_signature.bin qatprovider_temp.so"; dump_cmd[4] = "objcopy --dump-section .libqat_sig=libqat_signature.bin qatprovider_temp.so"; dump_cmd[5] = "objcopy --dump-section .qat_4xxx_bin_sig=qat_4xxx_bin_signature.bin qatprovider_temp.so"; dump_cmd[6] = "objcopy --dump-section .qat_4xxx_mmp_sig=qat_4xxx_mmp_signature.bin qatprovider_temp.so"; dump_cmd[7] = "objcopy --dump-section .ipsec_mb_sig=ipsec_mb_signature.bin qatprovider_temp.so"; dump_cmd[8] = "objcopy --dump-section .libcrypto_mb_sig=libcrypto_mb_signature.bin qatprovider_temp.so"; dump_cmd[9] = "objcopy --dump-section .qat_sig=qat_signature.bin qatprovider_temp.so"; rmv_cmd[0] = "objcopy --remove-section .qat_4xxx_sig qatprovider_temp.so"; rmv_cmd[1] = "objcopy --remove-section .usdm_drv_sig qatprovider_temp.so"; rmv_cmd[2] = "objcopy --remove-section .iqat_sig qatprovider_temp.so"; rmv_cmd[3] = "objcopy --remove-section .usdm_sig qatprovider_temp.so"; rmv_cmd[4] = "objcopy --remove-section .libqat_sig qatprovider_temp.so"; rmv_cmd[5] = "objcopy --remove-section .qat_4xxx_bin_sig qatprovider_temp.so"; rmv_cmd[6] = "objcopy --remove-section .qat_4xxx_mmp_sig qatprovider_temp.so"; rmv_cmd[7] = "objcopy --remove-section .ipsec_mb_sig qatprovider_temp.so"; rmv_cmd[8] = "objcopy --remove-section .libcrypto_mb_sig qatprovider_temp.so"; rmv_cmd[9] = "objcopy --remove-section .qat_sig qatprovider_temp.so"; } else { if (qat_hw_offload) { nfile = 8; src_files[0] = "/usr/lib64/build/qat_4xxx.ko"; src_files[1] = "/usr/lib64/build/usdm_drv.ko"; src_files[2] = "/usr/lib64/build/intel_qat.ko"; src_files[3] = "/usr/lib64/libusdm_drv_s.so"; src_files[4] = "/usr/lib64/libqat_s.so"; src_files[5] = "/lib/firmware/qat_4xxx.bin"; src_files[6] = "/lib/firmware/qat_4xxx_mmp.bin"; src_files[7] = "qatprovider_temp.so"; sig_files[0] = "qat_4xxx_signature.bin"; sig_files[1] = "usdm_drv_signature.bin"; sig_files[2] = "intel_qat_signature.bin"; sig_files[3] = "usdm_signature.bin"; sig_files[4] = "libqat_signature.bin"; sig_files[5] = "qat_4xxx_bin_signature.bin"; sig_files[6] = "qat_4xxx_mmp_signature.bin"; sig_files[7] = "qat_signature.bin"; dump_cmd[0] = "objcopy --dump-section .qat_4xxx_sig=qat_4xxx_signature.bin qatprovider_temp.so"; dump_cmd[1] = "objcopy --dump-section .usdm_drv_sig=usdm_drv_signature.bin qatprovider_temp.so"; dump_cmd[2] = "objcopy --dump-section .iqat_sig=intel_qat_signature.bin qatprovider_temp.so"; dump_cmd[3] = "objcopy --dump-section .usdm_sig=usdm_signature.bin qatprovider_temp.so"; dump_cmd[4] = "objcopy --dump-section .libqat_sig=libqat_signature.bin qatprovider_temp.so"; dump_cmd[5] = "objcopy --dump-section .qat_4xxx_bin_sig=qat_4xxx_bin_signature.bin qatprovider_temp.so"; dump_cmd[6] = "objcopy --dump-section .qat_4xxx_mmp_sig=qat_4xxx_mmp_signature.bin qatprovider_temp.so"; dump_cmd[7] = "objcopy --dump-section .qat_sig=qat_signature.bin qatprovider_temp.so"; rmv_cmd[0] = "objcopy --remove-section .qat_4xxx_sig qatprovider_temp.so"; rmv_cmd[1] = "objcopy --remove-section .usdm_drv_sig qatprovider_temp.so"; rmv_cmd[2] = "objcopy --remove-section .iqat_sig qatprovider_temp.so"; rmv_cmd[3] = "objcopy --remove-section .usdm_sig qatprovider_temp.so"; rmv_cmd[4] = "objcopy --remove-section .libqat_sig qatprovider_temp.so"; rmv_cmd[5] = "objcopy --remove-section .qat_4xxx_bin_sig qatprovider_temp.so"; rmv_cmd[6] = "objcopy --remove-section .qat_4xxx_mmp_sig qatprovider_temp.so"; rmv_cmd[7] = "objcopy --remove-section .qat_sig qatprovider_temp.so"; } else { nfile = 3; src_files[0] = "/usr/lib64/libIPSec_MB.so"; src_files[1] = "/usr/lib64/libcrypto_mb.so"; src_files[2] = "qatprovider_temp.so"; sig_files[0] = "ipsec_mb_signature.bin"; sig_files[1] = "libcrypto_mb_signature.bin"; sig_files[2] = "qat_signature.bin"; dump_cmd[0] = "objcopy --dump-section .ipsec_mb_sig=ipsec_mb_signature.bin qatprovider_temp.so"; dump_cmd[1] = "objcopy --dump-section .libcrypto_mb_sig=libcrypto_mb_signature.bin qatprovider_temp.so"; dump_cmd[2] = "objcopy --dump-section .qat_sig=qat_signature.bin qatprovider_temp.so"; rmv_cmd[0] = "objcopy --remove-section .ipsec_mb_sig qatprovider_temp.so"; rmv_cmd[1] = "objcopy --remove-section .libcrypto_mb_sig qatprovider_temp.so"; rmv_cmd[2] = "objcopy --remove-section .qat_sig qatprovider_temp.so"; } } # ifdef QAT_HW srmv_cmd[0] = "objcopy --remove-section .qat_4xxx_sig qatprovider_temp.so"; srmv_cmd[1] = "objcopy --remove-section .usdm_drv_sig qatprovider_temp.so"; srmv_cmd[2] = "objcopy --remove-section .iqat_sig qatprovider_temp.so"; srmv_cmd[3] = "objcopy --remove-section .usdm_sig qatprovider_temp.so"; srmv_cmd[4] = "objcopy --remove-section .libqat_sig qatprovider_temp.so"; srmv_cmd[5] = "objcopy --remove-section .qat_4xxx_bin_sig qatprovider_temp.so"; srmv_cmd[6] = "objcopy --remove-section .qat_4xxx_mmp_sig qatprovider_temp.so"; # endif static unsigned char pubkey[INTEGRITY_PUB_KEYLENGTH]; unsigned char *read_buffer = NULL; enable_ondemand = ondemand; EVP_MD_CTX *ctx = NULL; unsigned int bufflen = 0; int siglen = INTEGRITY_SIGLEN; unsigned char *sigbuf = NULL, *buf = NULL; OSSL_PARAM *params = NULL, *params_sig = NULL; OSSL_PARAM_BLD *bld = NULL; EVP_PKEY_CTX *kctx = NULL, *sctx = NULL; EVP_PKEY *pkey = NULL; BN_CTX *bnctx = NULL; get_pub_key_from_file(pubkey_file, pubkey); DUMPL("Pubkey", pubkey, INTEGRITY_PUB_KEYLENGTH); ST_KAT_SIGN *t = NULL; static const ST_KAT_PARAM ecdsa_prime_key_1[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecdh_curve_name), ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, pubkey), ST_KAT_PARAM_END() }; static ST_KAT_SIGN st_kat_sign_tests_1[] = { { QAT_SELF_TEST_DESC_SIGN_ECDSAP256, "EC", "SHA3-256", ecdsa_prime_key_1, }, { QAT_SELF_TEST_DESC_SIGN_ECDSAP256, "EC", "SHA-256", ecdsa_prime_key_1, }, }; if (co_ex_enabled) { t = &st_kat_sign_tests_1[1]; } else { if (qat_hw_offload) t = &st_kat_sign_tests_1[0]; else t = &st_kat_sign_tests_1[1]; } if (co_ex_enabled) { /* To make symmetric algorithms run in HW Platform * when co-existence is enabled */ # ifdef ENABLE_QAT_HW_GCM qat_hw_gcm_offload = 1; qat_sw_gcm_offload = 0; # endif # ifdef ENABLE_QAT_SW_SHA2 qat_sw_sha_offload = 0; # endif for (i = 0; i < 2; i++) { if (i == 1) { if (ASYNC_get_current_job() != NULL) break; enable_async = ENABLE_FIPS; async_jobs = ASYNC_JOBS; } kat_self_test_init(ondemand, co_ex_enabled); } DEBUG("\n=================== QAT HW self tests result ===========\n"); fips_result(); /* Reset the values to make symmetric algorithms run in SW Platform * when co-existence is enabled */ # ifdef ENABLE_QAT_SW_GCM qat_hw_gcm_offload = 0; qat_sw_gcm_offload = 1; # endif # ifdef ENABLE_QAT_SW_SHA2 qat_sw_sha_offload = 1; # endif /* To make asymmetric algorithms run in SW Platform * when co-existence is enabled */ # ifdef ENABLE_QAT_SW_RSA qat_hw_rsa_offload = 0; qat_sw_rsa_offload = 1; # endif # ifdef ENABLE_QAT_SW_ECDSA qat_hw_ecdsa_offload = 0; qat_sw_ecdsa_offload = 1; # endif # ifdef ENABLE_QAT_SW_ECDH qat_hw_ecdh_offload = 0; qat_sw_ecdh_offload = 1; # endif # ifdef ENABLE_QAT_SW_ECX qat_hw_ecx_offload = 0; qat_sw_ecx_offload = 1; # endif qat_hw_dsa_offload = 0; qat_hw_dh_offload = 0; qat_hw_ecx_448_offload = 0; qat_hw_hkdf_offload = 0; qat_hw_prf_offload = 0; # ifdef ENABLE_QAT_SW_SHA2 qat_hw_sha_offload = 0; qat_sw_sha_offload = 1; # endif qat_hw_offload = 0; for (i = 0; i < 2; i++) { if (i == 1) { if (ASYNC_get_current_job() != NULL) break; enable_async = ENABLE_FIPS; async_jobs = ASYNC_JOBS; } kat_self_test_init(ondemand, co_ex_enabled); } DEBUG("\n=================== QAT SW self tests result ===========\n"); fips_result(); /* Reset the values to make asymmetric algorithms run in HW Platform * when co-existence is enabled */ # ifdef ENABLE_QAT_HW_RSA qat_hw_rsa_offload = 1; qat_sw_rsa_offload = 0; # endif # ifdef ENABLE_QAT_HW_ECDSA qat_hw_ecdsa_offload = 1; qat_sw_ecdsa_offload = 0; # endif # ifdef ENABLE_QAT_HW_ECDH qat_hw_ecdh_offload = 1; qat_sw_ecdh_offload = 0; # endif # ifdef ENABLE_QAT_HW_ECX qat_hw_ecx_offload = 1; qat_sw_ecx_offload = 0; # endif # ifdef ENABLE_QAT_HW_DSA qat_hw_dsa_offload = 1; # endif # ifdef ENABLE_QAT_HW_DH qat_hw_dh_offload = 1; # endif # ifdef ENABLE_QAT_HW_ECX qat_hw_ecx_448_offload = 1; # endif # ifdef ENABLE_QAT_HW_HKDF qat_hw_hkdf_offload = 1; # endif # ifdef ENABLE_QAT_HW_PRF qat_hw_prf_offload = 1; # endif # ifdef ENABLE_QAT_HW_SHA3 qat_hw_sha_offload = 1; qat_sw_sha_offload = 0; # endif # ifdef QAT_HW qat_hw_offload = 1; # endif } else { for (i = 0; i < 2; i++) { if (i == 1) { if (ASYNC_get_current_job() != NULL) break; enable_async = ENABLE_FIPS; async_jobs = ASYNC_JOBS; } kat_self_test_init(ondemand, co_ex_enabled); } fips_result(); } if (!integrity_status) { INFO("QAT FIPS self-tests(KAT) result: FAIL.\n"); sys_ret = remove("qatprovider_temp.so"); sys_ret = remove("public_key.txt"); return 0; } # ifdef QAT_HW if (qat_hw_offload == 0) { for (i = 0; i < 7; i++) sys_ret = system(srmv_cmd[i]); } # endif for (j = 0; j < nfile; j++) { ctx = EVP_MD_CTX_new(); if (co_ex_enabled) { md = EVP_MD_fetch(NULL, "SHA-256", NULL); } else { if (qat_hw_offload) md = EVP_MD_fetch(NULL, "SHA3-256", NULL); else md = EVP_MD_fetch(NULL, "SHA-256", NULL); } sys_ret = system(dump_cmd[j]); sys_ret = system(rmv_cmd[j]); DEBUG("QAT Provider Path %s len %ld\n", src_files[j], strlen(src_files[j])); module_bio = bio_open_default(src_files[j], 'r', FORMAT_BINARY); if (module_bio == NULL) WARN("Error @module_bio creation\n"); sig_bio = BIO_new_file(sig_files[j], "rb"); if (sig_bio == NULL) WARN("Error @sig_bio creation\n"); sigbuf = OPENSSL_zalloc(siglen); if (sigbuf == NULL) WARN("Error memory allocation for sigbuf"); siglen = BIO_read(sig_bio, sigbuf, siglen); BIO_free(sig_bio); buf = OPENSSL_zalloc(BUFFERSIZE); EVP_DigestInit_ex(ctx, md, NULL); while (BIO_pending(module_bio) || !BIO_eof(module_bio)) { i = BIO_read(module_bio, (char *)buf, BUFFERSIZE); EVP_DigestUpdate(ctx, buf, i); if (i < 0) { WARN("Read Error\n"); } if (i == 0) break; } read_buffer = OPENSSL_zalloc(INTEGRITY_BUF_SIZE); if (read_buffer == NULL) WARN("Error @read_buffer memory allocation failed\n"); EVP_DigestFinal(ctx, read_buffer, &bufflen); bnctx = BN_CTX_new_ex(NULL); if (bnctx == NULL) WARN("Error in memory creation for BN_CTX\n"); bld = OSSL_PARAM_BLD_new(); if (bld == NULL) WARN("Error in memory creation for OSSL_PARAM_BLD\n"); if (!add_params(bld, t->key, bnctx)) WARN("Error in add_params API\n"); params = OSSL_PARAM_BLD_to_param(bld); kctx = EVP_PKEY_CTX_new_from_name(NULL, t->algorithm, ""); if (kctx == NULL || params == NULL) WARN("Error in kctx creation..\n"); if (EVP_PKEY_fromdata_init(kctx) <= 0 || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) WARN("Error in EVP_PKEY_fromdata_init || EVP_PKEY_fromdata \n"); /* Create a EVP_PKEY_CTX to use for the signing operation */ sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); if (sctx == NULL) WARN("Error in EVP_PKEY_CTX_new_from_pkey\n"); /* set signature parameters */ if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST, t->mdalgorithm, strlen(t->mdalgorithm) + 1)) WARN("Error in OSSL_PARAM_BLD_push_utf8_string\n"); params_sig = OSSL_PARAM_BLD_to_param(bld); if (EVP_PKEY_verify_init(sctx) <= 0) WARN("Error: Failed at EVP_PKEY_verify_init API!!..\n"); if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) WARN("Error in EVP_PKEY_CTX_set_params..\n"); if (EVP_PKEY_verify(sctx, sigbuf, siglen, read_buffer, bufflen) <= 0) { WARN("Error: Failed at EVP_PKEY_verify..\n"); integrity_status = 0; } BIO_free(module_bio); OPENSSL_free(sigbuf); siglen = INTEGRITY_SIGLEN; OPENSSL_free(buf); OPENSSL_free(read_buffer); EVP_MD_CTX_free(ctx); EVP_MD_free(md); md = NULL; BN_CTX_free(bnctx); EVP_PKEY_CTX_free(kctx); EVP_PKEY_CTX_free(sctx); EVP_PKEY_free(pkey); pkey = NULL; OSSL_PARAM_free(params); OSSL_PARAM_free(params_sig); OSSL_PARAM_BLD_free(bld); sys_ret = remove(sig_files[j]); } sys_ret = remove("qatprovider_temp.so"); sys_ret = remove("public_key.txt"); if (sys_ret != 0) WARN("System process failure\n"); smem_id = shmget((key_t) SM_KEY, 16, 0666); smem_ptr = shmat(smem_id, NULL, 0); if (integrity_status) { INFO("QAT FIPS self-tests(KAT) and integrity test result: PASS\n"); strcpy(smem_ptr, "KAT_PASS"); } else { INFO("QAT FIPS Integrity test result: FAIL\n"); strcpy(smem_ptr, "KAT_FAIL"); return 0; } return 1; } #endif qatengine-1.9.0/qat_fips.h000066400000000000000000000261121500416242000154470ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_fips.h * * This file provides an interface to perform qat fips test * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef QAT_FIPS_H # define QAT_FIPS_H # ifndef _GNU_SOURCE # define _GNU_SOURCE # endif # ifndef __USE_GNU # define __USE_GNU # endif # include # include # include # ifndef __FreeBSD__ # include # else # include # include # include # include # include # endif # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include "e_qat.h" # include "qat_utils.h" # include "qat_provider.h" # include "qat_prov_rsa.h" # define OPENSSL_NO_DES # include # include "qat_self_test_data.inc" # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) # define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ # define FIPS_KEY_STRING "f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813" # define FORMAT_BINARY 2 /* Generic binary */ # define BUFSIZE 4096 # define INSTALL_STATUS_VAL "INSTALL_QAT_SELF_TEST_KATS_RUN" # define INTEGRITY_SIGLEN 72 # define INTEGRITY_PUB_KEYLENGTH 65 # define INTEGRITY_BUF_SIZE 32 # define OSSL_PROV_FIPS_PARAM_INSTALL_VERSION "install-version" # define VERSION_VAL "1" # define OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS "conditional-errors" # define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks" # define OSSL_PROV_FIPS_PARAM_MODULE_MAC "module-mac" # define OSSL_PROV_FIPS_PARAM_INSTALL_MAC "install-mac" # define OSSL_PROV_FIPS_PARAM_INSTALL_STATUS "install-status" # define B_FORMAT_TEXT 0x8000 # define FORMAT_UNDEF 0 # define FORMAT_TEXT (1 | B_FORMAT_TEXT)/* Generic text */ # define FORMAT_BINARY 2 /* Generic binary */ # define FORMAT_BASE64 (3 | B_FORMAT_TEXT)/* Base64 */ # define FORMAT_ASN1 4 /* ASN.1/DER */ # define FORMAT_PEM (5 | B_FORMAT_TEXT) # define FORMAT_PKCS12 6 # define FORMAT_SMIME (7 | B_FORMAT_TEXT) # define FORMAT_ENGINE 8 /* Not really a file format */ # define FORMAT_PEMRSA (9 | B_FORMAT_TEXT)/* PEM RSAPublicKey format */ # define FORMAT_ASN1RSA 10 /* DER RSAPublicKey format */ # define FORMAT_MSBLOB 11 /* MS Key blob format */ # define FORMAT_PVK 12 /* MS PVK file format */ # define FORMAT_HTTP 13 /* Download using HTTP */ # define FORMAT_NSS 14 /* NSS keylog format */ struct async_args_callback { int job_ready; int i; }; struct qat_self_test_result { const char *type[10]; const char *desc[10]; int result[10]; }; typedef struct qat_self_test_result QAT_SELF_TEST_RESULT; extern QAT_SELF_TEST_RESULT *qat_signature_result; extern QAT_SELF_TEST_RESULT *qat_kas_result; extern QAT_SELF_TEST_RESULT *qat_cipher_result; extern QAT_SELF_TEST_RESULT *qat_digest_result; extern QAT_SELF_TEST_RESULT *qat_mac_result; extern QAT_SELF_TEST_RESULT *qat_kdf_result; extern QAT_SELF_TEST_RESULT *qat_async_signature_result; extern QAT_SELF_TEST_RESULT *qat_async_kas_result; extern QAT_SELF_TEST_RESULT *qat_async_cipher_result; extern QAT_SELF_TEST_RESULT *qat_async_digest_result; extern QAT_SELF_TEST_RESULT *qat_async_mac_result; extern QAT_SELF_TEST_RESULT *qat_async_kdf_result; struct ossl_self_test_st { /* local state variables */ const char *phase; const char *type; const char *desc; OSSL_CALLBACK *cb; /* callback related variables used to pass the state back to the user */ OSSL_PARAM params[4]; void *cb_arg; }; typedef struct ossl_self_test_st OSSL_SELF_TEST; struct test_params_t { char *engine_id; int *count; const char *type; int size; ENGINE *e; int print_output; int verify; int performance; int enable_external_polling; int enable_event_driven_polling; int enable_async; const char *prov_id; OSSL_PROVIDER *prov; size_t sigsize; int use_callback_mode; int enable_negative; int curve; int kdf; char *tls_version; char *digest_kdf; int prf_op; int hkdf_op; int ecx_op; int explicit_engine; int sign_only; int verify_only; int encrypt_only; int decrypt_only; int async_jobs; ASYNC_JOB **jobs; ASYNC_WAIT_CTX **awcs; void *additional_args; OSSL_LIB_CTX *provctx; const char *phase; const char *desc; OSSL_CALLBACK *cb; OSSL_SELF_TEST *st; /* callback related variables used to pass the state back to the user */ OSSL_PARAM params[4]; void *cb_arg; int ondemand; int co_existence; }; typedef struct test_params_t TEST_PARAMS; int QAT_SELF_TEST_kats(void *args); struct async_additional_args_rsa { int sign_only; int verify_only; int encrypt_only; int decrypt_only; int padding; }; struct qat_evp_pkey_ctx_st { /* Actual operation */ int operation; /* * Library context, property query, keytype and keymgmt associated with * this context */ OSSL_LIB_CTX *libctx; char *propquery; const char *keytype; /* If |pkey| below is set, this field is always a reference to keymgmt */ EVP_KEYMGMT *keymgmt; union { struct { void *genctx; } keymgmt; struct { EVP_KEYEXCH *exchange; /* * Opaque ctx returned from a providers exchange algorithm * implementation OSSL_FUNC_keyexch_newctx() */ void *algctx; } kex; struct { EVP_SIGNATURE *signature; /* * Opaque ctx returned from a providers signature algorithm * implementation OSSL_FUNC_signature_newctx() */ void *algctx; } sig; struct { EVP_ASYM_CIPHER *cipher; /* * Opaque ctx returned from a providers asymmetric cipher algorithm * implementation OSSL_FUNC_asym_cipher_newctx() */ void *algctx; } ciph; struct { EVP_KEM *kem; /* * Opaque ctx returned from a providers KEM algorithm * implementation OSSL_FUNC_kem_newctx() */ void *algctx; } encap; } op; /* * Cached parameters. Inits of operations that depend on these should * call evp_pkey_ctx_use_delayed_data() when the operation has been set * up properly. */ struct { /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */ char *dist_id_name; /* The name used with EVP_PKEY_CTX_ctrl_str() */ void *dist_id; /* The distinguishing ID itself */ size_t dist_id_len; /* The length of the distinguishing ID */ /* Indicators of what has been set. Keep them together! */ unsigned int dist_id_set:1; } cached_parameters; /* Application specific data, usually used by the callback */ void *app_data; /* Keygen callback */ EVP_PKEY_gen_cb *pkey_gencb; /* implementation specific keygen data */ int *keygen_info; int keygen_info_count; /* Legacy fields below */ /* EVP_PKEY identity */ int legacy_keytype; /* Method associated with this operation */ const EVP_PKEY_METHOD *pmeth; /* Engine that implements this method or NULL if builtin */ ENGINE *engine; /* Key: may be NULL */ EVP_PKEY *pkey; /* Peer key for key agreement, may be NULL */ EVP_PKEY *peerkey; /* Algorithm specific data */ void *data; /* Indicator if digest_custom needs to be called */ unsigned int flag_call_digest_custom:1; /* * Used to support taking custody of memory in the case of a provider being * used with the deprecated EVP_PKEY_CTX_set_rsa_keygen_pubexp() API. This * member should NOT be used for any other purpose and should be removed * when said deprecated API is excised completely. */ BIGNUM *rsa_pubexp; } /* QAT_EVP_PKEY_CTX */ ; typedef struct qat_evp_pkey_ctx_st QAT_EVP_PKEY_CTX; int qat_fips_self_test(void *qatctx, int ondemand, int co_ex_enabled); void kat_self_test_init(int ondemand, int co_existence); void fips_result(void); int self_test_events(const OSSL_PARAM params[], void *arg); int QAT_TlsPrf_Ops(void *args, unsigned char *out, size_t outlen, const char *desc); int add_params(OSSL_PARAM_BLD * bld, const ST_KAT_PARAM * params, BN_CTX *ctx); int get_pub_key_from_file(char *in_name, unsigned char *out); #endif qatengine-1.9.0/qat_fork.c000066400000000000000000000176131500416242000154500ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file e_qat.c * * This file provides an implementation for fork in QAT engine * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Standard Includes */ #include #include #include #include #include #include /* Local Includes */ #include "qat_fork.h" #include "qat_utils.h" #include "e_qat.h" /* OpenSSL Includes */ #include #ifdef QAT_OPENSSL_PROVIDER # include #endif /* QAT includes */ #ifdef QAT_HW # include "cpa.h" # include "cpa_types.h" # ifndef __FreeBSD__ typedef cpu_set_t qat_cpuset; # else # include typedef cpuset_t qat_cpuset; # endif #endif #ifdef QAT_OPENSSL_PROVIDER # include "qat_provider.h" #endif void engine_init_child_at_fork_handler(void) { #ifndef DISABLE_QAT_AUTO_ENGINE_INIT_ON_FORK # ifndef QAT_OPENSSL_PROVIDER /* Reinitialise the engine */ ENGINE* e = ENGINE_by_id(engine_qat_id); if (NULL == e) { WARN("Engine pointer is NULL\n"); QATerr(QAT_F_ENGINE_INIT_CHILD_AT_FORK_HANDLER, QAT_R_ENGINE_NULL); return; } if (qat_engine_init(e) != 1) { WARN("Failure in qat_engine_init function\n"); QATerr(QAT_F_ENGINE_INIT_CHILD_AT_FORK_HANDLER, QAT_R_ENGINE_INIT_FAILURE); } ENGINE_free(e); #ifdef QAT_BORINGSSL ENGINE_QAT_PTR_RESET(); #endif /* QAT_BORINGSSL */ # else QAT_PROV_CTX *ctx; OSSL_PROVIDER *prov; const char *prov_name = "qatprovider"; ctx = OPENSSL_zalloc(sizeof(*ctx)); prov = OSSL_PROVIDER_load(prov_libctx_of(ctx),prov_name); if (NULL == prov) { WARN("Provider pointer is NULL\n"); QATerr(QAT_F_ENGINE_INIT_CHILD_AT_FORK_HANDLER, QAT_R_ENGINE_NULL); return; } if (qat_engine_init(NULL) != 1) { WARN("Failure in qat_engine_init function\n"); QATerr(QAT_F_ENGINE_INIT_CHILD_AT_FORK_HANDLER, QAT_R_ENGINE_INIT_FAILURE); } OPENSSL_free(ctx); OSSL_PROVIDER_unload(prov); # endif #endif } void engine_finish_before_fork_handler(void) { #ifndef QAT_OPENSSL_PROVIDER /* Reset the engine preserving the value of global variables */ ENGINE* e = ENGINE_by_id(engine_qat_id); if (NULL == e) { WARN("Engine pointer is NULL\n"); QATerr(QAT_F_ENGINE_FINISH_BEFORE_FORK_HANDLER, QAT_R_ENGINE_NULL); return; } qat_engine_finish_int(e, QAT_RETAIN_GLOBALS); ENGINE_free(e); ENGINE_QAT_PTR_RESET(); #else QAT_PROV_CTX *ctx; OSSL_PROVIDER *prov; const char *prov_name = "qatprovider"; ctx = OPENSSL_zalloc(sizeof(*ctx)); prov = OSSL_PROVIDER_load(prov_libctx_of(ctx),prov_name); if (NULL == prov) { WARN("Provider pointer is NULL\n"); QATerr(QAT_F_ENGINE_FINISH_BEFORE_FORK_HANDLER, QAT_R_ENGINE_NULL); return; } qat_engine_finish_int(NULL, QAT_RETAIN_GLOBALS); OPENSSL_free(ctx); OSSL_PROVIDER_unload(prov); #endif qat_hw_keep_polling = 1; qat_sw_keep_polling = 1; } int qat_create_thread(pthread_t *pThreadId, const pthread_attr_t *attr, void *(*start_func) (void *), void *pArg) { return pthread_create(pThreadId, attr, start_func,(void *)pArg); } int qat_join_thread(pthread_t threadId, void **retval) { return pthread_join(threadId, retval); } int qat_kill_thread(pthread_t threadId, int sig) { return pthread_kill(threadId, sig); } int qat_setspecific_thread(pthread_key_t key, const void *value) { return pthread_setspecific(key, value); } void *qat_getspecific_thread(pthread_key_t key) { return pthread_getspecific(key); } #ifdef QAT_HW int qat_adjust_thread_affinity(pthread_t threadptr) { # ifdef QAT_POLL_CORE_AFFINITY int coreID = 0; int sts = 1; qat_cpuset cpuset; CPU_ZERO(&cpuset); CPU_SET(coreID, &cpuset); sts = pthread_setaffinity_np(threadptr, sizeof(qat_cpuset), &cpuset); if (sts != 0) { WARN("pthread_setaffinity_np error, status = %d\n", sts); QATerr(QAT_F_QAT_ADJUST_THREAD_AFFINITY, QAT_R_PTHREAD_SETAFFINITY_FAILURE); return 0; } sts = pthread_getaffinity_np(threadptr, sizeof(qat_cpuset), &cpuset); if (sts != 0) { WARN("pthread_getaffinity_np error, status = %d\n", sts); QATerr(QAT_F_QAT_ADJUST_THREAD_AFFINITY, QAT_R_PTHREAD_GETAFFINITY_FAILURE); return 0; } if (CPU_ISSET(coreID, &cpuset)) { DEBUG("Polling thread assigned on CPU core %d\n", coreID); } # endif return 1; } int qat_fcntl(int fd, int cmd, int arg) { return fcntl(fd, cmd, arg); } int qat_set_instance_for_thread(long instanceNum) { int inst_idx; thread_local_variables_t *tlv = NULL; tlv = qat_check_create_local_variables(); if (NULL == tlv || 0 == qat_num_instances || instanceNum < 0) { WARN("could not create local variables or no instances available\n"); QATerr(QAT_F_QAT_SET_INSTANCE_FOR_THREAD, QAT_R_SET_INSTANCE_FAILURE); return 0; } tlv->qatAsymInstanceNumForThread = QAT_INVALID_INSTANCE; tlv->qatSymInstanceNumForThread = QAT_INVALID_INSTANCE; /* If asym can be supported */ if (qat_asym_num_instance > 0) { inst_idx = instanceNum % qat_asym_num_instance; tlv->qatAsymInstanceNumForThread = qat_map_asym_inst[inst_idx]; } /* If asym can be supported */ if (qat_sym_num_instance > 0) { inst_idx = instanceNum % qat_sym_num_instance; tlv->qatSymInstanceNumForThread = qat_map_sym_inst[inst_idx]; } enable_instance_for_thread = 1; return 1; } /* Wrapper for memory Allocation to use pinned contiguous memory or application memory * based on instance's SVM or contiguous mem capability */ void *qat_mem_alloc(size_t memsize, int inst_mem_type, const char *file, int line) { if (inst_mem_type == QAT_INSTANCE_SVM) return OPENSSL_zalloc(memsize); else return qaeCryptoMemAlloc(memsize, file, line); } #endif qatengine-1.9.0/qat_fork.h000066400000000000000000000161341500416242000154520ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_fork.h * * This file provides an interface for forking in engine * *****************************************************************************/ #ifndef QAT_FORK_H # define QAT_FORK_H # include "e_qat.h" int qat_fcntl(int fd, int cmd, int arg); /****************************************************************************** * function: * void engine_init_child_at_fork_handler(void) * * description: * This function is registered, by the call to pthread_atfork(), as * a function to be invoked in the child process prior to fork() returning. ******************************************************************************/ void engine_init_child_at_fork_handler(void); /****************************************************************************** * function: * void engine_finish_before_fork_handler(void) * * description: * This function is registered, by the call to pthread_atfork(), as * a function to be run (by the parent process) before a fork() function. ******************************************************************************/ void engine_finish_before_fork_handler(void); /****************************************************************************** * function: * int qat_create_thread(pthread_t *pThreadId, * const pthread_attr_t *attr, * void *(*start_func) (void *), void *pArg) * * @param pThreadId [OUT] - Pointer to Thread ID * @param start_func [IN] - Pointer to Thread Start routine * @param attr [IN] - Pointer to Thread attributes * @param pArg [IN] - Arguments to start routine * * description: * Wrapper function for pthread_create ******************************************************************************/ int qat_create_thread(pthread_t *pThreadId, const pthread_attr_t *attr, void *(*start_func) (void *), void *pArg); /****************************************************************************** * function: * int qat_join_thread(pthread_t threadId, void **retval) * * @param pThreadId [IN] - Thread ID of the created thread * @param retval [OUT] - Pointer that contains thread's exit status * * description: * Wrapper function for pthread_create ******************************************************************************/ int qat_join_thread(pthread_t threadId, void **retval); /****************************************************************************** * function: * int qat_kill_thread(pthread_t threadId, int sig) * * @param pThreadId [IN] - Thread ID of the created thread * @param sig [IN] - Signal number * * description: * Wrapper function for pthread_kill ******************************************************************************/ int qat_kill_thread(pthread_t threadId, int sig); /****************************************************************************** * function: * int qat_setspecific_thread(pthread_key_t key, const void *value) * * @param key [IN] - key obtained from pthread_key_create() * @param value [IN] - Thread specific value * * description: * Wrapper function for pthread_setspecific ******************************************************************************/ int qat_setspecific_thread(pthread_key_t key, const void *value); /****************************************************************************** * function: * int qat_getspecific_thread(pthread_key_t key) * * @param key [IN] - key obtained from pthread_key_create() * * description: * Wrapper function for pthread_getspecific ******************************************************************************/ void *qat_getspecific_thread(pthread_key_t key); /****************************************************************************** * function: * int qat_adjust_thread_affinity(pthread_t threadptr); * * @param threadptr[IN ] - Thread ID * * description: * Sets the CPU affinity mask using pthread_setaffinity_np * and returns the CPU affinity mask using pthread_getaffinity_np ******************************************************************************/ int qat_adjust_thread_affinity(pthread_t threadptr); /****************************************************************************** * function: * int qat_set_instance_for_thread(long instanceNum) * * @param instanceNum [IN] - logical instance number * * description: * Bind the current thread to a particular logical Cy instance. Note that if * instanceNum is greater than the number of configured instances, the * modulus operation is used. * ******************************************************************************/ int qat_set_instance_for_thread(long instanceNum); /****************************************************************************** * function: * void *qat_mem_alloc(size_t memsize, int inst_mem_type, * const char *file, int line) * * description: * Wrapper funcation to memory allocation based on instance type (SVM or pinned * contiguous memory) * ******************************************************************************/ void *qat_mem_alloc(size_t memsize, int inst_mem_type, const char *file, int line); #endif /* QAT_FORK_H */ qatengine-1.9.0/qat_hw_asym_common.c000066400000000000000000000341041500416242000175200ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_asym_common.c * * This file contains common functions used for asymmetric operations * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif #include #include #include #include #include "cpa_cy_ln.h" #include "qat_hw_asym_common.h" #include "qat_utils.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #define QAT_PERFORMOP_RETRIES 3 #ifdef ENABLE_QAT_HW_SM2 #define QAT_SM2_SIZE 32 #endif /****************************************************************************** * function: * qat_BN_to_FB(CpaFlatBuffer *fb, * BIGNUM *bn) * * @param fb [OUT] - API flatbuffer structure pointer * @param bn [IN] - Big Number pointer * @param qat_svm [OUT] - Instance Memory type * * description: * This function is used to transform the big number format to the flat buffer * format. The function is used to deliver the RSA Public/Private key structure * from OpenSSL layer to API layer. ******************************************************************************/ int qat_BN_to_FB(CpaFlatBuffer * fb, const BIGNUM *bn, int qat_svm) { if (unlikely((fb == NULL || bn == NULL ))) { WARN("Invalid input params.\n"); return 0; } /* Memory allocate for flat buffer */ fb->dataLenInBytes = (Cpa32U) BN_num_bytes(bn); if (0 == fb->dataLenInBytes) { fb->pData = NULL; DEBUG("Datalen = 0, zero byte memory allocation\n"); return 1; } if (!qat_svm) fb->pData = qaeCryptoMemAlloc(fb->dataLenInBytes, __FILE__, __LINE__); else fb->pData = OPENSSL_zalloc(fb->dataLenInBytes); if (NULL == fb->pData) { fb->dataLenInBytes = 0; WARN("Failed to allocate fb->pData\n"); return 0; } /* * BN_bn2in() converts the absolute value of big number into big-endian * form and stores it at output buffer. the output buffer must point to * BN_num_bytes of memory */ BN_bn2bin(bn, fb->pData); return 1; } # if defined(QAT_OPENSSL_PROVIDER) && defined(ENABLE_QAT_HW_SM2) int qat_BN_to_FB_for_sm2(CpaFlatBuffer * fb, const BIGNUM *bn, int qat_svm) { if (unlikely((fb == NULL || bn == NULL ))) { WARN("Invalid input params.\n"); return 0; } /* Memory allocate for flat buffer */ fb->dataLenInBytes = (Cpa32U) BN_num_bytes(bn); if (0 == fb->dataLenInBytes) { fb->pData = NULL; DEBUG("Datalen = 0, zero byte memory allocation\n"); return 1; } if (fb->dataLenInBytes < QAT_SM2_SIZE) fb->dataLenInBytes = fb->dataLenInBytes + (QAT_SM2_SIZE - fb->dataLenInBytes); if (!qat_svm) fb->pData = qaeCryptoMemAlloc(fb->dataLenInBytes, __FILE__, __LINE__); else fb->pData = OPENSSL_zalloc(fb->dataLenInBytes); if (NULL == fb->pData) { fb->dataLenInBytes = 0; WARN("Failed to allocate fb->pData\n"); return 0; } /* * BN_bn2in() converts the absolute value of big number into big-endian * form and stores it at output buffer. the output buffer must point to * BN_num_bytes of memory */ BN_bn2bin(bn, fb->pData); return 1; } #endif /* Callback to indicate QAT completion of bignum modular exponentiation */ static void qat_modexpCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer * pOut) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } /****************************************************************************** * function: qat_mod_exp(BIGNUM *res, const BIGNUM *base, const BIGNUM *exp, const BIGNUM *mod, int *fallback) * * @param res [IN] - Result bignum of mod_exp * @param base [IN] - Base used for mod_exp * @param exp [IN] - Exponent used for mod_exp * @param mod [IN] - Modulus used for mod_exp * @param fallback [OUT] - Pointer to Software Fallback flag * * description: * Bignum modular exponentiation function used in DH and DSA. * ******************************************************************************/ int qat_mod_exp(BIGNUM *res, const BIGNUM *base, const BIGNUM *exp, const BIGNUM *mod, int *fallback) { CpaCyLnModExpOpData opData; CpaFlatBuffer result = { 0, }; CpaStatus status = 0; int retval = 1, job_ret = 0; int inst_num = QAT_INVALID_INSTANCE; int qatPerformOpRetries = 0; op_done_t op_done; int iMsgRetry = getQatMsgRetryCount(); useconds_t ulPollInterval = getQatPollInterval(); thread_local_variables_t *tlv = NULL; int qat_svm = QAT_INSTANCE_ANY; DEBUG(" - Started\n"); opData.base.pData = NULL; opData.exponent.pData = NULL; opData.modulus.pData = NULL; if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_MOD_EXP, ERR_R_INTERNAL_ERROR); } retval = 0; goto exit; } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (qat_BN_to_FB(&opData.base, (BIGNUM *)base, qat_svm) != 1 || qat_BN_to_FB(&opData.exponent, (BIGNUM *)exp, qat_svm) != 1 || qat_BN_to_FB(&opData.modulus, (BIGNUM *)mod, qat_svm) != 1) { WARN("Failed to convert base, exponent or modulus to flatbuffer\n"); QATerr(QAT_F_QAT_MOD_EXP, QAT_R_BUF_CONV_FAIL); retval = 0; goto exit; } result.dataLenInBytes = BN_num_bytes(mod); result.pData = qat_mem_alloc(result.dataLenInBytes, qat_svm, __FILE__, __LINE__); if (NULL == result.pData) { WARN("Failed to allocate result.pData\n"); QATerr(QAT_F_QAT_MOD_EXP, QAT_R_RESULT_PDATA_ALLOC_FAIL); retval = 0; goto exit; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_MOD_EXP, ERR_R_INTERNAL_ERROR); retval = 0; goto exit; } #ifdef QAT_BORINGSSL qat_init_op_done(&op_done,qat_svm); #else qat_init_op_done(&op_done); #endif if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notifications\n"); QATerr(QAT_F_QAT_MOD_EXP, QAT_R_MOD_SETUP_ASYNC_EVENT_FAIL); retval = 0; qat_cleanup_op_done(&op_done); goto exit; } } do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failure to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_MOD_EXP, QAT_R_MOD_GET_NEXT_INST_FAIL); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } retval = 0; qat_cleanup_op_done(&op_done); goto exit; } status = cpaCyLnModExp(qat_instance_handles[inst_num], qat_modexpCallbackFn, &op_done, &opData, &result); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (CPA_STATUS_SUCCESS != status) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_MOD_EXP, QAT_R_MOD_LN_MOD_EXP_FAIL); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); retval = 0; qat_cleanup_op_done(&op_done); goto exit; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_MOD_EXP, ERR_R_INTERNAL_ERROR); retval = 0; QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto exit; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_MOD_EXP, ERR_R_INTERNAL_ERROR); } retval = 0; qat_cleanup_op_done(&op_done); goto exit; } qat_cleanup_op_done(&op_done); /* Convert the flatbuffer results back to a BN */ BN_bin2bn(result.pData, result.dataLenInBytes, res); exit: QAT_MEM_FREE_FLATBUFF(opData.base, qat_svm); QAT_MEM_FREE_FLATBUFF(opData.exponent, qat_svm); QAT_MEM_FREE_FLATBUFF(opData.modulus, qat_svm); QAT_MEM_FREE_FLATBUFF(result, qat_svm); return retval; } qatengine-1.9.0/qat_hw_asym_common.h000066400000000000000000000054541500416242000175330ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_asym_common.h * * This file contains the interface to common asymmetric functions * *****************************************************************************/ #ifndef QAT_HW_ASYM_COMMON_H # define QAT_HW_ASYM_COMMON_H # include # include "cpa.h" int qat_BN_to_FB(CpaFlatBuffer * fb, const BIGNUM *bn, int qat_svm); int qat_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, int *fallback); # ifdef ENABLE_QAT_HW_SM2 int qat_BN_to_FB_for_sm2(CpaFlatBuffer * fb, const BIGNUM *bn, int qat_svm); # endif # ifdef ENABLE_QAT_HW_ECX void qat_ecx_cb(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean multiplyStatus, CpaFlatBuffer *pXk, CpaFlatBuffer *pYk); int reverse_bytes(unsigned char *tobuffer, unsigned char *frombuffer, unsigned int tosize, unsigned int fromsize); # endif #endif /* QAT_HW_ASYM_COMMON_H */ qatengine-1.9.0/qat_hw_callback.c000066400000000000000000000152311500416242000167330ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_callback.c * * This file provides implementation for callback in engine * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Standard Includes */ #include #include #include #include /* Local Includes */ #include "qat_hw_callback.h" #include "qat_events.h" #include "qat_utils.h" /* OpenSSL Includes */ #include /* QAT includes */ #include "cpa.h" #include "cpa_types.h" #include "icp_sal_poll.h" #if defined(QAT_BORINGSSL) void qat_init_op_done(op_done_t *opDone, int qat_svm) { if (unlikely(opDone == NULL)) { WARN("opDone is NULL\n"); QATerr(QAT_F_QAT_INIT_OP_DONE, QAT_R_OPDONE_NULL); return; } opDone->flag = 0; opDone->verifyResult = CPA_FALSE; opDone->status = CPA_STATUS_FAIL; opDone->job = ASYNC_get_current_job(); if (opDone->job != NULL) opDone->job->qat_svm = qat_svm; opDone->qat_svm = qat_svm; } #else void qat_init_op_done(op_done_t *opDone) { if (unlikely(opDone == NULL)) { WARN("opDone is NULL\n"); QATerr(QAT_F_QAT_INIT_OP_DONE, QAT_R_OPDONE_NULL); return; } opDone->flag = 0; opDone->verifyResult = CPA_FALSE; opDone->status = CPA_STATUS_FAIL; opDone->job = ASYNC_get_current_job(); } #endif int qat_init_op_done_pipe(op_done_pipe_t *opdpipe, unsigned int npipes) { if (unlikely((opdpipe == NULL) || (npipes == 0))) { WARN("opdpipe is NULL or npipes is 0.\n"); QATerr(QAT_F_QAT_INIT_OP_DONE_PIPE, QAT_R_OPDPIPE_NULL); return 0; } opdpipe->num_pipes = npipes; opdpipe->num_submitted = 0; opdpipe->num_processed = 0; opdpipe->opDone.flag = 0; opdpipe->opDone.verifyResult = CPA_TRUE; opdpipe->opDone.job = ASYNC_get_current_job(); /* Setup async notification if using async jobs. */ if (opdpipe->opDone.job != NULL && (qat_setup_async_event_notification(opdpipe->opDone.job) == 0)) { WARN("Failure to setup async event notifications\n"); QATerr(QAT_F_QAT_INIT_OP_DONE_PIPE, QAT_R_SETUP_ASYNC_EVENT_FAILURE); qat_cleanup_op_done_pipe(opdpipe); return 0; } return 1; } int qat_init_op_done_rsa_crt(op_done_rsa_crt_t *opdcrt) { if (unlikely(opdcrt == NULL)) { WARN("opdcrt is NULL\n"); QATerr(QAT_F_QAT_INIT_OP_DONE_RSA_CRT, QAT_R_OPDCRT_NULL); return 0; } opdcrt->opDone.flag = 0; /* note that the initial value is true in order to judge via AND */ opdcrt->opDone.verifyResult = CPA_TRUE; opdcrt->opDone.status = CPA_STATUS_SUCCESS; opdcrt->opDone.job = NULL; opdcrt->req = 0; opdcrt->resp = 0; return 1; } void qat_cleanup_op_done(op_done_t *opDone) { if (unlikely(opDone == NULL)) { WARN("opDone is NULL\n"); return; } opDone->verifyResult = CPA_FALSE; opDone->status = CPA_STATUS_FAIL; if (opDone->job) { opDone->job = NULL; } } void qat_cleanup_op_done_pipe(op_done_pipe_t *opdone) { if (unlikely(opdone == NULL)) { WARN("opdone is NULL\n"); return; } opdone->num_pipes = 0; opdone->num_submitted = 0; opdone->num_processed = 0; qat_cleanup_op_done(&opdone->opDone); } void qat_cleanup_op_done_rsa_crt(op_done_rsa_crt_t *opdcrt) { if (unlikely(opdcrt == NULL)) { WARN("opdcrt is NULL\n"); return; } opdcrt->req = 0; opdcrt->resp = 0; qat_cleanup_op_done(&opdcrt->opDone); } void qat_crypto_callbackFn(void *callbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList * pDstBuffer, CpaBoolean verifyResult) { ASYNC_JOB *job = NULL; op_done_t *opDone = (op_done_t *)callbackTag; if (unlikely(opDone == NULL)) { WARN("opDone is NULL\n"); QATerr(QAT_F_QAT_CRYPTO_CALLBACKFN, QAT_R_OPDONE_NULL); return; } DEBUG("status %d verifyResult %d\n", status, verifyResult); opDone->verifyResult = (status == CPA_STATUS_SUCCESS) && verifyResult ? CPA_TRUE : CPA_FALSE; opDone->status = status; /* Cache job pointer to avoid a race condition if opDone gets cleaned up * in the calling thread. */ job = (ASYNC_JOB *)opDone->job; opDone->flag = 1; if (job) { #ifdef QAT_BORINGSSL /* TODO: Possible to move this as callback to qat_wake_job */ bssl_qat_before_wake_job(job, ASYNC_STATUS_OK, pOpData, pDstBuffer->pBuffers, opDone); #endif /* QAT_BORINGSSL */ qat_wake_job(job, ASYNC_STATUS_OK); } } qatengine-1.9.0/qat_hw_callback.h000066400000000000000000000166271500416242000167520ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_callback.h * * This file provides and interface for async events to engine * *****************************************************************************/ #ifndef QAT_HW_CALLBACK_H # define QAT_HW_CALLBACK_H # include # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "e_qat.h" /* Struct for tracking threaded QAT operation completion. */ typedef struct { volatile int flag; volatile CpaBoolean verifyResult; volatile ASYNC_JOB *job; volatile CpaStatus status; #if defined(QAT_BORINGSSL) volatile int qat_svm; #endif } op_done_t; /* Use this variant of op_done to track QAT chained cipher * operation completion supporting pipelines. */ typedef struct { /* Keep this as first member of the structure. * to allow inter-changeability by casting pointers. */ op_done_t opDone; volatile unsigned int num_pipes; volatile unsigned int num_submitted; volatile unsigned int num_processed; } op_done_pipe_t; /* Use this variant of op_done to track * QAT RSA CRT operation completion. */ typedef struct { /* Keep this as first member of the structure. * to allow inter-changeability by casting pointers. */ op_done_t opDone; unsigned int req; volatile unsigned int resp; } op_done_rsa_crt_t; /****************************************************************************** * function: * qat_init_op_done(op_done_t *opDone) * * @param opDone [IN] - pointer to op done_t callback structure. * * description: * Initialise the QAT operation "done" callback structure. * ******************************************************************************/ #if defined(QAT_BORINGSSL) void qat_init_op_done(op_done_t *opDone, int qat_svm); #else void qat_init_op_done(op_done_t *opDone); #endif /****************************************************************************** * function: * qat_init_op_done_pipe(op_done_pipe_t *opdpipe, unsigned int npipes) * * @param opdpipe [IN] - pointer to op_done_pipe_t callback structure * @param npipes [IN] - number of pipes in the pipeline * * description: * Initialise the QAT chained operation "done" callback structure. * Setup async event notification if required. The function returns * 1 for success and 0 for failure. * ******************************************************************************/ int qat_init_op_done_pipe(op_done_pipe_t *opDone, unsigned int npipes); /****************************************************************************** * function: * qat_init_op_done_rsa_crt(op_done_rsa_crt_t *opdcrt) * * @param opdcrt [IN] - pointer to op_done_rsa_crt_t callback structure. * * description: * Initialise the QAT RSA synchronous operation "done" callback structure. * The function returns 1 for success and 0 for failure. * ******************************************************************************/ int qat_init_op_done_rsa_crt(op_done_rsa_crt_t *opdcrt); /****************************************************************************** * function: * qat_cleanup_op_done(op_done_t *opDone) * * @param opDone [IN] - pointer to op_done_t callback structure. * * description: * Cleanup the data in the "done" callback structure. * ******************************************************************************/ void qat_cleanup_op_done(op_done_t *opDone); /****************************************************************************** * function: * qat_cleanup_op_done_pipe(op_done_pipe_t *opDone) * * @param opDone [IN] - pointer to op_done_pipe_t callback structure. * * description: * Cleanup the QAT chained operation "done" callback structure. * ******************************************************************************/ void qat_cleanup_op_done_pipe(op_done_pipe_t *opDone); /****************************************************************************** * function: * qat_cleanup_op_done_rsa_crt(op_done_rsa_crt_t *opdcrt) * * @param opdcrt [IN] - pointer to op_done_rsa_crt_t callback structure. * * description: * Cleanup the QAT RSA synchronous operation "done" callback structure. * ******************************************************************************/ void qat_cleanup_op_done_rsa_crt(op_done_rsa_crt_t *opdcrt); /****************************************************************************** * function: * qat_crypto_callbackFn(void *callbackTag, CpaStatus status, * const CpaCySymOp operationType, void *pOpData, * CpaBufferList * pDstBuffer, CpaBoolean verifyResult) * * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. Cast to op_done. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: * Callback function used by cpaCySymPerformOp to indicate completion. * ******************************************************************************/ void qat_crypto_callbackFn(void *callbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList * pDstBuffer, CpaBoolean verifyResult); #endif /* QAT_HW_CALLBACK_H */ qatengine-1.9.0/qat_hw_ccm.c000066400000000000000000002166371500416242000157560ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_ccm.c * * This file contains the engine implementations for CCM cipher operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include "e_qat.h" #include "qat_utils.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_sym.h" #include "qat_evp.h" #include "qat_hw_ccm.h" #include "qat_hw_ciphers.h" #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_aes_ccm.h" #endif #include #include #include #include #include #include #define GET_SW_AES_CCM_CIPHER(ctx) \ qat_ccm_cipher_sw_impl(EVP_CIPHER_CTX_type((ctx)) ) #ifdef ENABLE_QAT_HW_CCM /****************************************************************************** * function: * qat_session_data_init(EVP_CIPHER_CTX *ctx, * qat_aes_ccm_ctx *qctx, * const unsigned char* key, * const unsigned char* iv, * int enc) * * @param ctx [IN] - pointer to the evp context * @param qctx [IN] - pointer to the qat context * @param key [IN] - pointer to the cipher key * @param iv [IN] - pointer to the iv this maybe NULL. * @param enc [IN] - whether we are doing encryption (1) or decryption (0). * * description: * This function is to create QAT specific session data. * It is called from the function qat_aes_ccm_init(). * * It will return 1 if successful and 0 on failure. ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER static int qat_session_data_init(EVP_CIPHER_CTX *ctx, void *vctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc) # else static int qat_session_data_init(EVP_CIPHER_CTX *ctx, qat_ccm_ctx * qctx, const unsigned char *key, const unsigned char *iv, int enc) # endif { # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) vctx; # endif DEBUG("QAT HW CCM Started\n"); if (NULL == qctx || NULL == ctx) { WARN("qctx or ctx is NULL\n"); QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_QCTX_CTX_NULL); return 0; } if (key != NULL) { if (qctx->qat_svm) { if (qctx->cipher_key) { OPENSSL_free(qctx->cipher_key); qctx->cipher_key = NULL; } # ifdef QAT_OPENSSL_PROVIDER qctx->cipher_key = OPENSSL_zalloc(keylen); # else qctx->cipher_key = OPENSSL_zalloc(EVP_CIPHER_CTX_key_length(ctx)); # endif } else { if (qctx->cipher_key) { qaeCryptoMemFreeNonZero(qctx->cipher_key); qctx->cipher_key = NULL; } # ifdef QAT_OPENSSL_PROVIDER qctx->cipher_key = qaeCryptoMemAlloc(keylen, __FILE__, __LINE__); # else qctx->cipher_key = qaeCryptoMemAlloc(EVP_CIPHER_CTX_key_length(ctx), __FILE__, __LINE__); # endif } if (qctx->cipher_key == NULL) { WARN("Unable to allocate memory for qctx->cipher_key.\n"); QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_KEY_MALLOC_FAILURE); return 0; } # ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->cipher_key, key, keylen); # else memcpy(qctx->cipher_key, key, EVP_CIPHER_CTX_key_length(ctx)); # endif qctx->key_set = 1; } if (iv != NULL && qctx->iv_set) { qctx->OpData.ivLenInBytes = QAT_AES_CCM_OP_VALUE - qctx->L; } if (NULL == qctx->session_data) { qctx->session_data = OPENSSL_zalloc(sizeof(CpaCySymSessionSetupData)); if (NULL == qctx->session_data) { WARN("session setup data zalloc failure\n"); QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_SSD_MALLOC_FAILURE); return 0; } } /* Set priority and operation of this session */ qctx->session_data->sessionPriority = CPA_CY_PRIORITY_HIGH; qctx->session_data->symOperation = CPA_CY_SYM_OP_ALGORITHM_CHAINING; /* --- Cipher configuration --- */ /* Cipher algorithm and mode */ qctx->session_data->cipherSetupData.cipherAlgorithm = CPA_CY_SYM_CIPHER_AES_CCM; /* Cipher key length */ if (key != NULL && qctx->key_set) { # ifdef QAT_OPENSSL_PROVIDER qctx->session_data->cipherSetupData.cipherKeyLenInBytes = keylen; # else qctx->session_data->cipherSetupData.cipherKeyLenInBytes = EVP_CIPHER_CTX_key_length(ctx); # endif } if (qctx->key_set) { qctx->session_data->cipherSetupData.pCipherKey = (Cpa8U *) qctx->cipher_key; } /* Operation to perform */ if (enc) { qctx->session_data->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT; qctx->session_data->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER; /* Tag follows immediately after the region to hash */ } else { qctx->session_data->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; qctx->session_data->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; } /* --- Hash Configuration --- */ /* Set the hash mode and the length of the digest */ qctx->session_data->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_AES_CCM; qctx->session_data->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH; qctx->session_data->hashSetupData.digestResultLenInBytes = qctx->M; /* For CCM authKey and authKeyLen are not required. * This information is provided by the cipherKey in cipherSetupData */ qctx->session_data->hashSetupData.authModeSetupData.authKey = NULL; qctx->session_data->hashSetupData.authModeSetupData.authKeyLenInBytes = 0; /* Set the length of the AAD to the default value */ qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = 0; /* Tag follows immediately after the region to hash */ qctx->session_data->digestIsAppended = CPA_TRUE; /* digestVerify is not required to be set. For CCM authenticated * encryption this value is understood to be CPA_FALSE during encryption and * CPA_TRUE during decryption */ qctx->init_params_set = 1; return 1; } /****************************************************************************** * function: * qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, * const unsigned char *inkey, * const unsigned char *iv, * int enc) * * @param ctx [IN] - pointer to existing context * @param inKey [IN] - input cipher key * @param iv [IN] - initialisation vector * @param enc [IN] - 1 encrypt 0 decrypt * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the cipher and hash algorithm parameters for this * EVP context. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER int qat_aes_ccm_init(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) { # else int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc) { # endif # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; # else qat_ccm_ctx *qctx = NULL; # endif int ret = 1; int fallback = 0; # ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER sw_aes_ccm_cipher; # endif if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_INIT, QAT_R_CTX_NULL); return 0; } DEBUG("CTX = %p, key = %p, iv = %p, enc = %d\n", (void *)ctx, (void *)inkey, (void *)iv, enc); # ifndef QAT_OPENSSL_PROVIDER qctx = QAT_CCM_GET_CTX(ctx); # else qctx->enc = enc; # endif /* Initialise a QAT session and set the cipher keys */ if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_INIT, QAT_R_QCTX_NULL); return 0; } if (qat_get_sw_fallback_enabled()) fallback = 1; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD fallback = 1; # endif if (!inkey && !iv) { DEBUG("key and IV not set\n"); ret = 1; goto end; } if (iv) { /* Set the value of the IV */ memcpy(qctx->next_iv, iv, QAT_AES_CCM_OP_VALUE - qctx->L); qctx->iv_len = QAT_AES_CCM_OP_VALUE - qctx->L; qctx->iv_set = 1; } qctx->tls_aad_len = -1; qctx->tag_len = -1; qctx->tag_set = 0; qctx->len_set = 0; if ((qctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get QAT Instance Handle\n"); ret = 0; goto end; } qctx->qat_svm = !qat_instance_details[qctx->inst_num].qat_instance_info. requiresPhysicallyContiguousMemory; /* Initialize QAT session */ # ifdef QAT_OPENSSL_PROVIDER if (0 == qat_session_data_init(ctx, qctx, inkey, keylen, iv, ivlen, enc)) { # else if (0 == qat_session_data_init(ctx, qctx, inkey, iv, enc)) { # endif WARN("qat_session_data_init failed.\n"); goto err; } goto end; err: QAT_MEM_FREE_BUFF(qctx->cipher_key, qctx->qat_svm); end: if (fallback) { # ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); /* Run the software init function */ ret = EVP_CIPHER_meth_get_init(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, inkey, iv, enc); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); # else OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; sw_aes_ccm_cipher = get_default_cipher_aes_ccm(qctx->nid); if (enc) { if (!qctx->sw_ctx) qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); ret = sw_aes_ccm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } else { if (!qctx->sw_ctx) qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); ret = sw_aes_ccm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } # endif } return ret; } /****************************************************************************** * function: * qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, * int type, int arg, void *ptr) * * @param ctx [IN] - pointer to existing context * @param type [IN] - type of request either * EVP_CTRL_AEAD_SET_MAC_KEY or EVP_CTRL_AEAD_TLS1_AAD * @param arg [IN] - size of the pointed to by ptr * @param ptr [IN] - input buffer contain the necessary parameters * * @retval x The return value is dependent on the type of request being made * EVP_CTRL_AEAD_SET_MAC_KEY return of 1 is success * EVP_CTRL_AEAD_TLS1_AAD return value indicates the amount * for padding to be applied to the SSL/TLS record * @retval -1 function failed * * description: * This function is a generic control interface provided by the EVP API. For * chained requests this interface is used for setting the hmac key value for * authentication of the SSL/TLS record. * The second type is used to specify the TLS virtual header which is used * in the authentication calculation and to identify record payload size. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER int qat_aes_ccm_ctrl(void *ctx, int type, int arg, void *ptr) # else int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) # endif { # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; # else qat_ccm_ctx *qctx = NULL; int ret_sw = 0; int fallback = 0; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD int nid = EVP_CIPHER_CTX_nid(ctx); # endif # endif unsigned int plen = 0; int enc = 0; int ret = 0; int l_value = 0; if (NULL == ctx) { WARN("ctx is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_CTX_NULL); return 0; } # ifdef QAT_OPENSSL_PROVIDER enc = qctx->enc; # else enc = EVP_CIPHER_CTX_encrypting(ctx); qctx = QAT_CCM_GET_CTX(ctx); if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_QCTX_NULL); return 0; } # endif switch (type) { case EVP_CTRL_INIT: DEBUG("EVP_CTRL_INIT, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); qctx->key_set = 0; qctx->iv_len = QAT_CCM_TLS_TOTAL_IV_LEN; qctx->iv_set = 0; qctx->tag_set = 0; qctx->L = 8; qctx->M = 12; qctx->tls_aad_len = -1; qctx->tag_len = -1; qctx->len_set = 0; ret = 1; goto end; case EVP_CTRL_GET_IVLEN: DEBUG("EVP_CTRL_CCM_GET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); *(int *)ptr = QAT_AES_CCM_OP_VALUE - qctx->L; ret = 1; goto end; case EVP_CTRL_AEAD_SET_TAG: DEBUG("EVP_CTRL_AEAD_SET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg < QAT_CCM_TAG_MIN_LEN || arg > QAT_CCM_TAG_MAX_LEN) { WARN("TAG length invalid or invalid operation enc\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_SET_TAG_INVALID_OP); return 0; } if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx)) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_INVALID_PTR); return 0; } /* ctx->buf is a static buffer of size * EVP_MAX_BLOCK_LENGTH = 32 */ if (ptr) { memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), ptr, arg); qctx->tag_set = 1; } qctx->tag_len = arg; qctx->M = arg; ret = 1; goto end; case EVP_CTRL_AEAD_GET_TAG: DEBUG("EVP_CTRL_CCM_GET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg <= QAT_CCM_TAG_MIN_LEN || arg > QAT_CCM_TAG_MAX_LEN || !enc) { WARN("TAG length invalid or invalid operation (!enc)\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_SET_TAG_INVALID_OP); return 0; } if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx) || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_INVALID_PTR); return 0; } qctx->iv_set = 0; qctx->len_set = 0; if (!qctx->tag_set) { qctx->tag_set = 0; goto end; } memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(ctx), arg); qctx->tag_set = 0; return 1; case EVP_CTRL_CCM_SET_IV_FIXED: DEBUG("EVP_CTRL_CCM_SET_IV_FIXED, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_INVALID_PTR); return 0; } /* Special case: -1 length restores whole IV */ if (arg == -1) { memcpy(qctx->next_iv, ptr, QAT_CCM_TLS_TOTAL_IV_LEN); ret = 1; goto end; } /* Fixed field must be at least 4 bytes (EVP_CCM_TLS_FIXED_IV_LEN) * and invocation field at least 8 (EVP_CCM_TLS_EXPLICIT_IV_LEN) */ if ((arg < EVP_CCM_TLS_FIXED_IV_LEN) || (qctx->iv_len - arg) < EVP_CCM_TLS_EXPLICIT_IV_LEN) { WARN("IV length invalid\n"); ret = 0; goto end; } if (arg != EVP_CCM_TLS_FIXED_IV_LEN) { WARN("IV length not supported\n"); return 0; } if (arg) { memcpy(qctx->next_iv, ptr, arg); } ret = 1; goto end; case EVP_CTRL_AEAD_SET_IVLEN: DEBUG("EVP_CTRL_CCM_SET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); l_value = QAT_AES_CCM_OP_VALUE - arg; /* fall thru */ case EVP_CTRL_CCM_SET_L: DEBUG("EVP_CTRL_CCM_SET_L, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (l_value < 2 || l_value > 8) { if (arg < 2 || arg > 8) { return 0; } else { l_value = arg; } } qctx->L = l_value; ret = 1; goto end; case EVP_CTRL_AEAD_TLS1_AAD: DEBUG("EVP_CTRL_AEAD_TLS1_AAD, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (TLS_VIRT_HDR_SIZE != arg) { WARN("AAD length is not valid\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_AAD_LEN_INVALID); return 0; } /* Allocate the memory only the first time */ if (qctx->tls_aad_len < 0) { int aad_buffer_len = TLS_VIRT_HDR_SIZE; DEBUG("Allocating memory for AAD in TLS sync\n"); /* For QAT the length of the buffer for AAD must be multiple * of block size */ if (aad_buffer_len % AES_BLOCK_SIZE) { aad_buffer_len += AES_BLOCK_SIZE - (aad_buffer_len % AES_BLOCK_SIZE); DEBUG("Adjusting AAD buffer length = %d\n", aad_buffer_len); } qctx->aad = qat_mem_alloc(aad_buffer_len, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->aad) { WARN("Unable to allocate memory for TLS header\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_AAD_MALLOC_FAILURE); ret = 0; goto end; } /* Set the flag to mark the TLS case */ qctx->tls_aad_len = arg; /* Set the length of the AAD in the session * The session hasn't been initialized yet here and this value * should never change in the TLS case */ if (qctx->session_data != NULL) qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = arg; } if (NULL == qctx->aad || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_AAD_INVALID_PTR); ret = 0; goto end; } /* Copy the header from p into the buffer */ memcpy(qctx->aad, ptr, arg); /* Extract the length of the payload from the TLS header */ plen = qctx->aad[arg - QAT_CCM_TLS_PAYLOADLENGTH_MSB_OFFSET] << QAT_BYTE_SHIFT | qctx->aad[arg - QAT_CCM_TLS_PAYLOADLENGTH_LSB_OFFSET]; DEBUG("IN plen = %d\n", plen); DUMPL("IN qctx->aad", qctx->aad, TLS_VIRT_HDR_SIZE); /* The payload contains the explicit IV -> correct the length */ plen -= EVP_CCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!enc) { plen -= qctx->M; } /* Fix the length like in the SW version of CCM */ qctx->aad[arg - QAT_CCM_TLS_PAYLOADLENGTH_MSB_OFFSET] = plen >> QAT_BYTE_SHIFT; qctx->aad[arg - QAT_CCM_TLS_PAYLOADLENGTH_LSB_OFFSET] = plen & 0xff; DEBUG("OUT plen = %d\n", plen); DUMPL("OUT qctx->aad", qctx->aad, TLS_VIRT_HDR_SIZE); /* Return the length of the TAG */ ret = qctx->M; goto end; case EVP_CTRL_COPY: ret = 1; goto end; default: WARN("Invalid type %d\n", type); QATerr(QAT_F_QAT_AES_CCM_CTRL, QAT_R_INVALID_CTRL_TYPE); return -1; } end: #ifndef QAT_OPENSSL_PROVIDER # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (type == EVP_CTRL_INIT || qctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) fallback = 1; # endif if (qat_get_sw_fallback_enabled()) fallback = 1; if (fallback) { if (type == EVP_CTRL_INIT && qctx->sw_ctx_cipher_data == NULL) { unsigned int sw_size = 0; sw_size = EVP_CIPHER_impl_ctx_size(GET_SW_AES_CCM_CIPHER(ctx)); qctx->sw_ctx_cipher_data = OPENSSL_zalloc(sw_size); if (qctx->sw_ctx_cipher_data == NULL) { WARN("Unable to allocate memory for sw_ctx_cipher_data\n"); return -1; } } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_sw = EVP_CIPHER_meth_get_ctrl(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, type, arg, ptr); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (ret_sw < 0) { WARN("SW aes-ccm ctrl function failed.\n"); return -1; } return ret_sw; } # endif return ret; } /****************************************************************************** * function: * qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER int qat_aes_ccm_cleanup(void *ctx) # else int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx) # endif { # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; # else qat_ccm_ctx *qctx = NULL; # endif CpaStatus sts = 0; CpaCySymSessionSetupData *session_data = NULL; CpaBoolean sessionInUse = CPA_FALSE; int ret_val = 1; DEBUG("- Entering\n"); if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_CLEANUP, QAT_R_CTX_NULL); return 0; } # ifndef QAT_OPENSSL_PROVIDER qctx = QAT_CCM_GET_CTX(ctx); if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_CLEANUP, QAT_R_QCTX_NULL); return 0; } # endif /* Wait for in-flight requests before removing session */ if (qctx->qat_ctx != NULL) { do { cpaCySymSessionInUse(qctx->qat_ctx, &sessionInUse); } while (sessionInUse); } session_data = qctx->session_data; if (session_data) { /* Remove the session */ if (qctx->qat_ctx) { if (is_instance_available(qctx->inst_num)) { sts = cpaCySymRemoveSession(qat_instance_handles[qctx->inst_num], qctx->qat_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, sts = %d.!\n", sts); ret_val = 0; /* Lets not return yet and instead make a best effort to * cleanup the rest to avoid memory leaks */ } } /* Cleanup the memory */ QAT_MEM_FREE_NONZERO_BUFF(qctx->qat_ctx, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->srcBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->dstBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_BUFF(qctx->cipher_key, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->aad, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->OpData.pAdditionalAuthData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->OpData.pIv, qctx->qat_svm); qctx->qat_ctx = NULL; qctx->srcBufferList.pPrivateMetaData = NULL; qctx->dstBufferList.pPrivateMetaData = NULL; qctx->OpData.pAdditionalAuthData = NULL; qctx->OpData.pIv = NULL; qctx->cipher_key = NULL; qctx->aad = NULL; } session_data->cipherSetupData.pCipherKey = NULL; OPENSSL_clear_free(session_data, sizeof(CpaCySymSessionSetupData)); } qctx->is_session_init = 0; # ifdef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx) { OPENSSL_free(qctx->sw_ctx); qctx->sw_ctx = NULL; } # else qctx->packet_size = 0; if (qctx->sw_ctx_cipher_data) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } # endif return ret_val; } /****************************************************************************** * * function: * * static void qat_ccm_cb(void *pCallbackTag, CpaStatus status, * const CpaCySymOp operationType, * void *pOpData, CpaBufferList *pDstBuffer, * CpaBoolean verifyResult) * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. Cast to op_done_pipe_t. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: Callback to indicate the completion of crypto operation ******************************************************************************/ static void qat_ccm_cb(void *pCallbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList * pDstBuffer, CpaBoolean verifyResult) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); } DEBUG("status is = %d | verifyResult is = %d | tag function called %p \n", status, verifyResult, (struct COMPLETION_STRUCT *)pCallbackTag); qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, verifyResult); } /****************************************************************************** * function: * qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function synchronises the initialisation of the QAT session and * pre-allocates the necessary buffers for the session. ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER static int qat_aes_ccm_session_init(void *ctx, int *fallback) # else static int qat_aes_ccm_session_init(EVP_CIPHER_CTX *ctx, int *fallback) # endif { # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = NULL; # else qat_ccm_ctx *qctx = NULL; # endif CpaCySymSessionSetupData *sessionSetupData = NULL; Cpa32U sessionCtxSize = 0; CpaCySymSessionCtx pSessionCtx = NULL; int numBuffers = 1, enc = 0; CpaStatus status; DEBUG("- Entering\n"); if (NULL == ctx) { WARN("parameter ctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, QAT_R_CTX_NULL); return 0; } # ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_PROV_CCM_CTX *) ctx; enc = QAT_CCM_GET_ENC(qctx);; # else qctx = QAT_CCM_GET_CTX(ctx); enc = EVP_CIPHER_CTX_encrypting(ctx); # endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, QAT_R_QCTX_NULL); return 0; } /* All parameters have not been set yet or we have already been * initialised. */ if ((1 != qctx->init_params_set) || (1 == qctx->is_session_init)) { WARN("Parameters not set or session already initialised\n"); if (qat_get_sw_fallback_enabled()) *fallback = 1; return 0; } sessionSetupData = qctx->session_data; if (NULL == sessionSetupData) { WARN("sessionSetupData is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, QAT_R_SSD_NULL); return 0; } /* Update digestResultLenInBytes with qctx->tag_len if both lengths are mismatch for decryption */ if (!enc) { DEBUG("digestResultLenInBytes = %d, tag len = %d\n", sessionSetupData->hashSetupData.digestResultLenInBytes, (int)qctx->M); if (!(qctx->tag_len < 0) && sessionSetupData->hashSetupData.digestResultLenInBytes != qctx->M) { sessionSetupData->hashSetupData.digestResultLenInBytes = qctx->M; DEBUG("Taglen updated\n"); } } if ((qctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get QAT Instance Handle\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } return 0; } status = cpaCySymSessionCtxGetSize(qat_instance_handles[qctx->inst_num], sessionSetupData, &sessionCtxSize); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); if (qat_get_sw_fallback_enabled()) *fallback = 1; return 0; } pSessionCtx = (CpaCySymSessionCtx) qat_mem_alloc(sessionCtxSize, qctx->qat_svm, __FILE__, __LINE__); if (NULL == pSessionCtx) { WARN("pSessionCtx malloc failed\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); return 0; } DUMP_SESSION_SETUP_DATA(sessionSetupData); status = cpaCySymInitSession(qat_instance_handles[qctx->inst_num], qat_ccm_cb, sessionSetupData, pSessionCtx); if (status == CPA_STATUS_SUCCESS) { if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } } else { QAT_MEM_FREE_BUFF(pSessionCtx, qctx->qat_svm); WARN("cpaCySymInitSession failed! Status = %d\n", status); if (qat_get_sw_fallback_enabled() && ((status == CPA_STATUS_RESTARTING) || (status == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; return 0; } else { WARN("- No QAT instance available and s/w fallback not enabled.\n"); return 0; } } qctx->qat_ctx = pSessionCtx; /* Setup meta data for buffer lists */ status = cpaCyBufferListGetMetaSize(qat_instance_handles[qctx->inst_num], numBuffers, &(qctx->meta_size)); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetMetaSize failed for the instance id %d\n", qctx->inst_num); if (qat_get_sw_fallback_enabled()) { *fallback = 1; goto err; } QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); } qctx->srcBufferList.numBuffers = numBuffers; qctx->srcBufferList.pBuffers = &qctx->srcFlatBuffer; qctx->srcBufferList.pUserData = NULL; qctx->dstBufferList.numBuffers = numBuffers; qctx->dstBufferList.pBuffers = &qctx->dstFlatBuffer; qctx->dstBufferList.pUserData = NULL; if (qctx->meta_size) { qctx->srcBufferList.pPrivateMetaData = qat_mem_alloc(qctx->meta_size, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->srcBufferList.pPrivateMetaData) { WARN("srcBufferList.pPrivateMetaData is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); goto err; } qctx->dstBufferList.pPrivateMetaData = qat_mem_alloc(qctx->meta_size, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->dstBufferList.pPrivateMetaData) { WARN("dstBufferList.pPrivateMetaData is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); goto err; } } else { qctx->srcBufferList.pPrivateMetaData = NULL; qctx->dstBufferList.pPrivateMetaData = NULL; } /* Create the OpData structure to remove this processing from the data * path */ qctx->OpData.sessionCtx = qctx->qat_ctx; qctx->OpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL; /* Set the IV */ if (NULL == qctx->OpData.pIv) { qctx->OpData.pIv = qat_mem_alloc(QAT_CCM_IV_MAX_LEN, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->OpData.pIv) { WARN("qctx->OpData.pIv is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); goto err; } memcpy(&qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], qctx->next_iv, qctx->iv_len); } /* Set the AAD */ if (NULL == qctx->OpData.pAdditionalAuthData) { int aad_buffer_len = qctx->packet_size; if (qctx->tls_aad_len < 0) { DEBUG("Allocating memory for AAD in TLS sync\n"); /* For QAT the length of the buffer for AAD must be multiple * of block size */ if (aad_buffer_len % AES_BLOCK_SIZE) { aad_buffer_len += AES_BLOCK_SIZE - (aad_buffer_len % AES_BLOCK_SIZE); DEBUG("Adjusting AAD buffer length = %d\n", aad_buffer_len); } } qctx->OpData.pAdditionalAuthData = qat_mem_alloc(aad_buffer_len + QAT_CCM_IV_MAX_LEN, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->OpData.pAdditionalAuthData) { WARN("qctx->OpData.pAdditionalAuthData is NULL.\n"); QATerr(QAT_F_QAT_AES_CCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); goto err; } if (qctx->aad) { memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], qctx->aad, qctx->session_data->hashSetupData. authModeSetupData.aadLenInBytes); } memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_IV_WRITE_BUFFER], qctx->next_iv, qctx->iv_len); } DUMPL("qctx->OpData.pAdditionalAuthData", &qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); /* All the data in the buffer must be encrypted */ qctx->OpData.cryptoStartSrcOffsetInBytes = 0; /* Following parameters are ignored in CCM */ qctx->OpData.messageLenToHashInBytes = 0; qctx->OpData.hashStartSrcOffsetInBytes = 0; qctx->OpData.pDigestResult = NULL; qctx->is_session_init = 1; return 1; err: QAT_MEM_FREE_NONZERO_BUFF(qctx->srcBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->dstBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->OpData.pIv, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(pSessionCtx, qctx->qat_svm); qctx->srcBufferList.pPrivateMetaData = NULL; qctx->dstBufferList.pPrivateMetaData = NULL; qctx->OpData.pIv = NULL; pSessionCtx = NULL; qctx->qat_ctx = NULL; return 0; } /****************************************************************************** * function: * qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * const unsigned char *in, size_t len) * * @param ctx [IN] - pointer to existing context * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval 0 function failed * @retval 1 function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * This is the function used in the TLS case. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER int qat_aes_ccm_tls_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) # else int qat_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) # endif { # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; QAT_EVP_CIPHER sw_aes_ccm_cipher; # else qat_ccm_ctx *qctx = NULL; # endif CpaStatus sts = 0; op_done_t op_done; int ret_val = -1; int job_ret = 0; int enc = 0; int fallback = 0; # if !defined(ENABLE_QAT_SMALL_PKT_OFFLOAD) || defined(QAT_OPENSSL_PROVIDER) int nid = 0; # endif unsigned int message_len = 0; unsigned int buffer_len = 0; thread_local_variables_t *tlv = NULL; CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_CTX_NULL); return -1; } # ifndef QAT_OPENSSL_PROVIDER qctx = QAT_CCM_GET_CTX(ctx); # endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_QCTX_NULL); return -1; } /* Encrypt/decrypt must be performed in place */ if (NULL == in || out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M)) { WARN("Input parameters are not valid.\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_INVALID_LEN); return -1; } # ifdef QAT_OPENSSL_PROVIDER enc = QAT_CCM_GET_ENC(qctx); nid = qctx->nid; # else enc = EVP_CIPHER_CTX_encrypting(ctx); # endif # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifndef QAT_OPENSSL_PROVIDER nid = EVP_CIPHER_CTX_nid(ctx); # endif # endif DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void *)ctx, (void *)out, (void *)in, len); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD qctx->packet_size = len; if ((len - (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M)) <= qat_pkt_threshold_table_get_threshold(nid)) { DEBUG("Using OpenSSL SW for Packetsize %zu\n", len - (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M)); fallback = 1; goto err; } # endif /* The key has been set in the init function: no need to check it here */ /* Initialize the session if not done before */ if (0 == qctx->is_session_init) { # ifdef QAT_OPENSSL_PROVIDER if (0 == qat_aes_ccm_session_init(qctx, &fallback)) { # else if (0 == qat_aes_ccm_session_init(ctx, &fallback)) { # endif WARN("Unable to initialise Cipher context.\n"); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } goto err; } } else { memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], qctx->aad, qctx->tls_aad_len); } /* Encryption: generate explicit IV and write to start of buffer. * Decryption: read the explicit IV from start of buffer */ if (enc) { memcpy(&qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], qctx->next_iv, qctx->iv_len); /* Copy the explicit IV to the output buffer */ memcpy(out, qctx->next_iv + EVP_CCM_TLS_FIXED_IV_LEN, EVP_CCM_TLS_EXPLICIT_IV_LEN); qctx->iv_set = 1; } else { /* Retrieve the explicit IV from the message buffer */ memcpy(qctx->next_iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Set the IV that will be used in the current operation */ memcpy(&qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], qctx->next_iv, qctx->iv_len); qctx->iv_set = 1; } DUMPL("Post ctrl IV: ", &qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], qctx->iv_len); DUMPL("Post ctrl next IV: ", qctx->next_iv, qctx->iv_len); DUMPL("qctx->OpData.pAdditionalAuthData", &qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); /* Set the generated IV to OpData */ if (qctx->iv_set) { memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_IV_WRITE_BUFFER], &qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], qctx->iv_len); qctx->OpData.ivLenInBytes = QAT_AES_CCM_OP_VALUE - qctx->L; } /* If key or IV not set, throw error here and return. */ if (!qctx->key_set || !qctx->iv_set) { WARN("Cipher key or IV not set.\n"); if (qat_get_sw_fallback_enabled()) { fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else { QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, QAT_R_KEY_IV_NOT_SET); } goto err; } /* Include the explicit part of the IV at the beginning of the output */ in += EVP_CCM_TLS_EXPLICIT_IV_LEN; out += EVP_CCM_TLS_EXPLICIT_IV_LEN; /* This is the length of the message that must be encrypted */ message_len = len - (EVP_CCM_TLS_EXPLICIT_IV_LEN + qctx->M); /* The buffer must have enough memory to save also the TAG */ buffer_len = message_len + qctx->M; /* Build request/response buffers */ /* Allocate the memory of the FlatBuffer and copy the payload */ if (!qctx->qat_svm) qctx->srcFlatBuffer.pData = qaeCryptoMemAlloc(buffer_len, __FILE__, __LINE__); else qctx->srcFlatBuffer.pData = (Cpa8U *) in; if (NULL == qctx->srcFlatBuffer.pData) { WARN("src/dst buffer allocation.\n"); goto err; } if (!qctx->qat_svm) qctx->dstFlatBuffer.pData = qctx->srcFlatBuffer.pData; else qctx->dstFlatBuffer.pData = (Cpa8U *) out; if (!enc) { /* Decryption: the tag is appended and must be copied to the buffer */ if (!qctx->qat_svm) memcpy(qctx->srcFlatBuffer.pData, in, message_len + qctx->M); qctx->tag_len = qctx->M; } else { /* Encryption: copy only the payload */ if (!qctx->qat_svm) memcpy(qctx->srcFlatBuffer.pData, in, message_len); } /* The operation is done in place in the buffers * The variables in and out remain separate */ qctx->srcFlatBuffer.dataLenInBytes = buffer_len; qctx->srcBufferList.pUserData = NULL; qctx->dstFlatBuffer.dataLenInBytes = buffer_len; qctx->dstBufferList.pUserData = NULL; qctx->OpData.messageLenToCipherInBytes = message_len; tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); DUMP_SYM_PERFORM_OP_GCM_CCM(qat_instance_handles[qctx->inst_num], qctx->OpData, qctx->srcBufferList, qctx->dstBufferList); sts = qat_sym_perform_op(qctx->inst_num, &op_done, &(qctx->OpData), &(qctx->srcBufferList), &(qctx->dstBufferList), &(qctx->session_data->verifyDigest)); if (sts != CPA_STATUS_SUCCESS) { if (!qctx->qat_svm) { qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } qat_cleanup_op_done(&op_done); WARN("cpaCySymPerformOp failed sts=%d.\n", sts); if (qat_get_sw_fallback_enabled() && (sts == CPA_STATUS_RESTARTING || sts == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); } goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_AES_CCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); if (enc && CPA_STATUS_SUCCESS == op_done.status) { #ifdef QAT_OPENSSL_PROVIDER *padlen = len; ret_val = 1; #else ret_val = len; #endif DEBUG("Encryption succeeded\n"); } else if (!enc && CPA_TRUE == op_done.verifyResult) { #ifdef QAT_OPENSSL_PROVIDER *padlen = message_len; ret_val = 1; #else ret_val = message_len; #endif DEBUG("Decryption succeeded\n"); } else { if (enc) DEBUG("Encryption failed\n"); else DEBUG("Decryption failed\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; /* Probably already set anyway */ WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } } DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(qctx->dstBufferList); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); qat_cleanup_op_done(&op_done); if (!qctx->qat_svm) { memcpy(out, qctx->dstFlatBuffer.pData, message_len + qctx->M); qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } DUMPL("Digest Result", out, message_len + qctx->M); err: /* Don't reuse the IV */ qctx->iv_set = 0; if (fallback) { # ifdef QAT_OPENSSL_PROVIDER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); if (sw_aes_ccm_cipher.cupdate == NULL) return 0; ret_val = sw_aes_ccm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); if (!ret_val) return 0; # else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); # endif } return ret_val; } /****************************************************************************** * function: * qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * size_t *padlen, const unsigned char *in, * size_t len) * * @param ctx [IN] - pointer to existing context * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval len function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * This is the implementation of the Update case: the AAD is added by calling * UpdateEncrypt() with out == NULL. * This is the case used in the speed test. * * The flag EVP_CIPH_FLAG_CUSTOM_CIPHER is required to have the Update function * working correctly when out == NULL, that is when setting the AAD. * When this flag is enabled, the function must return -1 in case of failure and * the length of the output (value >= 0) for success. * * QAT vs SW Engine * ================ * * In the Update use case, the behavior of the functions is different between * the QAT and the SW engine. * * EVP Function SW Engine QAT Engine * ---------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * * This doesn't impact the TLS case because Update and Final are considered * a single operation like in the QAT engine. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER int qat_aes_ccm_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) # else int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) # endif { # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; const int RET_SUCCESS = 1; int final_fallback = 0; QAT_EVP_CIPHER sw_aes_ccm_cipher; # else qat_ccm_ctx *qctx = NULL; const int RET_SUCCESS = 0; # endif CpaStatus sts = 0; op_done_t op_done; const int RET_FAIL = -1; int ret_val = RET_FAIL; int job_ret = 0; int enc = 0; int fallback = 0; size_t aad_len = 0; int aad_buffer_len = 0; unsigned buffer_len = 0; thread_local_variables_t *tlv = NULL; # if !defined(ENABLE_QAT_SMALL_PKT_OFFLOAD) || defined(QAT_OPENSSL_PROVIDER) int nid = 0; # endif CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, QAT_R_CTX_NULL); return RET_FAIL; } # ifdef QAT_OPENSSL_PROVIDER enc = qctx->enc; nid = qctx->nid; # else qctx = QAT_CCM_GET_CTX(ctx); enc = EVP_CIPHER_CTX_encrypting(ctx); # endif # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifndef QAT_OPENSSL_PROVIDER nid = EVP_CIPHER_CTX_nid(ctx); # endif # endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, QAT_R_QCTX_NULL); return RET_FAIL; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); fallback = 1; goto end; } DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void *)ctx, (void *)out, (void *)in, len); /* Distinguish the Update and TLS case */ if (qctx->tls_aad_len >= 0) { # ifdef QAT_OPENSSL_PROVIDER return qat_aes_ccm_tls_cipher(ctx, out, padlen, outsize, in, len); # else return qat_aes_ccm_tls_cipher(ctx, out, in, len); # endif } /* If either key or IV not set, throw error here. */ if (!qctx->key_set || !qctx->iv_set) { WARN("Cipher key or IV not set.\n"); if (qat_get_sw_fallback_enabled()) { fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto end; } else { QATerr(QAT_F_QAT_AES_CCM_CIPHER, QAT_R_KEY_IV_NOT_SET); } return RET_FAIL; } if ((in == NULL) && (out == NULL)) { if (qctx->OpData.pIv == NULL) { qctx->OpData.pIv = qat_mem_alloc(QAT_CCM_IV_MAX_LEN, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->OpData.pIv) { WARN("Unable to allocate memory for qctx->OpData.pIv\n"); return RET_FAIL; } } memcpy(&qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], qctx->next_iv, qctx->iv_len); qctx->len_set = 1; # ifdef QAT_OPENSSL_PROVIDER *padlen = len; # endif if (qat_get_sw_fallback_enabled()) goto end; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD goto end; # else return len; # endif } /* This is called when doing Update */ if (in) { if (out == NULL) { DEBUG("in != NULL && out == NULL -> Adding AAD\n"); aad_len = len; /* Check if the length of the AAD has changed */ if (qctx->session_data->hashSetupData. authModeSetupData.aadLenInBytes != aad_len) { /* Free the memory used for the previous AAD */ if (qctx->OpData.pAdditionalAuthData) { QAT_MEM_FREE_BUFF(qctx->OpData.pAdditionalAuthData, qctx->qat_svm); qctx->OpData.pAdditionalAuthData = NULL; } /* For QAT the length of the buffer for AAD must be multiple of block size */ aad_buffer_len = aad_len; if (aad_buffer_len % AES_BLOCK_SIZE) { aad_buffer_len += AES_BLOCK_SIZE - (aad_buffer_len % AES_BLOCK_SIZE); DEBUG("Adjusting AAD buffer length = %d\n", aad_buffer_len); } qctx->OpData.pAdditionalAuthData = qat_mem_alloc(aad_buffer_len + QAT_CCM_IV_MAX_LEN, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->OpData.pAdditionalAuthData) { WARN("Unable to allocate memory for AAD\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } /* Set the length of the AAD */ qctx->session_data->hashSetupData. authModeSetupData.aadLenInBytes = aad_len; } memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], in, aad_len); DUMPL("qctx->aad", &qctx->OpData.pAdditionalAuthData[QAT_CCM_AAD_WRITE_BUFFER], aad_len); /* The pAdditionalAuthData will be initialized firstly in * qat_aes_ccm_session_init(), but the AAD can be updated * for several times. So it is very important to update the * AAD pointer in qat OpData structure in time. */ memcpy(&qctx->OpData.pAdditionalAuthData[QAT_CCM_IV_WRITE_BUFFER], &qctx->OpData.pIv[QAT_CCM_IV_WRITE_BUFFER], QAT_AES_CCM_OP_VALUE - qctx->L); # ifdef QAT_OPENSSL_PROVIDER *padlen = aad_len; # endif if (qat_get_sw_fallback_enabled()) goto end; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD goto end; # else return 1; # endif } else { /* The key has been set in the init function: no need to check it */ # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD qctx->packet_size = len; if (len <= qat_pkt_threshold_table_get_threshold(nid)) { DEBUG("Using OpenSSL SW for Packetsize %zu\n", len); # ifdef QAT_OPENSSL_PROVIDER *padlen = len; # endif goto end; } # endif if (0 == qctx->is_session_init) { # ifdef QAT_OPENSSL_PROVIDER if (0 == qat_aes_ccm_session_init(qctx, &fallback)) { # else if (0 == qat_aes_ccm_session_init(ctx, &fallback)) { # endif WARN("Unable to initialise Cipher context.\n"); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto end; } return RET_FAIL; } } if (len == 0) buffer_len = EVP_CCM_TLS_TAG_LEN; else buffer_len = len + EVP_CCM_TLS_TAG_LEN; /* Build request/response buffers */ /* Allocate the memory of the FlatBuffer and copy the payload */ if (!qctx->qat_svm) qctx->srcFlatBuffer.pData = qaeCryptoMemAlloc(buffer_len, __FILE__, __LINE__); else qctx->srcFlatBuffer.pData = (Cpa8U *) in; if (NULL == qctx->srcFlatBuffer.pData) { WARN("src/dst buffer allocation.\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } if (!qctx->qat_svm) { qctx->dstFlatBuffer.pData = qctx->srcFlatBuffer.pData; memcpy(qctx->srcFlatBuffer.pData, in, len); } else { qctx->dstFlatBuffer.pData = (Cpa8U *) out; } /* The operation is done in place in the buffers * The variables in and out remain separate */ qctx->srcFlatBuffer.dataLenInBytes = buffer_len; qctx->srcBufferList.pUserData = NULL; qctx->dstFlatBuffer.dataLenInBytes = buffer_len; qctx->dstBufferList.pUserData = NULL; qctx->OpData.messageLenToCipherInBytes = len; # ifdef QAT_OPENSSL_PROVIDER qctx->OpData.ivLenInBytes = QAT_AES_CCM_OP_VALUE - qctx->L; qctx->OpData.cryptoStartSrcOffsetInBytes = 0; # endif /* Decryption: set the digest (tag) for verification * This is different from SW implementation. Here we have a single * function to decrypt AND verify */ if (!enc) { /* Copy EVP_CCM_TLS_TAG_LEN bytes from tag buffer as the maximum tag length can only be EVP_CCM_TLS_TAG_LEN */ # ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->dstFlatBuffer.pData + len, qctx->buf, qctx->M); # else if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx)) { WARN("Tag not set\n"); if (!qctx->qat_svm) { qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } return RET_FAIL; } else { memcpy(qctx->dstFlatBuffer.pData + len, EVP_CIPHER_CTX_buf_noconst(ctx), qctx->M); } # endif } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); qat_cleanup_op_done(&op_done); QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } } DUMP_SYM_PERFORM_OP_GCM_CCM(qat_instance_handles[qctx->inst_num], qctx->OpData, qctx->srcBufferList, qctx->dstBufferList); DUMPL("AAD: ", qctx->OpData.pAdditionalAuthData, qctx->session_data->hashSetupData. authModeSetupData.aadLenInBytes); sts = qat_sym_perform_op(qctx->inst_num, &op_done, &(qctx->OpData), &(qctx->srcBufferList), &(qctx->dstBufferList), &(qctx->session_data->verifyDigest)); if (sts != CPA_STATUS_SUCCESS) { if (!qctx->qat_svm) { qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } qat_cleanup_op_done(&op_done); WARN("cpaCySymPerformOp failed sts=%d.\n", sts); if (qat_get_sw_fallback_enabled() && (sts == CPA_STATUS_RESTARTING || sts == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto end; } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto end; } else { QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); QATerr(QAT_F_QAT_AES_CCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, 0)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(qctx->dstBufferList); if (enc && CPA_STATUS_SUCCESS == op_done.status) { ret_val = len; DEBUG("Encryption succeeded\n"); } else if (!enc && (CPA_TRUE == op_done.verifyResult)) { ret_val = len; DEBUG("Decryption succeeded\n"); } else { if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG( "Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto end; } DEBUG("Encryption or Decryption failed\n"); } QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); qat_cleanup_op_done(&op_done); if (enc) { /* After encryption, copy the TAG from the buffer to the ctx */ # ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->buf, qctx->dstFlatBuffer.pData + len, qctx->M); DUMPL("TAG calculated by QAT", qctx->buf, qctx->M); # endif memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), qctx->dstFlatBuffer.pData + len, qctx->M); DUMPL("TAG calculated by QAT", EVP_CIPHER_CTX_buf_noconst(ctx), EVP_CCM_TLS_TAG_LEN); qctx->tag_len = qctx->M; qctx->tag_set = 1; } if (!qctx->qat_svm) { memcpy(out, qctx->dstFlatBuffer.pData, len); qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } # ifdef QAT_OPENSSL_PROVIDER *padlen = len; # endif return ret_val; } } else { # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifdef QAT_OPENSSL_PROVIDER if (len <= qat_pkt_threshold_table_get_threshold(nid)) final_fallback = 1; # endif # endif # ifdef QAT_OPENSSL_PROVIDER if (final_fallback || !qctx->tag_set) { qctx->iv_set = 0; sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); if (sw_aes_ccm_cipher.cfinal == NULL) return 0; ret_val = sw_aes_ccm_cipher.cfinal(qctx->sw_ctx, out, padlen, outsize); *padlen = len; return ret_val; } # endif if (!enc) { # if OPENSSL_VERSION_NUMBER < 0x30200000 if (qctx->tag_len < 0) { ret_val = RET_FAIL; goto end; } # endif /* Don't reuse the IV */ qctx->iv_set = 0; DEBUG("Decrypt Final()\n"); /* The SW implem here compares the TAGs and returns -1 if they are different. * Now the TAGs are checked when decrypting the payload so Final always return success */ return RET_SUCCESS; } DEBUG("Encrypt Final()\n"); /* The SW implem here copy the TAG to ctx->buf so that it can be * retrieved using ctrl() with GET_TAG. * Now the TAG is appended and has already been copied to that location * hence we do nothing. */ /* Don't reuse the IV */ qctx->iv_set = 0; return RET_SUCCESS; } end: # ifdef QAT_OPENSSL_PROVIDER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(nid); if (sw_aes_ccm_cipher.cupdate == NULL) return RET_FAIL; ret_val = sw_aes_ccm_cipher. cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); if (!ret_val) return RET_FAIL; # else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_CCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("ret_val = %d\n", ret_val); # endif return ret_val; } #endif qatengine-1.9.0/qat_hw_ccm.h000066400000000000000000000144071500416242000157520ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_ccm.h * * This file provides a interface for AES-CCM operations * *****************************************************************************/ #ifndef QAT_HW_CCM_H # define QAT_HW_CCM_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "cpa_cy_drbg.h" # define AES_CCM_IV_LEN 12 # define QAT_AES_CCM_OP_VALUE 15 # define QAT_CCM_IV_WRITE_BUFFER 1 # define QAT_CCM_AAD_WRITE_BUFFER 18 # define QAT_CCM_GET_CTX(ctx) (EVP_CIPHER_CTX_get_cipher_data(ctx)) # define QAT_CCM_GET_ENC(ctx) ((ctx)->enc) # define QAT_CCM_TLS_TOTAL_IV_LEN (EVP_CCM_TLS_FIXED_IV_LEN + EVP_CCM_TLS_EXPLICIT_IV_LEN) # define QAT_CCM_TLS_PAYLOADLENGTH_MSB_OFFSET 2 # define QAT_CCM_TLS_PAYLOADLENGTH_LSB_OFFSET 1 /* The length of valid CCM Tag must be between 0 and 16 Bytes */ # define QAT_CCM_TAG_MIN_LEN 0 # define QAT_CCM_TAG_MAX_LEN 16 # define QAT_CCM_IV_MAX_LEN 16 # define QAT_CCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CCM_MODE \ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_AEAD_CIPHER \ | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT) /* AES-CCM context */ typedef struct qat_aes_ccm_ctx_t { /* QAT Session Params */ int inst_num; CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx qat_ctx; int init_params_set; /* This flag is set to 1 when the session has been initialized */ int is_session_init; /* QAT Op Params */ CpaCySymOpData OpData; /* TODO Both buffer point to the same area of memory * and the operation is done in place. * Why am I using 2 separate buffers instead of one like in CCM sample? * Do I need to allocate and use separate metadata? */ CpaBufferList srcBufferList; CpaBufferList dstBufferList; CpaFlatBuffer srcFlatBuffer; CpaFlatBuffer dstFlatBuffer; /* -- Crypto -- */ /* IV that will be used in the next operation: * For current operation using oPData.pIv. * In the SW engine the IV in the context and the IV used by the cipher * are stored in different variables. * This is a separate value and can be modified without affecting * the current operation. * For example: TLS case increment the IV before doing the encryption, * but the current operation still used the not-incremented IV */ Cpa8U next_iv[EVP_MAX_IV_LENGTH]; /* Length of the IV (it is always 12 Byte for CCM in TLS case */ unsigned int iv_len; /* Flag that indicates whether the IV has been set * TODO The value is set correctly but never read and actually used... */ unsigned char iv_set; /* The tag is saved in evp_ctx->buf */ int tag_len; /* Pointer to AAD. * In the TLS case this will contain the TLS header */ Cpa8U *aad; /* -- TLS data -- */ /* Length of the AAD in the TLS case. * This is used like a flag: when Update case this is set to -1*/ int tls_aad_len; /* Size of the meta data for the driver * It cannot allocate memory so this must be done by the user application */ unsigned int meta_size; /* Pointer to pCipherKey */ Cpa8U *cipher_key; /* Flag to keep track of key passed */ int key_set; int len_set; int tag_set; int L, M; int packet_size; int nid; void *sw_ctx_cipher_data; int qat_svm; EVP_CIPHER_CTX *sw_ctx; EVP_CIPHER *sw_cipher; } qat_ccm_ctx; # ifdef QAT_OPENSSL_PROVIDER int qat_aes_ccm_init(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_aes_ccm_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len); int qat_aes_ccm_cleanup(void *ctx); int qat_aes_ccm_ctrl(void *ctx, int type, int arg, void *ptr); # else int qat_aes_ccm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc); int qat_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_aes_ccm_cleanup(EVP_CIPHER_CTX *ctx); int qat_aes_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); # endif #endif /* QAT_HW_CCM_H */ qatengine-1.9.0/qat_hw_chachapoly.c000066400000000000000000002163651500416242000173250ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_chachapoly.c * * This file provides an implementation of CHACHAPOLY operations for OpenSSL * engine * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include "openssl/ossl_typ.h" #include #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_utils.h" #include "qat_hw_ciphers.h" #include "qat_evp.h" #include "qat_hw_chachapoly.h" #ifdef QAT_HW_INTREE # ifndef ENABLE_QAT_HW_CHACHAPOLY # define ENABLE_QAT_HW_CHACHAPOLY # endif #endif #ifdef QAT_OPENSSL_PROVIDER #include "qat_prov_chachapoly.h" #endif # define GET_SW_CHACHA_CTX EVP_chacha20_poly1305() #ifdef ENABLE_QAT_HW_CHACHAPOLY # ifdef QAT_OPENSSL_PROVIDER static int qat_chacha20_poly1305_init_key_iv(QAT_PROV_CIPHER_CTX *cp_ctx, const unsigned char *key, const unsigned char *iv); static int qat_chacha20_poly1305_mac_keygen(QAT_PROV_CIPHER_CTX *cp_ctx); static void qat_chacha20_core(chacha_buf *output, const unsigned int input[16]); static void qat_chacha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, const unsigned int key[8], const unsigned int counter[4]); # else static int qat_chacha20_poly1305_init(EVP_CIPHER_CTX *ctx, const unsigned char *user_key, const unsigned char *iv, int enc); static int qat_chacha20_poly1305_do_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t len); static int qat_chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx); static int qat_chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); static int qat_chacha20_poly1305_init_key_iv(qat_chachapoly_ctx *cp_ctx, const unsigned char *key, const unsigned char *iv); static int qat_chacha20_poly1305_mac_keygen(qat_chachapoly_ctx *cp_ctx); static void qat_chacha20_core(chacha_buf *output, const unsigned int input[16]); static void qat_chacha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, const unsigned int key[8], const unsigned int counter[4]); # endif /****************************************************************************** * function: * chachapoly_cipher_meth(int nid, int keylen) * * @param nid [IN] - Cipher NID to be created * @param keylen [IN] - Key length of cipher * @retval - EVP_CIPHER * to created cipher * @retval - NULL if failure * * description: * create a new EVP_CIPHER based on requested nid ******************************************************************************/ const EVP_CIPHER *chachapoly_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; # ifndef QAT_OPENSSL_PROVIDER int res = 1; if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_CHACHA_POLY)) { /* block size is 1 and key size is 32 bytes. */ if ((c = EVP_CIPHER_meth_new(nid, 1, keylen)) == NULL) { WARN("Failed to allocate cipher methods for nid %d\n", nid); return NULL; } /* IV size is 12 bytes for TLS protocol */ res &= EVP_CIPHER_meth_set_iv_length(c, QAT_CHACHA20_POLY1305_MAX_IVLEN); res &= EVP_CIPHER_meth_set_flags(c, EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_CUSTOM_IV_LENGTH); res &= EVP_CIPHER_meth_set_init(c, qat_chacha20_poly1305_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_chacha20_poly1305_do_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_chacha20_poly1305_cleanup); res &= EVP_CIPHER_meth_set_impl_ctx_size(c, 0); res &= EVP_CIPHER_meth_set_set_asn1_params(c, NULL); res &= EVP_CIPHER_meth_set_get_asn1_params(c, NULL); res &= EVP_CIPHER_meth_set_ctrl(c, qat_chacha20_poly1305_ctrl); if (res == 0) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_CIPHER_meth_free(c); c = NULL; } qat_hw_chacha_poly_offload = 1; DEBUG("QAT HW CHACHA POLY registration succeeded\n"); return c; } else { qat_hw_chacha_poly_offload = 0; DEBUG("QAT HW CHACHA POLY is disabled, using OpenSSL SW\n"); EVP_CIPHER_meth_free(c); return EVP_chacha20_poly1305(); } # else return c; # endif } /****************************************************************************** * function: * qat_chachapoly_cb(void *callbackTag, CpaStatus status, * const CpaCySymOp operationType, void *pOpData, * CpaBufferList * pDstBuffer, CpaBoolean verifyResult) * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: * Callback function used by chachapoly. ******************************************************************************/ static void qat_chachapoly_cb(void *callbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList *pDstBuffer, CpaBoolean verifyResult) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); } qat_crypto_callbackFn(callbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } static const CpaCySymOpData template_opData = { .sessionCtx = NULL, .packetType = CPA_CY_SYM_PACKET_TYPE_FULL, .pIv = NULL, .ivLenInBytes = 0, .cryptoStartSrcOffsetInBytes = 0, .messageLenToCipherInBytes = 0, .hashStartSrcOffsetInBytes = 0, .messageLenToHashInBytes = 0, .pDigestResult = NULL, .pAdditionalAuthData = NULL }; /****************************************************************************** * function: * qat_chacha20_core(chacha_buf *output, const unsigned int input[16]) * * @param output [OUT] - output buffer to hold key bytes * @param input [IN] - input keystream * * description: * chacha_core performs 20 rounds of ChaCha on the input words in * "input" and writes the 64 output bytes to "output". ******************************************************************************/ static void qat_chacha20_core(chacha_buf *output, const unsigned int input[16]) { unsigned x[16]; int i; memcpy(x, input, sizeof(x)); for (i = 20; i > 0; i -= 2) { QUARTERROUND(0, 4, 8, 12); QUARTERROUND(1, 5, 9, 13); QUARTERROUND(2, 6, 10, 14); QUARTERROUND(3, 7, 11, 15); QUARTERROUND(0, 5, 10, 15); QUARTERROUND(1, 6, 11, 12); QUARTERROUND(2, 7, 8, 13); QUARTERROUND(3, 4, 9, 14); } for (i = 0; i < 16; ++i) output->u[i] = x[i] + input[i]; } /****************************************************************************** * function: * qat_chacha20_ctr32(unsigned char *out, const unsigned char *inp, * size_t len, const unsigned int key[8], * const unsigned int counter[4]) * * @param out [OUT] - output buffer to hold key bytes * @param inp [IN] - input keystream * @param len [IN] - length of input key buffer * @param key [IN] - chacha key collected into 8 64-bit elements * @param counter [IN] - nonce and counter values concatenated into 4 32-bit elements * * description: * ChaCha20_ctr32 encrypts "len" bytes from "inp" with the given key and * nonce and writes the result to "out", which may be equal to "inp". ******************************************************************************/ static void qat_chacha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, const unsigned int key[8], const unsigned int counter[4]) { static const char sigma[16] = "expand 32-byte k"; const char *constants; unsigned int input[16]; chacha_buf buf; size_t todo, i; constants = sigma; input[0] = U8TO32_LITTLE(constants + 0); input[1] = U8TO32_LITTLE(constants + 4); input[2] = U8TO32_LITTLE(constants + 8); input[3] = U8TO32_LITTLE(constants + 12); input[4] = key[0]; input[5] = key[1]; input[6] = key[2]; input[7] = key[3]; input[8] = key[4]; input[9] = key[5]; input[10] = key[6]; input[11] = key[7]; input[12] = counter[0]; input[13] = counter[1]; input[14] = counter[2]; input[15] = counter[3]; while (len > 0) { todo = sizeof(buf); if (len < todo) todo = len; qat_chacha20_core(&buf, input); for (i = 0; i < todo; i++) out[i] = inp[i] ^ buf.c[i]; out += todo; inp += todo; len -= todo; input[12]++; } } /****************************************************************************** * function: * qat_chacha20_poly1305_init_key_iv(qat_chachapoly_ctx *ctx, * const unsigned char *key, * const unsigned char *iv) * * @param ctx [IN] - pointer to existing cipher ctx * @param key [IN] - 256 bit cipher key * @param iv [IN] - 96 bit IV * * @retval 1 function succeeded * @retval 0 function failed * * description: * Initialise cipher key and IV in order to generate Poly1305(mac) key. ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_chacha20_poly1305_init_key_iv(QAT_PROV_CIPHER_CTX *cp_ctx, const unsigned char *key, const unsigned char *iv) #else static int qat_chacha20_poly1305_init_key_iv(qat_chachapoly_ctx *cp_ctx, const unsigned char *key, const unsigned char *iv) #endif { int i; if (cp_ctx == NULL) { WARN("chachapoly cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_INIT_KEY_IV, QAT_R_CHACHAPOLY_CTX_NULL); return 0; } if (iv != NULL) { unsigned char temp[QAT_CHACHA_CTR_SIZE] = { 0 }; if (cp_ctx->nonce_len <= QAT_CHACHA_CTR_SIZE) memcpy(temp + QAT_CHACHA_CTR_SIZE - cp_ctx->nonce_len, iv, cp_ctx->nonce_len); for (i = 0; i < QAT_CHACHA_CTR_SIZE; i+=4) cp_ctx->counter[i/4] = CHACHA_U8TOU32(temp+i); cp_ctx->iv[0] = cp_ctx->counter[1]; cp_ctx->iv[1] = cp_ctx->counter[2]; cp_ctx->iv[2] = cp_ctx->counter[3]; } if (key != NULL) { for (i = 0; i < QAT_CHACHA_KEY_SIZE; i+=4) cp_ctx->chacha_key[i/4] = CHACHA_U8TOU32(key+i); } return 1; } /****************************************************************************** * function: * qat_chacha20_poly1305_mac_keygen(qat_chachapoly_ctx *cp_ctx) * * @param ctx [IN] - pointer to existing cipher ctx * * @retval 1 function succeeded * @retval 0 function failed * * description: * Generate One-Time Poly1305 key for the hash operation * using cipher key and IV. ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_chacha20_poly1305_mac_keygen(QAT_PROV_CIPHER_CTX *cp_ctx) #else static int qat_chacha20_poly1305_mac_keygen(qat_chachapoly_ctx *cp_ctx) #endif { const unsigned char in_buf[2 * QAT_CHACHA_BLK_SIZE] = { 0 }; if (cp_ctx == NULL) { WARN("chachapoly cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_MAC_KEYGEN, QAT_R_CHACHAPOLY_CTX_NULL); return 0; } /* Initialise counter as 0. */ cp_ctx->counter[0] = 0; /* qat_chacha20_ctr32 encrypts QAT_CHACHA_BLK_SIZE bytes from in_buf * with the given key and nonce and writes the result * to cp_ctx->mac_key */ qat_chacha20_ctr32(cp_ctx->mac_key, in_buf, QAT_CHACHA_BLK_SIZE, cp_ctx->chacha_key, cp_ctx->counter); cp_ctx->mac_key_set = 1; return 1; } /****************************************************************************** * function: * qat_chachapoly_session_data_init(qat_chachapoly_ctx *cp_ctx, * const unsigned char *inkey, * const unsigned char *iv, * int enc) * * @param ctx [IN] - pointer to existing cipher ctx * @param inKey [IN] - cipher key * @param iv [IN] - initialisation vector * @param enc [IN] - 1 = encrypt, 0 = decrypt * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function is to create QAT specific session data. * It is called from the function qat_chacha20_poly1305_init(). ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_chachapoly_session_data_init(QAT_PROV_CIPHER_CTX *cp_ctx, const unsigned char* key, const unsigned char* iv, int enc) #else static int qat_chachapoly_session_data_init(qat_chachapoly_ctx *cp_ctx, const unsigned char* key, const unsigned char* iv, int enc) #endif { if (cp_ctx == NULL) { WARN("chachapoly cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, QAT_R_CHACHAPOLY_CTX_NULL); return 0; } if (cp_ctx->session_data == NULL) { cp_ctx->session_data = OPENSSL_zalloc(sizeof(CpaCySymSessionSetupData)); if (cp_ctx->session_data == NULL) { WARN("Failed to allocate session setup data\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, ERR_R_MALLOC_FAILURE); return 0; } } cp_ctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (cp_ctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); if (!qat_get_sw_fallback_enabled()) QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, ERR_R_INTERNAL_ERROR); return 0; } cp_ctx->qat_svm = !qat_instance_details[cp_ctx->inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; DEBUG("inst_num = %d inst mem type %d \n", cp_ctx->inst_num, cp_ctx->qat_svm); if (cp_ctx->mac_key == NULL) { cp_ctx->mac_key = qat_mem_alloc(QAT_CHACHA_BLK_SIZE, cp_ctx->qat_svm, __FILE__, __LINE__); if (cp_ctx->mac_key == NULL) { WARN("Failure in mac_key buffer allocation.\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, ERR_R_MALLOC_FAILURE); return -1; } } if (key != NULL) { memcpy(cp_ctx->cipher_key, key, QAT_CHACHA_KEY_SIZE); cp_ctx->key_set = 1; DUMPL("key", key, QAT_CHACHA_KEY_SIZE); } if (iv != NULL) { memcpy(cp_ctx->nonce, iv, QAT_CHACHA20_POLY1305_MAX_IVLEN); cp_ctx->iv_set = 1; DUMPL("IV", iv, QAT_CHACHA20_POLY1305_MAX_IVLEN); } cp_ctx->session_data->sessionPriority = CPA_CY_PRIORITY_HIGH; cp_ctx->session_data->symOperation = CPA_CY_SYM_OP_ALGORITHM_CHAINING; cp_ctx->session_data->cipherSetupData.cipherAlgorithm = CPA_CY_SYM_CIPHER_CHACHA; cp_ctx->session_data->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT; cp_ctx->session_data->cipherSetupData.cipherKeyLenInBytes = QAT_CHACHA_KEY_SIZE; /* Cipher key set NULL here as it will be set later. */ cp_ctx->session_data->cipherSetupData.pCipherKey = NULL; cp_ctx->session_data->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_POLY; cp_ctx->session_data->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH; cp_ctx->session_data->hashSetupData.digestResultLenInBytes = QAT_POLY1305_DIGEST_SIZE; cp_ctx->session_data->hashSetupData.authModeSetupData.authKey = NULL; cp_ctx->session_data->hashSetupData.authModeSetupData.authKeyLenInBytes = 0; cp_ctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = 0; /* ChachaPoly performs the chacha(cipher) operation first and then * the Poly MAC operation (hash) during encryption. */ cp_ctx->session_data->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; cp_ctx->session_data->digestIsAppended = CPA_FALSE; cp_ctx->session_data->verifyDigest = CPA_FALSE; if (!enc) { cp_ctx->session_data->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; cp_ctx->session_data->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER; } /* Partial requests not supported for CHACHA-POLY in the driver. */ cp_ctx->session_data->partialsNotRequired = CPA_TRUE; if (cp_ctx->opd == NULL) { cp_ctx->opd = OPENSSL_zalloc(sizeof(template_opData)); if (cp_ctx->opd == NULL) { WARN("memory allocation failed for symopData struct.\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, ERR_R_MALLOC_FAILURE); return 0; } /* Set cipher operation data template */ memcpy(cp_ctx->opd, &template_opData, sizeof(template_opData)); } /* Set cipher key and IV. */ if (cp_ctx->key_set && cp_ctx->iv_set) { if (qat_chacha20_poly1305_init_key_iv(cp_ctx, cp_ctx->cipher_key, cp_ctx->nonce)) { /* Generate Poly1305 mac key */ if (!qat_chacha20_poly1305_mac_keygen(cp_ctx)) { WARN("MAC keygen operation failed.\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, ERR_R_INTERNAL_ERROR); return 0; } DEBUG("Poly1305 key generated\n"); } cp_ctx->session_data->cipherSetupData.pCipherKey = cp_ctx->cipher_key; if (cp_ctx->opd->pIv == NULL) { cp_ctx->opd->pIv = qat_mem_alloc(QAT_CHACHA20_POLY1305_MAX_IVLEN, cp_ctx->qat_svm, __FILE__, __LINE__); if (cp_ctx->opd->pIv == NULL) { WARN("Malloc Failure for opd->pIv.\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SESSION_DATA_INIT, ERR_R_MALLOC_FAILURE); return 0; } } memcpy(cp_ctx->opd->pIv, cp_ctx->nonce, QAT_CHACHA20_POLY1305_MAX_IVLEN); cp_ctx->opd->ivLenInBytes = QAT_CHACHA20_POLY1305_MAX_IVLEN; } /* Mark session context init as set. */ cp_ctx->context_params_set = 1; DEBUG("Chachapoly context init set.\n"); return 1; } /****************************************************************************** * function: * qat_chacha20_poly1305_init(EVP_CIPHER_CTX *ctx, * const unsigned char *inkey, * const unsigned char *iv, * int enc) * * @param ctx [IN] - pointer to existing cipher ctx * @param inKey [IN] - cipher key * @param iv [IN] - initialisation vector * @param enc [IN] - 1 = encrypt, 0 = decrypt * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the cipher parameters for this EVP context. * This function can and will be **called multiple times** with some args * being NULL. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chacha20_poly1305_init(QAT_PROV_CIPHER_CTX *ctx, const unsigned char *user_key, int keylen, const unsigned char *iv, int ivlen, int enc) #else static int qat_chacha20_poly1305_init(EVP_CIPHER_CTX *ctx, const unsigned char *user_key, const unsigned char *iv, int enc) #endif { int ret = 1; int fallback = 0; if (unlikely(ctx == NULL)) { WARN("cipher context is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_INIT, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER sw_chachapoly_cipher; QAT_PROV_CIPHER_CTX *cp_ctx = ctx; #else qat_chachapoly_ctx *cp_ctx = qat_chachapoly_data(ctx); #endif if (cp_ctx == NULL) { WARN("chachapoly cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_INIT, QAT_R_CHACHAPOLY_CTX_NULL); return 0; } if (qat_get_sw_fallback_enabled()) fallback = 1; #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD fallback = 1; #endif /* Return 1 since it's not an error if key and IV not set. */ if (!user_key && !iv) { DEBUG("key and IV not set.\n"); ret = 1; goto end; } /* Initialize QAT session */ ret = qat_chachapoly_session_data_init(cp_ctx, user_key, iv, enc); if (ret == 0) { WARN("qat_chachapoly_session_data_init failed.\n"); if (fallback != 1) QATerr(QAT_F_QAT_CHACHA20_POLY1305_INIT, ERR_R_INTERNAL_ERROR); goto init_err; } DEBUG("Init complete. ctx %p, cp_ctx %p, Session data %p\n", ctx, cp_ctx, cp_ctx->session_data); goto end; init_err: if (cp_ctx->opd) { QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->opd->pIv, cp_ctx->qat_svm); OPENSSL_clear_free(cp_ctx->opd, sizeof(template_opData)); cp_ctx->opd = NULL; } if (cp_ctx->session_data != NULL) { OPENSSL_free(cp_ctx->session_data); cp_ctx->session_data = NULL; cp_ctx->context_params_set = 0; } end: if (fallback) { # ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx->sw_ctx_cipher_data); /* Run the software init function */ ret = EVP_CIPHER_meth_get_init(GET_SW_CHACHA_CTX)(ctx, user_key, iv, enc); EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx); # else OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; sw_chachapoly_cipher = get_default_cipher_chachapoly(); if (enc) { if (!cp_ctx->sw_ctx) cp_ctx->sw_ctx = sw_chachapoly_cipher.newctx(ctx); ret = sw_chachapoly_cipher.einit(cp_ctx->sw_ctx, user_key, keylen, iv, ivlen, params); } else { if (!cp_ctx->sw_ctx) cp_ctx->sw_ctx = sw_chachapoly_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); ret = sw_chachapoly_cipher.dinit(cp_ctx->sw_ctx, user_key, keylen, iv, ivlen, params); } # endif } return ret; } /****************************************************************************** * function: * qat_chachapoly_setup_op_params(qat_chachapoly_ctx *cp_ctx) * * @param ctx [IN] - pointer to existing ctx * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the crypto session and flatbuffer lists to be * passed to the driver. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER static int qat_chachapoly_setup_op_params(QAT_PROV_CIPHER_CTX *cp_ctx, int *fallback) # else static int qat_chachapoly_setup_op_params(qat_chachapoly_ctx *cp_ctx, int *fallback) # endif { int numBuffers = 1; /* Set numBuffers to 1. (For cipher and hash operations.) */ Cpa32U bufferMetaSize = 0; Cpa32U sctx_size = 0; CpaStatus status; if (cp_ctx == NULL) { WARN("chachapoly context cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SETUP_OP_PARAMS, QAT_R_CHACHAPOLY_CTX_NULL); return 0; } if (!cp_ctx->context_params_set || !cp_ctx->key_set) { WARN("Context params or key not set.\n"); if (qat_get_sw_fallback_enabled()) { *fallback = 1; } return 0; } status = cpaCySymSessionCtxGetSize(qat_instance_handles[cp_ctx->inst_num], cp_ctx->session_data, &sctx_size); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); if (qat_get_sw_fallback_enabled()) { *fallback = 1; } return 0; } DEBUG("Size of session ctx = %d\n", sctx_size); cp_ctx->session_ctx = (CpaCySymSessionCtx) qat_mem_alloc(sctx_size, cp_ctx->qat_svm, __FILE__, __LINE__); if (cp_ctx->session_ctx == NULL) { WARN("Memory alloc failed for session ctx\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SETUP_OP_PARAMS, ERR_R_MALLOC_FAILURE); return 0; } DUMP_SESSION_SETUP_DATA(cp_ctx->session_data); /* Initialise Session data */ status = cpaCySymInitSession(qat_instance_handles[cp_ctx->inst_num], qat_chachapoly_cb, cp_ctx->session_data, cp_ctx->session_ctx); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCySymInitSession failed! Status = %d\n", status); if (qat_get_sw_fallback_enabled() && ((status == CPA_STATUS_RESTARTING) || (status == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else WARN("- No QAT instance available and s/w fallback not enabled.\n"); QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->session_ctx, cp_ctx->qat_svm); return 0; } else { if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } } /* Get buffer metasize */ status = cpaCyBufferListGetMetaSize(qat_instance_handles[cp_ctx->inst_num], numBuffers, &bufferMetaSize); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetMetaSize failed for the instance id %d\n", cp_ctx->inst_num); QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->session_ctx, cp_ctx->qat_svm); if (qat_get_sw_fallback_enabled()) { *fallback = 1; } else QATerr(QAT_F_QAT_CHACHAPOLY_SETUP_OP_PARAMS, ERR_R_INTERNAL_ERROR); return 0; } DEBUG("Buffer MetaSize : %d\n", bufferMetaSize); cp_ctx->pSrcBufferList.numBuffers = numBuffers; cp_ctx->pDstBufferList.numBuffers = numBuffers; if (bufferMetaSize) { cp_ctx->pSrcBufferList.pPrivateMetaData = qat_mem_alloc(bufferMetaSize, cp_ctx->qat_svm, __FILE__, __LINE__); cp_ctx->pDstBufferList.pPrivateMetaData = qat_mem_alloc(bufferMetaSize, cp_ctx->qat_svm,__FILE__, __LINE__); if (cp_ctx->pSrcBufferList.pPrivateMetaData == NULL || cp_ctx->pDstBufferList.pPrivateMetaData == NULL) { WARN("QMEM alloc failed for PrivateData\n"); QATerr(QAT_F_QAT_CHACHAPOLY_SETUP_OP_PARAMS, ERR_R_MALLOC_FAILURE); QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->session_ctx, cp_ctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->pSrcBufferList.pPrivateMetaData, cp_ctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->pDstBufferList.pPrivateMetaData, cp_ctx->qat_svm); return 0; } } else { cp_ctx->pSrcBufferList.pPrivateMetaData = NULL; cp_ctx->pDstBufferList.pPrivateMetaData = NULL; } cp_ctx->pDstBufferList.pUserData = NULL; cp_ctx->pSrcBufferList.pUserData = NULL; cp_ctx->pSrcBufferList.pBuffers = &cp_ctx->src_buffer; cp_ctx->pDstBufferList.pBuffers = &cp_ctx->dst_buffer; /* Mark session init as set.*/ cp_ctx->session_init = 1; return 1; } /****************************************************************************** * function: * qat_chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *evp_ctx, unsigned char *out, * const unsigned char *in, size_t len) * * @param evp_ctx [IN] - pointer to existing context * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval 0 failure * @retval 1 success * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * This is the function used in the TLS case. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_chacha20_poly1305_tls_cipher(QAT_PROV_CIPHER_CTX * ctx, unsigned char *out, size_t *padlen, size_t outl, const unsigned char *in, size_t len) #else static int qat_chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { int outlen = 0; int job_ret = 0; int cipher_len = 0; int plen; int enc; CpaStatus status; op_done_t op_done; thread_local_variables_t *tlv = NULL; # ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER sw_chachapoly_cipher; QAT_PROV_CIPHER_CTX *cp_ctx = NULL; # else qat_chachapoly_ctx *cp_ctx = NULL; # endif int fallback = 0; #if !defined(QAT_OPENSSL_PROVIDER) int retVal = 0; # endif if (unlikely(ctx == NULL)) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, QAT_R_CTX_NULL); return -1; } #ifdef QAT_OPENSSL_PROVIDER cp_ctx = ctx; #else cp_ctx = qat_chachapoly_data(ctx); #endif if (cp_ctx == NULL) { WARN("chachapoly context cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, QAT_R_CHACHAPOLY_CTX_NULL); return -1; } plen = cp_ctx->tls_payload_length; if (len != plen + QAT_POLY1305_BLOCK_SIZE) { WARN("Invalid tls payload length\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, QAT_R_INVALID_INPUT_LENGTH); return -1; } #ifdef QAT_OPENSSL_PROVIDER enc = QAT_PROV_GET_ENC(ctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif DEBUG("ctx %p, cp_ctx %p, len %zu plen %d enc: %d\n", ctx, cp_ctx, len, plen, enc); #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD cp_ctx->packet_size = len; # ifdef QAT_OPENSSL_PROVIDER if ((len - QAT_POLY1305_BLOCK_SIZE) <= qat_pkt_threshold_table_get_threshold(ctx->nid)) { DEBUG("Using OpenSSL SW for Packetsize %zu\n", len); fallback = 1; goto cleanup; } # else if ((len - QAT_POLY1305_BLOCK_SIZE) <= qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { DEBUG("Using OpenSSL SW for Packetsize %zu\n", len); fallback = 1; goto cleanup; } # endif #endif /* Set chachapoly opdata params and initialise session. */ if (cp_ctx->context_params_set && !cp_ctx->session_init) { if (!qat_chachapoly_setup_op_params(cp_ctx, &fallback)) { WARN("chachapoly operational params setup failed.\n"); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } goto cleanup; } } else if (!cp_ctx->context_params_set) { WARN("chachapoly operational params setup failed.\n"); if (qat_get_sw_fallback_enabled()) { fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto cleanup; } } /* Actual message length is the input length minus the tag length. */ cipher_len = len - QAT_POLY1305_DIGEST_SIZE; DEBUG("InputLen %zu, CipherLen %d\n", len, cipher_len); /* Allocate buffer for HASH and CIPHER operation. */ if (!cp_ctx->qat_svm) cp_ctx->src_buffer.pData = qaeCryptoMemAlloc(len, __FILE__, __LINE__); else cp_ctx->src_buffer.pData = (Cpa8U *)in; if (cp_ctx->src_buffer.pData == NULL) { WARN("Unable to allocate memory for TLS header\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, ERR_R_MALLOC_FAILURE); goto tls_cipher_err; } if (!cp_ctx->qat_svm) { cp_ctx->dst_buffer.pData = cp_ctx->src_buffer.pData; memcpy(cp_ctx->src_buffer.pData, in, cipher_len); } else { cp_ctx->dst_buffer.pData = (Cpa8U *)out; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, ERR_R_INTERNAL_ERROR); goto tls_cipher_err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto tls_cipher_err; } } cp_ctx->src_buffer.dataLenInBytes = cipher_len; cp_ctx->pSrcBufferList.pUserData = NULL; cp_ctx->dst_buffer.dataLenInBytes = cipher_len; cp_ctx->pDstBufferList.pUserData = NULL; cp_ctx->opd->sessionCtx = cp_ctx->session_ctx; /* Set messageLenToCipherInBytes to the cipher buffer length. */ cp_ctx->opd->messageLenToCipherInBytes = cipher_len; /* Set the offset where the tag need to be written in the destination buffer. */ cp_ctx->opd->hashStartSrcOffsetInBytes = cipher_len; /* Set AAD */ cp_ctx->opd->pAdditionalAuthData = cp_ctx->tls_aad; cp_ctx->opd->pDigestResult = cp_ctx->mac_key; DUMPL("pDigestResult", cp_ctx->opd->pDigestResult, QAT_CHACHA_KEY_SIZE); DUMPL("AAD Buffer", cp_ctx->opd->pAdditionalAuthData, cp_ctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); OPENSSL_cleanse(cp_ctx->opd->pIv, QAT_CHACHA20_POLY1305_MAX_IVLEN); memcpy(cp_ctx->opd->pIv, cp_ctx->derived_iv, QAT_CHACHA20_POLY1305_MAX_IVLEN); DUMP_CP_PERFORM_OP(qat_instance_handles[cp_ctx->inst_num], cp_ctx->opd, cp_ctx->pSrcBufferList, cp_ctx->pDstBufferList); status = qat_sym_perform_op(cp_ctx->inst_num, &op_done, cp_ctx->opd, &(cp_ctx->pSrcBufferList), &(cp_ctx->pDstBufferList), &(cp_ctx->session_data->verifyDigest)); if (status != CPA_STATUS_SUCCESS) { if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm type unsupported in QAT_HW\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto cleanup; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto tls_cipher_err; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_CP_PERFORM_OP_OUTPUT(&(cp_ctx->session_data->verifyDigest), cp_ctx->pDstBufferList); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (enc && CPA_STATUS_SUCCESS == op_done.status) { outlen = len; # ifdef QAT_OPENSSL_PROVIDER *padlen = len; outlen = 1; # endif DEBUG("Encryption succeeded.\n"); } else if (!enc && CPA_TRUE == op_done.verifyResult) { outlen = cipher_len; # ifdef QAT_OPENSSL_PROVIDER *padlen = cipher_len; outlen = 1; # endif DEBUG("Decryption succeeded.\n"); } else { WARN("Verification of result failed\n"); CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qat_cleanup_op_done(&op_done); if (qat_get_sw_fallback_enabled()) { fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto cleanup; } QATerr(QAT_F_QAT_CHACHA20_POLY1305_TLS_CIPHER, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); /* Copy destination buffer into out buffer. */ if (!cp_ctx->qat_svm) memcpy(out, cp_ctx->dst_buffer.pData, cipher_len); memcpy(out + cipher_len, cp_ctx->opd->pDigestResult, QAT_POLY1305_DIGEST_SIZE); cleanup: if (fallback) { # ifdef QAT_OPENSSL_PROVIDER sw_chachapoly_cipher = get_default_cipher_chachapoly(); if (sw_chachapoly_cipher.cupdate == NULL) return -1; outlen = sw_chachapoly_cipher. cupdate(cp_ctx->sw_ctx, out, padlen, outl, in, len); if (!outlen) return -1; # else EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx->sw_ctx_cipher_data); retVal = EVP_CIPHER_meth_get_do_cipher(GET_SW_CHACHA_CTX) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx); if (retVal) outlen = len; # endif } tls_cipher_err: if (cp_ctx->src_buffer.pData && !cp_ctx->qat_svm) { qaeCryptoMemFreeNonZero(cp_ctx->src_buffer.pData); cp_ctx->src_buffer.pData = NULL; cp_ctx->dst_buffer.pData = NULL; } return outlen; } /****************************************************************************** * function: * qat_chacha20_poly1305_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * const unsigned char *in, size_t len) * * @param ctx [IN] - pointer to existing ctx * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval 0 failure * @retval 1 success * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * ******************************************************************************/ # ifdef QAT_OPENSSL_PROVIDER int qat_chacha20_poly1305_do_cipher(QAT_PROV_CIPHER_CTX * ctx, unsigned char *out, size_t *padlen, size_t outl, const unsigned char *in, size_t len) # else static int qat_chacha20_poly1305_do_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t len) # endif { int outlen = 0; int job_ret = 0; int plen; int enc; int fallback = 0; CpaStatus status; op_done_t op_done; thread_local_variables_t *tlv = NULL; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD int nid = 0; # endif # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CIPHER_CTX *cp_ctx = NULL; QAT_EVP_CIPHER sw_chachapoly_cipher; # else qat_chachapoly_ctx *cp_ctx = NULL; # endif if (unlikely(ctx == NULL)) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, QAT_R_CTX_NULL); return -1; } # ifdef QAT_OPENSSL_PROVIDER cp_ctx = ctx; # else cp_ctx = qat_chachapoly_data(ctx); # endif if (cp_ctx == NULL) { WARN("chachapoly context cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, QAT_R_CHACHAPOLY_CTX_NULL); return -1; } plen = cp_ctx->tls_payload_length; # ifdef QAT_OPENSSL_PROVIDER enc = QAT_PROV_GET_ENC(ctx); # else enc = EVP_CIPHER_CTX_encrypting(ctx); # endif # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifdef QAT_OPENSSL_PROVIDER nid = cp_ctx->nid; # else nid = EVP_CIPHER_CTX_nid(ctx); # endif # endif DEBUG("in %p, out %p ctx %p, cp_ctx %p, len %zu, plen %d enc %d\n", in, out, ctx, cp_ctx, len, plen, enc); if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL) { # ifdef QAT_OPENSSL_PROVIDER return qat_chacha20_poly1305_tls_cipher(ctx, out, padlen, outl, in, len); # else return qat_chacha20_poly1305_tls_cipher(ctx, out, in, len); # endif } /* Partial requests are not supported in the QAT driver * for CHACHA-POLY. */ if (out != NULL && in == NULL) { WARN("QAT Engine does not support partial requests.\n"); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD fallback = 1; # endif if (qat_get_sw_fallback_enabled()) { fallback = 1; } if (fallback && !cp_ctx->tag_set) { # ifdef QAT_OPENSSL_PROVIDER sw_chachapoly_cipher = get_default_cipher_chachapoly(); if (sw_chachapoly_cipher.cfinal == NULL) return -1; outlen = sw_chachapoly_cipher.cfinal(cp_ctx->sw_ctx, out, padlen, outl); if (!outlen) return -1; return outlen; # else EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx->sw_ctx_cipher_data); EVP_CIPHER_meth_get_do_cipher(GET_SW_CHACHA_CTX) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx); # endif } # ifdef QAT_OPENSSL_PROVIDER *padlen = len; return 1; # else return 0; # endif } if (in != NULL) { if (out == NULL) { /* Copy "in" buffer data into tls_aad when "out" buffer is NULL * as done in the software implementation. */ if (cp_ctx->context_params_set == 1) { if (cp_ctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes != len) { if (cp_ctx->tls_aad == NULL) cp_ctx->tls_aad = qaeCryptoMemAlloc(len, __FILE__, __LINE__); if (NULL == cp_ctx->tls_aad) { WARN("Unable to allocate memory for TLS header\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_MALLOC_FAILURE); return -1; } cp_ctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = len; } memcpy(cp_ctx->tls_aad, in, len); DUMPL("AAD", cp_ctx->tls_aad, len); } # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD DEBUG("Using OpenSSL SW for Packetsize %zu\n", len); fallback = 1; # endif if (qat_get_sw_fallback_enabled()) fallback = 1; # ifdef QAT_OPENSSL_PROVIDER *padlen = len; # endif outlen = 1; goto cleanup; } else { /* EncryptUpdate/DecryptUpdate case */ # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD cp_ctx->packet_size = len; if (len <= qat_pkt_threshold_table_get_threshold(nid)) { fallback = 1; # ifdef QAT_OPENSSL_PROVIDER *padlen = len; # endif DEBUG("Using OpenSSL SW for Packetsize %zu\n", len); goto cleanup; } # endif if (cp_ctx->context_params_set && !cp_ctx->session_init) { /* Set chachapoly opdata params and initialise session. */ if (!qat_chachapoly_setup_op_params(cp_ctx, &fallback)) { WARN("chachapoly operational params setup failed.\n"); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto cleanup; } QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_INTERNAL_ERROR); goto do_cipher_err; } } else if (!cp_ctx->context_params_set) { WARN("chachapoly operational params setup failed.\n"); if (qat_get_sw_fallback_enabled()) { fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto cleanup; } } /* Allocate buffer for HASH and Cipher operation. */ if (!cp_ctx->qat_svm) { cp_ctx->src_buffer.pData = qaeCryptoMemAlloc(len, __FILE__, __LINE__); } else { cp_ctx->src_buffer.pData = (Cpa8U *)in; cp_ctx->dst_buffer.pData = (Cpa8U *)out; } if (cp_ctx->src_buffer.pData == NULL) { WARN("Unable to allocate memory for src buffer\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_MALLOC_FAILURE); goto do_cipher_err; } if (!cp_ctx->qat_svm) { /* In-Place operation */ cp_ctx->dst_buffer.pData = cp_ctx->src_buffer.pData; /* Copy message into source buffer. */ memcpy(cp_ctx->src_buffer.pData, in, len); } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_INTERNAL_ERROR); goto do_cipher_err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto do_cipher_err; } } cp_ctx->src_buffer.dataLenInBytes = len; cp_ctx->pSrcBufferList.pUserData = NULL; cp_ctx->dst_buffer.dataLenInBytes = len; cp_ctx->pDstBufferList.pUserData = NULL; cp_ctx->opd->sessionCtx = cp_ctx->session_ctx; /* Set messageLenToCipherInBytes to the cipher buffer length. */ cp_ctx->opd->messageLenToCipherInBytes = len; /* Set the offset from where the tag needs to be written. */ cp_ctx->opd->hashStartSrcOffsetInBytes = len; /* Set AAD. */ cp_ctx->opd->pAdditionalAuthData = cp_ctx->tls_aad; /* Add Mackey into Digest */ cp_ctx->opd->pDigestResult = cp_ctx->mac_key; DUMPL("pDigestResult", cp_ctx->opd->pDigestResult, QAT_CHACHA_KEY_SIZE); DUMPL("AAD", cp_ctx->opd->pAdditionalAuthData, cp_ctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); DUMP_CP_PERFORM_OP(qat_instance_handles[cp_ctx->inst_num], cp_ctx->opd, cp_ctx->pSrcBufferList, cp_ctx->pDstBufferList); status = qat_sym_perform_op(cp_ctx->inst_num, &op_done, cp_ctx->opd, &(cp_ctx->pSrcBufferList), &(cp_ctx->pDstBufferList), &(cp_ctx->session_data->verifyDigest)); if (status != CPA_STATUS_SUCCESS) { if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm type unsupported in QAT_HW\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto cleanup; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto do_cipher_err; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_CP_PERFORM_OP_OUTPUT(&(cp_ctx->session_data->verifyDigest), cp_ctx->pDstBufferList); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (enc) { if (CPA_STATUS_SUCCESS != op_done.status) { if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG( "Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; /* Probably already set anyway */ WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } DEBUG("Encryption failed\n"); qat_cleanup_op_done(&op_done); goto cleanup; } DEBUG("Encryption succeeded\n"); /* Set tag after the encryption operation. */ #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, QAT_POLY1305_DIGEST_SIZE, cp_ctx->opd->pDigestResult); #else qat_chacha20_poly1305_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, QAT_POLY1305_DIGEST_SIZE, cp_ctx->opd->pDigestResult); *padlen = len; #endif DUMPL("Tag",cp_ctx->tag, QAT_POLY1305_DIGEST_SIZE); cp_ctx->tag_len = QAT_POLY1305_DIGEST_SIZE; cp_ctx->tag_set = 1; } else { if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - %s\n", cp_ctx->inst_num, qat_instance_details[cp_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qat_cleanup_op_done(&op_done); if (qat_get_sw_fallback_enabled()) { fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto cleanup; } QATerr(QAT_F_QAT_CHACHA20_POLY1305_DO_CIPHER, ERR_R_INTERNAL_ERROR); } else { DEBUG("Decryption succeeded\n"); #ifdef QAT_OPENSSL_PROVIDER *padlen = len; #endif } } outlen = len; qat_cleanup_op_done(&op_done); /* Copy destination buffer into "out" buffer. */ if (!cp_ctx->qat_svm) memcpy(out, cp_ctx->dst_buffer.pData, len); } } /* DecryptFinal case need not be handled explicitly here. * Software Implementation compare received tag and * calculated tag here. */ cleanup: if (fallback) { # ifdef QAT_OPENSSL_PROVIDER sw_chachapoly_cipher = get_default_cipher_chachapoly(); if (sw_chachapoly_cipher.cupdate == NULL) return -1; outlen = sw_chachapoly_cipher. cupdate(cp_ctx->sw_ctx, out, padlen, outl, in, len); if (!outlen) return -1; # else EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx->sw_ctx_cipher_data); outlen = EVP_CIPHER_meth_get_do_cipher(GET_SW_CHACHA_CTX) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx); if (outlen) outlen = len; # endif } do_cipher_err: if (cp_ctx->src_buffer.pData && !cp_ctx->qat_svm) { qaeCryptoMemFreeNonZero(cp_ctx->src_buffer.pData); cp_ctx->src_buffer.pData = NULL; cp_ctx->dst_buffer.pData = NULL; } return outlen; } /****************************************************************************** * function: * qat_chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to existing ctx * * @retval 1 success * @retval 0 failure * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chacha20_poly1305_cleanup(QAT_PROV_CIPHER_CTX *ctx) #else static int qat_chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx) #endif { int ret = 1; # ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CIPHER_CTX *cp_ctx = NULL; # else qat_chachapoly_ctx *cp_ctx = NULL; # endif CpaStatus status; CpaCySymSessionSetupData *ssd = NULL; CpaBoolean sessionInUse = CPA_FALSE; if (unlikely(ctx == NULL)) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CLEANUP, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER cp_ctx = ctx; #else cp_ctx = qat_chachapoly_data(ctx); #endif if (cp_ctx == NULL) { WARN("chachapoly context cipher data is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CLEANUP, QAT_R_CHACHAPOLY_CTX_NULL); return 0; } if (cp_ctx->session_ctx != NULL) { /* Wait for in-flight requests before removing session */ do { cpaCySymSessionInUse(cp_ctx->session_ctx, &sessionInUse); } while (sessionInUse); } ssd = cp_ctx->session_data; DEBUG("ctx %p, cp_ctx %p, SSD %p\n", ctx, cp_ctx, cp_ctx->session_data); if (ssd) { if (cp_ctx->session_init && is_instance_available(cp_ctx->inst_num)) { status = cpaCySymRemoveSession(qat_instance_handles[cp_ctx->inst_num], cp_ctx->session_ctx); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, status = %d\n", status); ret = 0; } QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->session_ctx, cp_ctx->qat_svm); cp_ctx->session_ctx = NULL; } OPENSSL_free(ssd); ssd = NULL; } /* Cleanup the memory */ QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->pSrcBufferList.pPrivateMetaData, cp_ctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->pDstBufferList.pPrivateMetaData, cp_ctx->qat_svm); if (cp_ctx->tls_aad) { if (!cp_ctx->qat_svm) qaeCryptoMemFreeNonZero(cp_ctx->tls_aad); cp_ctx->tls_aad = NULL; } if (cp_ctx->opd) { QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->opd->pIv, cp_ctx->qat_svm); OPENSSL_clear_free(cp_ctx->opd, sizeof(template_opData)); cp_ctx->opd = NULL; } QAT_MEM_FREE_NONZERO_BUFF(cp_ctx->mac_key, cp_ctx->qat_svm); cp_ctx->context_params_set = 0; cp_ctx->session_init = 0; cp_ctx->packet_size = 0; # ifdef QAT_OPENSSL_PROVIDER if (cp_ctx->sw_ctx) { OPENSSL_free(cp_ctx->sw_ctx); cp_ctx->sw_ctx = NULL; } # else if (cp_ctx->sw_ctx_cipher_data) { OPENSSL_free(cp_ctx->sw_ctx_cipher_data); cp_ctx->sw_ctx_cipher_data = NULL; } #endif return ret; } /****************************************************************************** * function: * qat_chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) * * @param ctx [IN] - pointer to existing ctx * @param type [IN] - type of request * @param arg [IN] - size of the pointed to by ptr * @param ptr [IN] - input buffer contain the necessary parameters * * @retval x The return value is dependent on the type of request being made. * @retval 0, -1 failure * * description: * This function is a generic control interface provided by the EVP API. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chacha20_poly1305_ctrl(QAT_PROV_CIPHER_CTX *ctx, int type, int arg, void *ptr) #else static int qat_chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) #endif { int enc; EVP_CIPHER_CTX *dst_ctx = NULL; void *tmp_ctx = NULL; int ret = 0; #ifndef QAT_OPENSSL_PROVIDER # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD int nid = 0; # endif int ret_sw = 0; int fallback = 0; #endif if (unlikely(ctx == NULL)) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CIPHER_CTX *cp_ctx = ctx; enc = QAT_PROV_GET_ENC(ctx); #else qat_chachapoly_ctx *cp_ctx = qat_chachapoly_data(ctx); enc = EVP_CIPHER_CTX_encrypting(ctx); # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD nid = EVP_CIPHER_CTX_nid(ctx); # endif #endif switch (type) { case EVP_CTRL_INIT: DEBUG("EVP_CTRL_INIT, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (cp_ctx == NULL) { cp_ctx = OPENSSL_zalloc(sizeof(qat_chachapoly_ctx)); if (cp_ctx == NULL) { WARN("unable to allocate memory for chachapoly ctx.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, ERR_R_MALLOC_FAILURE); return -1; } } DEBUG("ctx %p cp_ctx %p\n", ctx, cp_ctx); cp_ctx->tag_len = 0; cp_ctx->nonce_len = QAT_CHACHA20_POLY1305_MAX_IVLEN; cp_ctx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; cp_ctx->tls_aad = NULL; cp_ctx->tls_aad_len = 0; cp_ctx->key_set = 0; cp_ctx->iv_set = 0; cp_ctx->mac_key_set = 0; cp_ctx->mac_key = NULL; cp_ctx->tag_set = 0; #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx); #endif ret = 1; goto sw_ctrl; case EVP_CTRL_COPY: DEBUG("EVP_CTRL_COPY, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); dst_ctx = (EVP_CIPHER_CTX *)ptr; tmp_ctx = OPENSSL_memdup(cp_ctx, sizeof(qat_chachapoly_ctx)); if (tmp_ctx == NULL) { WARN("unable to copy chachapoly cipher context data.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, ERR_R_MALLOC_FAILURE); return -1; } EVP_CIPHER_CTX_set_cipher_data(dst_ctx, tmp_ctx); return 1; case EVP_CTRL_GET_IVLEN: DEBUG("EVP_CTRL_GET_IVLEN, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); *(int *)ptr = cp_ctx->nonce_len; ret = 1; goto sw_ctrl; case EVP_CTRL_AEAD_SET_IVLEN: DEBUG("EVP_CTRL_AEAD_SET_IVLEN, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg <= 0 || arg > QAT_CHACHA20_POLY1305_MAX_IVLEN) { WARN("Invalid IV length.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_INVALID_IVLEN); return 0; } cp_ctx->nonce_len = arg; ret = 1; goto sw_ctrl; case EVP_CTRL_AEAD_SET_IV_FIXED: DEBUG("EVP_CTRL_SET_IV_FIXED, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg != QAT_CHACHA20_POLY1305_MAX_IVLEN) { WARN("Invalid fixed IV length.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_INVALID_IVLEN); return 0; } cp_ctx->iv[0] = CHACHA_U8TOU32((unsigned char *)ptr); cp_ctx->iv[1] = CHACHA_U8TOU32((unsigned char *)ptr+4); cp_ctx->iv[2] = CHACHA_U8TOU32((unsigned char *)ptr+8); ret = 1; goto sw_ctrl; case EVP_CTRL_AEAD_SET_TAG: DEBUG("EVP_CTRL_AEAD_SET_TAG, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg <= 0 || arg > QAT_POLY1305_BLOCK_SIZE) { WARN("Invalid TAG length.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_INVALID_TAG_LEN); return 0; } if (ptr != NULL) { memcpy(cp_ctx->tag, ptr, arg); cp_ctx->tag_len = arg; cp_ctx->tag_set = 1; } ret = 1; goto sw_ctrl; case EVP_CTRL_AEAD_GET_TAG: DEBUG("EVP_CTRL_AEAD_GET_TAG, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg <= 0 || arg > QAT_POLY1305_BLOCK_SIZE || !enc) { WARN("Invalid TAG operation.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_INVALID_TAG_LEN); return 0; } memcpy(ptr, cp_ctx->tag, arg); if (cp_ctx->tag_set == 1) { cp_ctx->tag_set = 0; return 1; } cp_ctx->tag_set = 0; ret = 1; goto sw_ctrl; case EVP_CTRL_AEAD_TLS1_AAD: DEBUG("EVP_CTRL_AEAD_TLS1_AAD, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void *)ctx, type, arg, ptr); if (arg != EVP_AEAD_TLS1_AAD_LEN) { WARN("Invalid AAD length.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_AAD_LEN_INVALID); return 0; } unsigned int len; unsigned char *aad = ptr; if (cp_ctx->tls_aad_len <= 0) { cp_ctx->tls_aad = qaeCryptoMemAlloc(arg, __FILE__, __LINE__); if (cp_ctx->tls_aad == NULL) { WARN("Unable to allocate memory for TLS header\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, ERR_R_MALLOC_FAILURE); return 0; } cp_ctx->tls_aad_len = arg; } memcpy(cp_ctx->tls_aad, ptr, EVP_AEAD_TLS1_AAD_LEN); /* Get the length of the TLS payload */ len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 | aad[EVP_AEAD_TLS1_AAD_LEN - 1]; aad = cp_ctx->tls_aad; if (!enc) { if (len < QAT_POLY1305_BLOCK_SIZE) { WARN("Invalid TAG length or no TAG.\n"); QATerr(QAT_F_QAT_CHACHA20_POLY1305_CTRL, QAT_R_INVALID_ATTACHED_TAG); return 0; } /* Discount attached tag */ len -= QAT_POLY1305_BLOCK_SIZE; /* Adjust the length of the payload */ aad[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8); aad[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len; } if (cp_ctx->session_data != NULL) cp_ctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = EVP_AEAD_TLS1_AAD_LEN; cp_ctx->tls_payload_length = len; /* merge record sequence number as per RFC7905 */ cp_ctx->counter[1] = cp_ctx->iv[0]; cp_ctx->counter[2] = cp_ctx->iv[1] ^ CHACHA_U8TOU32(aad); cp_ctx->counter[3] = cp_ctx->iv[2] ^ CHACHA_U8TOU32(aad+4); memset(cp_ctx->derived_iv, 0, QAT_CHACHA20_POLY1305_MAX_IVLEN); memcpy(cp_ctx->derived_iv, cp_ctx->nonce, 4); U32TOU8(cp_ctx->derived_iv + 4, cp_ctx->counter[2]); U32TOU8(cp_ctx->derived_iv + 8, cp_ctx->counter[3]); cp_ctx->mac_key_set = 0; ret = QAT_POLY1305_BLOCK_SIZE; goto sw_ctrl; default: WARN("Unknown type parameter\n"); return -1; } sw_ctrl: #ifndef QAT_OPENSSL_PROVIDER # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (type == EVP_CTRL_INIT || cp_ctx->packet_size <= qat_pkt_threshold_table_get_threshold(nid)) fallback = 1; # endif if (qat_get_sw_fallback_enabled()) fallback = 1; if (fallback) { if (type == EVP_CTRL_INIT && cp_ctx->sw_ctx_cipher_data == NULL) { cp_ctx->sw_ctx_cipher_data = OPENSSL_zalloc(QAT_CP_SW_CTX_MEM_SIZE); if (cp_ctx->sw_ctx_cipher_data == NULL) { WARN("Unable to allocate memory for sw_ctx_cipher_data\n"); return -1; } } EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx->sw_ctx_cipher_data); ret_sw = EVP_CIPHER_meth_get_ctrl(GET_SW_CHACHA_CTX)(ctx, type, arg, ptr); EVP_CIPHER_CTX_set_cipher_data(ctx, cp_ctx); if (ret_sw < 0) { WARN("SW aes-chachapoly ctrl function failed.\n"); return -1; } return ret_sw; } # endif return ret; } #endif qatengine-1.9.0/qat_hw_chachapoly.h000066400000000000000000000121241500416242000173150ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_chachapoly.h * * This file provides an interface for CHACHAPOLY operations * *****************************************************************************/ #ifndef QAT_HW_CHACHAPOLY_H # define QAT_HW_CHACHAPOLY_H #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_sym.h" # define QAT_POLY1305_DIGEST_SIZE 16 # define QAT_POLY1305_BLOCK_SIZE 16 # define QAT_CHACHA20_POLY1305_MAX_IVLEN 12 # define QAT_CHACHA_KEY_SIZE 32 # define QAT_CHACHA_BLK_SIZE 64 # define QAT_CHACHA_CTR_SIZE 16 # define QAT_CP_SW_CTX_MEM_SIZE 456 typedef struct qat_chachapoly_ctx_t { void *sw_ctx_cipher_data; int inst_num; int context_params_set; int session_init; CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx session_ctx; CpaCySymOpData *opd; CpaBufferList pSrcBufferList; CpaBufferList pDstBufferList; CpaFlatBuffer src_buffer; CpaFlatBuffer dst_buffer; unsigned char tag[QAT_POLY1305_BLOCK_SIZE]; unsigned char *tls_aad; unsigned char cipher_key[QAT_CHACHA_KEY_SIZE]; unsigned char *mac_key; unsigned char nonce[QAT_CHACHA20_POLY1305_MAX_IVLEN]; unsigned char derived_iv[QAT_CHACHA20_POLY1305_MAX_IVLEN]; unsigned int counter[QAT_CHACHA_CTR_SIZE/4]; unsigned int iv[3]; unsigned int chacha_key[QAT_CHACHA_KEY_SIZE/4]; int key_set; int iv_set; int mac_key_set; int tag_len; int nonce_len; int tls_aad_len; size_t tls_payload_length; int packet_size; int qat_svm; int tag_set; }qat_chachapoly_ctx; /* Standalone utility structure for chacha core operation. */ typedef union { unsigned int u[QAT_CHACHA_CTR_SIZE]; unsigned char c[QAT_CHACHA_BLK_SIZE]; }chacha_buf; const EVP_CIPHER *chachapoly_cipher_meth(int nid, int keylen); # define qat_chachapoly_data(ctx) \ ((qat_chachapoly_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx)) # define NO_TLS_PAYLOAD_LENGTH ((size_t)-1) # define CHACHA_U8TOU32(p) ( \ ((unsigned int)(p)[0]) | ((unsigned int)(p)[1]<<8) | \ ((unsigned int)(p)[2]<<16) | ((unsigned int)(p)[3]<<24) ) #define U8C(v) (v##U) #define U8V(v) ((unsigned char)(v) & U8C(0xFF)) #define U32TOU8(p, v) \ do { \ (p)[0] = U8V((v) ); \ (p)[1] = U8V((v) >> 8); \ (p)[2] = U8V((v) >> 16); \ (p)[3] = U8V((v) >> 24); \ } while (0) # define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n)))) # define U32TO8_LITTLE(p, v) do { \ (p)[0] = (u8)(v >> 0); \ (p)[1] = (u8)(v >> 8); \ (p)[2] = (u8)(v >> 16); \ (p)[3] = (u8)(v >> 24); \ } while(0) # define U8TO32_LITTLE(p) \ (((uint32_t)((p)[0]) << 0) | \ ((uint32_t)((p)[1]) << 8) | \ ((uint32_t)((p)[2]) << 16) | \ ((uint32_t)((p)[3]) << 24)) /* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */ # define QUARTERROUND(a,b,c,d) ( \ x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]),16), \ x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]),12), \ x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]), 8), \ x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]), 7) ) #endif qatengine-1.9.0/qat_hw_ciphers.c000066400000000000000000002075441500416242000166460ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /* * This file contains modified code from OpenSSL/BoringSSL used * in order to run certain operations in constant time. * It is subject to the following license: */ /* * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ /***************************************************************************** * @file qat_hw_ciphers.c * * This file contains the engine implementations for cipher operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include "qat_utils.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_evp.h" #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_sym.h" #include "qat_hw_ciphers.h" #include "qat_constant_time.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #include #include #include #include #include #include #include #include #ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; #endif #define GET_TLS_HDR(qctx, i) ((qctx)->aad[(i)]) #define GET_TLS_VERSION(hdr) (((hdr)[9]) << QAT_BYTE_SHIFT | (hdr)[10]) #define GET_TLS_PAYLOAD_LEN(hdr) (((((hdr)[11]) << QAT_BYTE_SHIFT) & 0xff00) | \ ((hdr)[12] & 0x00ff)) #define SET_TLS_PAYLOAD_LEN(hdr, len) \ do { \ hdr[11] = (len & 0xff00) >> QAT_BYTE_SHIFT; \ hdr[12] = len & 0xff; \ } while(0) # define GET_SW_CIPHER(ctx) \ qat_chained_cipher_sw_impl(EVP_CIPHER_CTX_nid((ctx))) #define GET_SW_NON_CHAINED_CIPHER(ctx) \ get_cipher_from_nid(EVP_CIPHER_CTX_nid((ctx))) #define DEBUG_PPL DEBUG int qatPerformOpRetries = 0; /* Setup template for Session Setup Data as most of the fields * are constant. The constant values of some of the fields are * chosen for Encryption operation. */ static const CpaCySymSessionSetupData template_ssd = { .sessionPriority = CPA_CY_PRIORITY_HIGH, .symOperation = CPA_CY_SYM_OP_ALGORITHM_CHAINING, .cipherSetupData = { .cipherAlgorithm = CPA_CY_SYM_CIPHER_AES_CBC, .cipherKeyLenInBytes = 0, .pCipherKey = NULL, .cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT, }, .hashSetupData = { .hashAlgorithm = CPA_CY_SYM_HASH_SHA1, .hashMode = CPA_CY_SYM_HASH_MODE_AUTH, .digestResultLenInBytes = 0, .authModeSetupData = { .authKey = NULL, .authKeyLenInBytes = HMAC_KEY_SIZE, .aadLenInBytes = 0, }, .nestedModeSetupData = {0}, }, .algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER, .digestIsAppended = CPA_TRUE, .verifyDigest = CPA_FALSE, .partialsNotRequired = CPA_TRUE, }; static const CpaCySymOpData template_opData = { .sessionCtx = NULL, .packetType = CPA_CY_SYM_PACKET_TYPE_FULL, .pIv = NULL, .ivLenInBytes = 0, .cryptoStartSrcOffsetInBytes = QAT_BYTE_ALIGNMENT, .messageLenToCipherInBytes = 0, .hashStartSrcOffsetInBytes = QAT_BYTE_ALIGNMENT - TLS_VIRT_HDR_SIZE, .messageLenToHashInBytes = 0, .pDigestResult = NULL, .pAdditionalAuthData = NULL }; static inline int get_digest_len(int nid) { return (((nid) == NID_aes_128_cbc_hmac_sha1 || (nid) == NID_aes_256_cbc_hmac_sha1) ? SHA_DIGEST_LENGTH : SHA256_DIGEST_LENGTH); } static inline const EVP_CIPHER *qat_chained_cipher_sw_impl(int nid) { switch (nid) { case NID_aes_128_cbc_hmac_sha1: return EVP_aes_128_cbc_hmac_sha1(); case NID_aes_256_cbc_hmac_sha1: return EVP_aes_256_cbc_hmac_sha1(); case NID_aes_128_cbc_hmac_sha256: return EVP_aes_128_cbc_hmac_sha256(); case NID_aes_256_cbc_hmac_sha256: return EVP_aes_256_cbc_hmac_sha256(); default: WARN("Invalid nid %d\n", nid); return NULL; } } static inline const EVP_CIPHER *get_cipher_from_nid(int nid) { switch (nid) { case NID_aes_128_cbc_hmac_sha1: case NID_aes_128_cbc_hmac_sha256: return EVP_aes_128_cbc(); case NID_aes_256_cbc_hmac_sha1: case NID_aes_256_cbc_hmac_sha256: return EVP_aes_256_cbc(); default: WARN("Invalid nid %d\n", nid); return NULL; } } static inline void qat_chained_ciphers_free_qop(qat_op_params **pqop, unsigned int *num_elem, int qat_svm) { unsigned int i = 0; qat_op_params *qop = NULL; if (pqop != NULL && ((qop = *pqop) != NULL)) { for (i = 0; i < *num_elem; i++) { if (!qat_svm) qaeCryptoMemFreeNonZero(qop[i].src_fbuf[1].pData); QAT_MEM_FREE_FLATBUFF(qop[i].src_fbuf[0], qat_svm); QAT_MEM_FREE_BUFF(qop[i].src_sgl.pPrivateMetaData, qat_svm); QAT_MEM_FREE_BUFF(qop[i].dst_sgl.pPrivateMetaData, qat_svm); QAT_MEM_FREE_BUFF(qop[i].op_data.pIv, qat_svm); } OPENSSL_free(qop); *pqop = NULL; *num_elem = 0; } } const EVP_CIPHER *qat_create_cipher_meth(int nid, int keylen) { EVP_CIPHER *c = NULL; #ifndef QAT_OPENSSL_PROVIDER int res = 1; #endif if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_AES_CBC_HMAC_SHA)) { if ((c = EVP_CIPHER_meth_new(nid, AES_BLOCK_SIZE, keylen)) == NULL) { WARN("Failed to allocate cipher methods for nid %d\n", nid); return NULL; } #ifndef QAT_OPENSSL_PROVIDER res &= EVP_CIPHER_meth_set_iv_length(c, AES_IV_LEN); res &= EVP_CIPHER_meth_set_flags(c, QAT_CHAINED_FLAG); res &= EVP_CIPHER_meth_set_init(c, qat_chained_ciphers_init); res &= EVP_CIPHER_meth_set_do_cipher(c, qat_chained_ciphers_do_cipher); res &= EVP_CIPHER_meth_set_cleanup(c, qat_chained_ciphers_cleanup); res &= EVP_CIPHER_meth_set_impl_ctx_size(c, sizeof(qat_chained_ctx)); res &= EVP_CIPHER_meth_set_set_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv); res &= EVP_CIPHER_meth_set_get_asn1_params(c, EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv); res &= EVP_CIPHER_meth_set_ctrl(c, qat_chained_ciphers_ctrl); if (res == 0) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_CIPHER_meth_free(c); c = NULL; } qat_hw_aes_cbc_hmac_sha_offload = 1; DEBUG("QAT HW AES_CBC_%d_HMAC_SHA registration succeeded\n", keylen*8); #endif return c; } else { qat_hw_aes_cbc_hmac_sha_offload = 0; DEBUG("QAT HW AES_CBC_%d_HMAC_SHA is disabled, using OpenSSL SW\n", keylen*8); EVP_CIPHER_meth_free(c); return qat_chained_cipher_sw_impl(nid); } } /****************************************************************************** * function: * qat_chained_callbackFn(void *callbackTag, CpaStatus status, * const CpaCySymOp operationType, void *pOpData, * CpaBufferList * pDstBuffer, CpaBoolean verifyResult) * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. Cast to op_done_pipe_t. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: * Callback function used by chained ciphers with pipeline support. This * function is called when operation is completed for each pipeline. However * the paused job is woken up when all the pipelines have been processed. * ******************************************************************************/ static void qat_chained_callbackFn(void *callbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList *pDstBuffer, CpaBoolean verifyResult) { ASYNC_JOB *job = NULL; op_done_pipe_t *opdone = (op_done_pipe_t *)callbackTag; CpaBoolean res = CPA_FALSE; if (opdone == NULL) { WARN("Callback Tag NULL\n"); return; } opdone->num_processed++; res = (status == CPA_STATUS_SUCCESS) && verifyResult ? CPA_TRUE : CPA_FALSE; /* If any single pipe processing failed, the entire operation * is treated as failure. The default value of opDone.verifyResult * is TRUE. Change it to false on Failure. */ if (res == CPA_FALSE) { WARN("Pipe %u failed (status %d, verifyResult %d)\n", opdone->num_processed, status, verifyResult); opdone->opDone.verifyResult = CPA_FALSE; } /* The QAT API guarantees submission order for request * i.e. first in first out. If not all requests have been * submitted or processed, wait for more callbacks. */ if ((opdone->num_submitted != opdone->num_pipes) || (opdone->num_submitted != opdone->num_processed)) return; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); } /* Cache job pointer to avoid a race condition if opdone gets cleaned up * in the calling thread. */ job = (ASYNC_JOB *)opdone->opDone.job; /* Mark job as done when all the requests have been submitted and * subsequently processed. */ opdone->opDone.flag = 1; if (job) { qat_wake_job(job, ASYNC_STATUS_OK); } } /****************************************************************************** * function: * qat_setup_op_params(EVP_CIPHER_CTX *ctx) * * @param qctx [IN] - pointer to existing qat_chained_ctx * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the flatbuffer and flat buffer list for use. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_setup_op_params(PROV_CIPHER_CTX *ctx) #else static int qat_setup_op_params(EVP_CIPHER_CTX *ctx) #endif { CpaCySymOpData *opd = NULL; Cpa32U msize = 0; #ifdef QAT_OPENSSL_PROVIDER qat_chained_ctx *qctx = (qat_chained_ctx *)ctx->qat_cipher_ctx; #else qat_chained_ctx *qctx = qat_chained_data(ctx); #endif int i = 0; unsigned int start; /* When no pipelines are used, numpipes = 1. The actual number of pipes are * not known until the start of do_cipher. */ if (PIPELINE_USED(qctx)) { /* When Pipes have been previously used, the memory has been allocated * for max supported pipes although initialised only for numpipes. */ start = qctx->npipes_last_used; } else { start = 1; /* When the context switches from using no pipes to using pipes, * free the previous allocated memory. */ if (qctx->qop != NULL && qctx->qop_len < qctx->numpipes) { qat_chained_ciphers_free_qop(&qctx->qop, &qctx->qop_len, qctx->qat_svm); DEBUG_PPL("[%p] qop memory freed\n", ctx); } } /* Allocate memory for qop depending on whether pipes are used or not. * In case of pipes, allocate for the maximum supported pipes. */ if (qctx->qop == NULL) { if (PIPELINE_USED(qctx)) { WARN("Pipeline used but no data allocated. Possible memory leak\n"); } qctx->qop_len = qctx->numpipes > 1 ? QAT_MAX_PIPELINES : 1; qctx->qop = (qat_op_params *) OPENSSL_zalloc(sizeof(qat_op_params) * qctx->qop_len); if (qctx->qop == NULL) { WARN("Unable to allocate memory[%lu bytes] for qat op params\n", sizeof(qat_op_params) * qctx->qop_len); return 0; } /* start from 0 as New array of qat_op_params */ start = 0; } for (i = start; i < qctx->numpipes; i++) { /* This is a whole block the size of the memory alignment. If the * alignment was to become smaller than the header size * (TLS_VIRT_HEADER_SIZE) which is unlikely then we would need to add * some more logic here to work out how many blocks of size * QAT_BYTE_ALIGNMENT we need to allocate to fit the header in. */ if (!qctx->qat_svm) FLATBUFF_ALLOC_AND_CHAIN(qctx->qop[i].src_fbuf[0], qctx->qop[i].dst_fbuf[0], QAT_BYTE_ALIGNMENT); else FLATBUFF_ALLOC_AND_CHAIN_SVM(qctx->qop[i].src_fbuf[0], qctx->qop[i].dst_fbuf[0], QAT_BYTE_ALIGNMENT); if (qctx->qop[i].src_fbuf[0].pData == NULL) { WARN("Unable to allocate memory for TLS header\n"); goto err; } memset(qctx->qop[i].src_fbuf[0].pData, 0, QAT_BYTE_ALIGNMENT); qctx->qop[i].src_fbuf[1].pData = NULL; qctx->qop[i].dst_fbuf[1].pData = NULL; qctx->qop[i].src_sgl.numBuffers = 2; qctx->qop[i].src_sgl.pBuffers = qctx->qop[i].src_fbuf; qctx->qop[i].src_sgl.pUserData = NULL; qctx->qop[i].src_sgl.pPrivateMetaData = NULL; qctx->qop[i].dst_sgl.numBuffers = 2; qctx->qop[i].dst_sgl.pBuffers = qctx->qop[i].dst_fbuf; qctx->qop[i].dst_sgl.pUserData = NULL; qctx->qop[i].dst_sgl.pPrivateMetaData = NULL; DEBUG("Pipe [%d] inst_num = %d\n", i, qctx->inst_num); DEBUG("Pipe [%d] No of buffers = %d\n", i, qctx->qop[i].src_sgl.numBuffers); /* setup meta data for buffer lists */ if (msize == 0 && cpaCyBufferListGetMetaSize(qat_instance_handles[qctx->inst_num], qctx->qop[i].src_sgl.numBuffers, &msize) != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetBufferSize failed.\n"); goto err; } DEBUG("Pipe [%d] Size of meta data = %d\n", i, msize); if (msize) { qctx->qop[i].src_sgl.pPrivateMetaData = qat_mem_alloc(msize, qctx->qat_svm, __FILE__, __LINE__); qctx->qop[i].dst_sgl.pPrivateMetaData = qat_mem_alloc(msize, qctx->qat_svm, __FILE__, __LINE__); if (qctx->qop[i].src_sgl.pPrivateMetaData == NULL || qctx->qop[i].dst_sgl.pPrivateMetaData == NULL) { WARN("QMEM alloc failed for PrivateData\n"); goto err; } } opd = &qctx->qop[i].op_data; /* Copy the opData template */ memcpy(opd, &template_opData, sizeof(template_opData)); /* Update Opdata */ opd->sessionCtx = qctx->session_ctx; #ifdef QAT_OPENSSL_PROVIDER opd->pIv = qat_mem_alloc(ctx->ivlen, qctx->qat_svm, __FILE__, __LINE__); #else opd->pIv = qat_mem_alloc(EVP_CIPHER_CTX_iv_length(ctx), qctx->qat_svm, __FILE__, __LINE__); #endif if (opd->pIv == NULL) { WARN("QMEM Mem Alloc failed for pIv for pipe %d.\n", i); goto err; } #ifdef QAT_OPENSSL_PROVIDER opd->ivLenInBytes = (Cpa32U) ctx->ivlen; #else opd->ivLenInBytes = (Cpa32U) EVP_CIPHER_CTX_iv_length(ctx); #endif } DEBUG_PPL("[%p] qop setup for %u elements\n", ctx, qctx->qop_len); return 1; err: qat_chained_ciphers_free_qop(&qctx->qop, &qctx->qop_len, qctx->qat_svm); return 0; } /****************************************************************************** * function: * qat_chained_ciphers_init(EVP_CIPHER_CTX *ctx, * const unsigned char *inkey, * const unsigned char *iv, * int enc) * * @param ctx [IN] - pointer to existing ctx * @param inKey [IN] - input cipher key * @param iv [IN] - initialisation vector * @param enc [IN] - 1 encrypt 0 decrypt * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the cipher and hash algorithm parameters for this * EVP context. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chained_ciphers_init(PROV_CIPHER_CTX *ctx, const unsigned char *inkey, size_t keylen, const unsigned char *iv, size_t ivlen, int enc) #else int qat_chained_ciphers_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc) #endif { CpaCySymSessionSetupData *ssd = NULL; Cpa32U sctx_size = 0; CpaCySymSessionCtx sctx = NULL; CpaStatus sts = 0; qat_chained_ctx *qctx = NULL; unsigned char *ckey = NULL; int ckeylen; int dlen; int ret = 0; int fallback = 0; #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER *sw_cipher = NULL; unsigned int sw_size = 0; #else EVP_CIPHER_CTX *sw_ctx = NULL; PROV_EVP_CIPHER sw_aes_cbc_cipher; #endif if (ctx == NULL || inkey == NULL) { WARN("ctx or inkey is NULL.\n"); return 0; } #ifdef QAT_OPENSSL_PROVIDER qctx = (qat_chained_ctx *)ctx->qat_cipher_ctx; #else qctx = qat_chained_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL.\n"); return 0; } DEBUG("QAT HW Ciphers Started\n"); INIT_SEQ_CLEAR_ALL_FLAGS(qctx); if (qat_get_sw_fallback_enabled()) fallback = 1; # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD fallback = 1; # endif if (qat_get_qat_offload_disabled()) { /* * Setting qctx->fallback as a flag for the other functions. * This means in the other functions (and in the err section in this function) * we no longer need to check qat_get_qat_offload_disabled() but just check * the fallback flag instead. This has the added benefit that even if * the engine control message to enable HW offload is sent it will not affect * requests that have already been init'd, they will continue to use SW until * the request is complete, i.e. no race condition. */ fallback = 1; } /* iv has been initialized in qatprovider, we don't need to do any operations if using qatprovider here. */ #ifdef QAT_OPENSSL_PROVIDER ckeylen = keylen; ckey = OPENSSL_malloc(keylen); #else if (iv != NULL) memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx)); else memset(EVP_CIPHER_CTX_iv_noconst(ctx), 0, EVP_CIPHER_CTX_iv_length(ctx)); ckeylen = EVP_CIPHER_CTX_key_length(ctx); ckey = OPENSSL_malloc(ckeylen); #endif if (ckey == NULL) { WARN("Unable to allocate memory for Cipher key.\n"); return 0; } memcpy(ckey, inkey, ckeylen); memset(qctx, 0, sizeof(*qctx)); qctx->numpipes = 1; qctx->total_op = 0; qctx->npipes_last_used = 1; qctx->fallback = 0; qctx->hmac_key = OPENSSL_zalloc(HMAC_KEY_SIZE); if (qctx->hmac_key == NULL) { WARN("Unable to allocate memory for HMAC Key\n"); goto err; } ssd = OPENSSL_zalloc(sizeof(CpaCySymSessionSetupData)); if (ssd == NULL) { WARN("Failed to allocate session setup data\n"); goto err; } qctx->session_data = ssd; /* Copy over the template for most of the values */ memcpy(ssd, &template_ssd, sizeof(template_ssd)); /* Change constant values for decryption */ if (!enc) { ssd->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; ssd->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; ssd->verifyDigest = CPA_TRUE; } ssd->cipherSetupData.cipherKeyLenInBytes = ckeylen; ssd->cipherSetupData.pCipherKey = ckey; #ifdef QAT_OPENSSL_PROVIDER dlen = get_digest_len(ctx->nid); #else dlen = get_digest_len(EVP_CIPHER_CTX_nid(ctx)); #endif ssd->hashSetupData.digestResultLenInBytes = dlen; if (dlen != SHA_DIGEST_LENGTH) ssd->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA256; ssd->hashSetupData.authModeSetupData.authKey = qctx->hmac_key; qctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (qctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); goto err; } qctx->qat_svm = !qat_instance_details[qctx->inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; DUMP_SESSION_SETUP_DATA(ssd); sts = cpaCySymSessionCtxGetSize(qat_instance_handles[qctx->inst_num], ssd, &sctx_size); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); goto err; } DEBUG("Size of session ctx = %d\n", sctx_size); sctx = (CpaCySymSessionCtx) qat_mem_alloc(sctx_size, qctx->qat_svm, __FILE__, __LINE__); if (sctx == NULL) { WARN("QMEM alloc failed for session ctx!\n"); goto err; } qctx->session_ctx = sctx; qctx->qop = NULL; qctx->qop_len = 0; INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_QAT_CTX_INIT); DEBUG_PPL("[%p] qat chained cipher ctx %p initialised\n",ctx, qctx); ret = 1; goto end; err: /* NOTE: no init seq flags will have been set if this 'err:' label code section is entered. */ OPENSSL_clear_free(ckey, ckeylen); OPENSSL_clear_free(qctx->hmac_key, HMAC_KEY_SIZE); if (ssd != NULL) OPENSSL_free(ssd); qctx->session_data = NULL; QAT_MEM_FREE_BUFF(qctx->session_ctx, qctx->qat_svm); end: if (fallback) { #ifndef QAT_OPENSSL_PROVIDER sw_cipher = (EVP_CIPHER *)GET_SW_CIPHER(ctx); sw_size = EVP_CIPHER_impl_ctx_size(sw_cipher); if (sw_size != 0) { qctx->sw_ctx_cipher_data = OPENSSL_zalloc(sw_size); if (qctx->sw_ctx_cipher_data == NULL) { WARN("Unable to allocate memory [%u bytes] for sw_ctx_cipher_data\n", sw_size); return 0; } } else { WARN("Unable to allocate memory for sw_ctx_cipher_data since sw_size is 0\n"); return 0; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); /* Run the software init function */ ret = EVP_CIPHER_meth_get_init(sw_cipher)(ctx, inkey, iv, enc); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (ret != 1) { if (qctx->sw_ctx_cipher_data != NULL) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } return 0; } #else OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); if (enc) { if (!sw_ctx) sw_ctx = sw_aes_cbc_cipher.newctx(ctx); ret = sw_aes_cbc_cipher.einit(sw_ctx, inkey, keylen, iv, ivlen, params); } else { if (!sw_ctx) sw_ctx = sw_aes_cbc_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); ret = sw_aes_cbc_cipher.dinit(sw_ctx, inkey, keylen, iv, ivlen, params); } ctx->sw_ctx = sw_ctx; if (ret != 1) return 0; #endif } return ret; } /****************************************************************************** * function: * qat_chained_ciphers_ctrl(EVP_CIPHER_CTX *ctx, * int type, int arg, void *ptr) * * @param ctx [IN] - pointer to existing ctx * @param type [IN] - type of request either * EVP_CTRL_AEAD_SET_MAC_KEY or EVP_CTRL_AEAD_TLS1_AAD * @param arg [IN] - size of the pointed to by ptr * @param ptr [IN] - input buffer contain the necessary parameters * * @retval x The return value is dependent on the type of request being made * EVP_CTRL_AEAD_SET_MAC_KEY return of 1 is success * EVP_CTRL_AEAD_TLS1_AAD return value indicates the amount of padding to * be applied to the SSL/TLS record * @retval -1 function failed * * description: * This function is a generic control interface provided by the EVP API. For * chained requests this interface is used for setting the hmac key value for * authentication of the SSL/TLS record. The second type is used to specify the * TLS virtual header which is used in the authentication calculation and to * identify record payload size. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chained_ciphers_ctrl(PROV_AES_HMAC_SHA_CTX *ctx, int type, int arg, void *ptr) #else int qat_chained_ciphers_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) #endif { qat_chained_ctx *qctx = NULL; unsigned char *hmac_key = NULL; CpaCySymSessionSetupData *ssd = NULL; SHA_CTX hkey1; SHA256_CTX hkey256; CpaStatus sts; char *hdr = NULL; unsigned int len = 0; int retVal = 0; #ifndef QAT_OPENSSL_PROVIDER int retVal_sw = 0; #endif int fallback = qat_get_sw_fallback_enabled(); int dlen = 0; if (ctx == NULL) { WARN("ctx parameter is NULL.\n"); return -1; } #ifdef QAT_OPENSSL_PROVIDER qctx = (qat_chained_ctx *)ctx->base.qat_cipher_ctx; #else qctx = qat_chained_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL.\n"); return -1; } #ifdef QAT_OPENSSL_PROVIDER dlen = get_digest_len(ctx->base.nid); #else dlen = get_digest_len(EVP_CIPHER_CTX_nid(ctx)); #endif switch (type) { case EVP_CTRL_AEAD_SET_MAC_KEY: hmac_key = qctx->hmac_key; ssd = qctx->session_data; memset(hmac_key, 0, HMAC_KEY_SIZE); if (arg > HMAC_KEY_SIZE) { if (dlen == SHA_DIGEST_LENGTH) { SHA1_Init(&hkey1); SHA1_Update(&hkey1, ptr, arg); SHA1_Final(hmac_key, &hkey1); } else { SHA256_Init(&hkey256); SHA256_Update(&hkey256, ptr, arg); SHA256_Final(hmac_key, &hkey256); } } else { memcpy(hmac_key, ptr, arg); ssd->hashSetupData.authModeSetupData.authKeyLenInBytes = arg; } INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_HMAC_KEY_SET); DEBUG("inst_num = %d\n", qctx->inst_num); DUMP_SESSION_SETUP_DATA(ssd); DEBUG("session_ctx = %p\n", qctx->session_ctx); sts = cpaCySymInitSession(qat_instance_handles[qctx->inst_num], qat_chained_callbackFn, ssd, qctx->session_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymInitSession failed! Status = %d\n", sts); if (fallback && ((sts == CPA_STATUS_RESTARTING) || (sts == CPA_STATUS_FAIL) || (sts == CPA_STATUS_UNSUPPORTED))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } else retVal = 0; } else { if (fallback) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_QAT_SESSION_INIT); retVal = 1; } break; case EVP_CTRL_AEAD_TLS1_AAD: /* This returns the amount of padding required for the send/encrypt direction. */ if (arg != TLS_VIRT_HDR_SIZE || qctx->aad_ctr >= QAT_MAX_PIPELINES) { WARN("Invalid argument for AEAD_TLS1_AAD.\n"); retVal = -1; break; } hdr = GET_TLS_HDR(qctx, qctx->aad_ctr); memcpy(hdr, ptr, TLS_VIRT_HDR_SIZE); qctx->aad_ctr++; if (qctx->aad_ctr > 1) INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_PPL_AADCTR_SET); len = GET_TLS_PAYLOAD_LEN(((char *)ptr)); if (GET_TLS_VERSION(((char *)ptr)) >= TLS1_1_VERSION) { #ifdef QAT_OPENSSL_PROVIDER if (len < ctx->base.ivlen) { #else if (len < EVP_CIPHER_CTX_iv_length(ctx)) { #endif WARN("Length is smaller than the IV length\n"); retVal = 0; break; } #ifdef QAT_OPENSSL_PROVIDER len -= ctx->base.ivlen; #else len -= EVP_CIPHER_CTX_iv_length(ctx); #endif } else if (qctx->aad_ctr > 1) { /* pipelines are not supported for * TLS version < TLS1.1 */ WARN("AAD already set for TLS1.0\n"); retVal = -1; break; } #ifdef QAT_OPENSSL_PROVIDER if (ctx->base.enc){ ctx->tls_aad_pad = (int)(((len + dlen + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - len); retVal = ctx->tls_aad_pad; } else { ctx->payload_length = arg; ctx->tls_aad_pad = SHA_DIGEST_LENGTH; retVal = 1; } #else if (EVP_CIPHER_CTX_encrypting(ctx)) retVal = (int)(((len + dlen + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - len); else retVal = dlen; #endif INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_TLS_HDR_SET); break; /* All remaining cases are exclusive to pipelines and are not * used with small packet offload feature. */ case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: if (arg > QAT_MAX_PIPELINES) { WARN("PIPELINE_OUTPUT_BUFS npipes(%d) > Max(%d).\n", arg, QAT_MAX_PIPELINES); return -1; } qctx->p_out = (unsigned char **)ptr; qctx->numpipes = arg; INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_PPL_OBUF_SET); return 1; case EVP_CTRL_SET_PIPELINE_INPUT_BUFS: if (arg > QAT_MAX_PIPELINES) { WARN("PIPELINE_OUTPUT_BUFS npipes(%d) > Max(%d).\n", arg, QAT_MAX_PIPELINES); return -1; } qctx->p_in = (unsigned char **)ptr; qctx->numpipes = arg; INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_PPL_IBUF_SET); return 1; case EVP_CTRL_SET_PIPELINE_INPUT_LENS: if (arg > QAT_MAX_PIPELINES) { WARN("PIPELINE_INPUT_LENS npipes(%d) > Max(%d).\n", arg, QAT_MAX_PIPELINES); return -1; } qctx->p_inlen = (size_t *)ptr; qctx->numpipes = arg; INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_PPL_BUF_LEN_SET); return 1; default: WARN("Unknown type parameter\n"); return -1; } /* Openssl EVP implementation changes the size of payload encoded in TLS * header pointed by ptr for EVP_CTRL_AEAD_TLS1_AAD, hence call is made * here after ptr has been processed by engine implementation. */ /* Currently, the s/w fallback feature does not support the use of pipelines. * However, even if the 'type' parameter passed in to this function implies * the use of pipelining, the s/w equivalent function (with this 'type' parameter) * will always be called if this 'sw_ctrl' label is reached. If the s/w function * succeeds then, if fallback is set, this success is returned to the calling function. * If, however, the s/w function fails, then this s/w failure is always returned * to the calling function regardless of whether fallback is set. An example * would be multiple calls to this function with type == EVP_CTRL_AEAD_TLS1_AAD * such that qctx->aad_ctr becomes > 1, which would imply the use of pipelining. * These multiple calls are always made to the s/w equivalent function. */ if (fallback) { #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); retVal_sw = EVP_CIPHER_meth_get_ctrl(GET_SW_CIPHER(ctx))(ctx, type, arg, ptr); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (retVal_sw <= 0) WARN("s/w chained ciphers ctrl function failed.\n"); return retVal_sw; #endif } return retVal; } /****************************************************************************** * function: * qat_chained_ciphers_cleanup(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to existing ctx * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chained_ciphers_cleanup(PROV_CIPHER_CTX *ctx) #else int qat_chained_ciphers_cleanup(EVP_CIPHER_CTX *ctx) #endif { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif qat_chained_ctx *qctx = NULL; CpaStatus sts = 0; CpaCySymSessionSetupData *ssd = NULL; int retVal = 1; if (ctx == NULL) { WARN("ctx parameter is NULL.\n"); return 0; } #ifdef QAT_OPENSSL_PROVIDER qctx = (qat_chained_ctx *)ctx->qat_cipher_ctx; #else qctx = qat_chained_data(ctx); #endif if (qctx == NULL) { WARN("qctx parameter is NULL.\n"); return 0; } #ifdef QAT_OPENSSL_PROVIDER if (ctx->sw_ctx) { OPENSSL_free(ctx->sw_ctx); ctx->sw_ctx = NULL; } #else if (qctx->sw_ctx_cipher_data != NULL) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } #endif /* ctx may be cleaned before it gets a chance to allocate qop */ qat_chained_ciphers_free_qop(&qctx->qop, &qctx->qop_len, qctx->qat_svm); ssd = qctx->session_data; if (ssd) { if (INIT_SEQ_IS_FLAG_SET(qctx, INIT_SEQ_QAT_SESSION_INIT)) { if (is_instance_available(qctx->inst_num)) { /* Clean up session if hardware available regardless of whether in */ /* fallback or not, if in INIT_SEQ_QAT_SESSION_INIT */ sts = cpaCySymRemoveSession(qat_instance_handles[qctx->inst_num], qctx->session_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, sts = %d\n", sts); retVal = 0; } } } QAT_MEM_FREE_BUFF(qctx->session_ctx, qctx->qat_svm); OPENSSL_clear_free(ssd->hashSetupData.authModeSetupData.authKey, ssd->hashSetupData.authModeSetupData. authKeyLenInBytes); OPENSSL_clear_free(ssd->cipherSetupData.pCipherKey, ssd->cipherSetupData.cipherKeyLenInBytes); OPENSSL_free(ssd); } qctx->fallback = 0; INIT_SEQ_CLEAR_ALL_FLAGS(qctx); DEBUG_PPL("[%p] EVP CTX cleaned up\n", ctx); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif return retVal; } /****************************************************************************** * function: * qat_chained_ciphers_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * const unsigned char *in, size_t len) * * @param ctx [IN] - pointer to existing ctx * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval 0 function failed * @retval 1 function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_chained_ciphers_do_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t len) #else int qat_chained_ciphers_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { CpaStatus sts = 0; CpaCySymOpData *opd = NULL; CpaBufferList *s_sgl = NULL; CpaBufferList *d_sgl = NULL; CpaFlatBuffer *s_fbuf = NULL; CpaFlatBuffer *d_fbuf = NULL; int retVal = 0, job_ret = 0; unsigned int pad_check = 1; int pad_len = 0; int plen = 0; int plen_adj = 0; op_done_pipe_t done; qat_chained_ctx *qctx = NULL; unsigned char *inb, *outb; unsigned char ivec[AES_BLOCK_SIZE]; unsigned char out_blk[TLS_MAX_PADDING_LENGTH + 1] = { 0x0 }; const unsigned char *in_blk = NULL; unsigned int ivlen = 0; int dlen, vtls, enc, i, buflen; int discardlen = 0; char *tls_hdr = NULL; int pipe = 0; int error = 0; int outlen = -1; int fallback = 0; size_t original_len = len; thread_local_variables_t *tlv = NULL; if (ctx == NULL) { WARN("CTX parameter is NULL.\n"); return -1; } #ifdef QAT_OPENSSL_PROVIDER PROV_EVP_CIPHER sw_aes_cbc_cipher; qctx = (qat_chained_ctx *)ctx->qat_cipher_ctx; #else qctx = qat_chained_data(ctx); #endif if (qctx == NULL) { WARN("QAT CTX NULL\n"); return -1; } if (!(is_instance_available(qctx->inst_num))) { WARN("No QAT instance available.\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto fallback; } else { WARN("Fail - No QAT instance available and s/w fallback is not enabled.\n"); return -1; /* Fail if software fallback not enabled. */ } } else { if (!INIT_SEQ_IS_FLAG_SET(qctx, INIT_SEQ_QAT_CTX_INIT)) { WARN("QAT Context not initialised"); if (qat_get_sw_fallback_enabled()) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); fallback = 1; goto fallback; } return -1; } } /* Pipeline initialisation requires multiple EVP_CIPHER_CTX_ctrl * calls to set all required parameters. Check if all have been * provided. For Pipeline, in and out buffers can be NULL as these * are supplied through ctrl messages. */ if (PIPELINE_INCOMPLETE_INIT(qctx) || (!PIPELINE_SET(qctx) && (out == NULL || (len % AES_BLOCK_SIZE)))) { WARN("%s \n", PIPELINE_INCOMPLETE_INIT(qctx) ? "Pipeline not initialised completely" : len % AES_BLOCK_SIZE ? "Buffer Length not multiple of AES block size" : "out buffer null"); return -1; } #ifdef QAT_OPENSSL_PROVIDER enc = ctx->enc; #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif /* If we are encrypting and EVP_EncryptFinal_ex is called with a NULL input buffer then return 0. Note: we don't actually support partial requests in the engine but this workaround avoids an error from OpenSSL speed on the last request when measuring cipher performance. Speed is written to measure performance using partial requests.*/ if (!PIPELINE_SET(qctx) && in == NULL && out != NULL && enc) { DEBUG("QAT partial requests work-around: NULL input buffer passed.\n"); return 0; } if (!INIT_SEQ_IS_FLAG_SET(qctx, INIT_SEQ_QAT_SESSION_INIT)) { /* The qat session is initialized when HMAC key is set. In case * HMAC key is not explicitly set, use default HMAC key of all zeros * and initialise a qat session. */ if (!PIPELINE_SET(qctx) && !TLS_HDR_SET(qctx) && !enc) { /* When decrypting do not verify computed digest * against stored digest as there is none in this case. */ qctx->session_data->verifyDigest = CPA_FALSE; } DEBUG("inst_num = %d\n", qctx->inst_num); DUMP_SESSION_SETUP_DATA(qctx->session_data); DEBUG("session_ctx = %p\n", qctx->session_ctx); sts = cpaCySymInitSession(qat_instance_handles[qctx->inst_num], qat_chained_callbackFn, qctx->session_data, qctx->session_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymInitSession failed! Status = %d\n", sts); if (qat_get_sw_fallback_enabled() && ((sts == CPA_STATUS_RESTARTING) || (sts == CPA_STATUS_FAIL) || (sts == CPA_STATUS_UNSUPPORTED))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto fallback; } else return -1; } else { if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_QAT_SESSION_INIT); } } #ifdef QAT_OPENSSL_PROVIDER ivlen = ctx->ivlen; dlen = get_digest_len(ctx->nid); #else ivlen = EVP_CIPHER_CTX_iv_length(ctx); dlen = get_digest_len(EVP_CIPHER_CTX_nid(ctx)); #endif /* Check and setup data structures for pipeline */ if (PIPELINE_SET(qctx)) { /* All the aad data (tls header) should be present */ if (qctx->aad_ctr != qctx->numpipes) { WARN("AAD data missing supplied %u of %u\n", qctx->aad_ctr, qctx->numpipes); return -1; } } else { #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifdef QAT_OPENSSL_PROVIDER int threshold_val = qat_pkt_threshold_table_get_threshold(ctx->nid); //threshold_val = 0; // in qatengine with openssl ver1.1.1, this value is always 0. Why? if (len <= threshold_val) { int sw_ret = 0; sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); if (sw_aes_cbc_cipher.cupdate == NULL) goto cleanup; if (in != NULL) sw_ret = sw_aes_cbc_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, len); else sw_ret = sw_aes_cbc_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); *outl = len; if (!sw_ret) goto cleanup; return sw_ret; } # else if (len <= qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) { EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); retVal = EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (retVal) { outlen = len; } goto cleanup; } # endif #endif /* When no TLS AAD information is supplied, for example: speed, * the payload length for encrypt/decrypt is equal to buffer len * and the HMAC is to be discarded. Set the fake AAD hdr to avoid * decision points in code for this special case handling. */ if (!TLS_HDR_SET(qctx)) { tls_hdr = GET_TLS_HDR(qctx, 0); /* Mark an invalid tls version */ tls_hdr[9] = tls_hdr[10] = 0; /* Set the payload length equal to entire length * of buffer i.e. there is no space for HMAC in * buffer. */ SET_TLS_PAYLOAD_LEN(tls_hdr, 0); plen = len; /* Find the extra length for qat buffers to store the HMAC and * padding which is later discarded when the result is copied out. * Note: AES_BLOCK_SIZE must be a power of 2 for this algorithm to * work correctly. * If the digest len (dlen) is a multiple of AES_BLOCK_SIZE, then * discardlen could theoretically be equal to 'dlen'. However * 1 byte is still needed for the required pad_len field which would * not be available in this case. Therefore we add an additional AES_BLOCK_SIZE to * ensure that even for the case of (dlen % AES_BLOCK_SIZE == 0) there * is room for the pad_len field byte - in this specific case the pad space * field would comprise the remaining 15 bytes and the pad_len byte field * would be equal to 15. * The '& ~(AES_BLOCK_SIZE - 1)' element of the algorithm serves to round down * 'discardlen' to the nearest AES_BLOCK_SIZE multiple. */ discardlen = ((len + dlen + AES_BLOCK_SIZE) & ~(AES_BLOCK_SIZE - 1)) - len; /* Pump-up the len by this amount */ len += discardlen; } /* If the same ctx is being re-used for multiple invocation * of this function without setting EVP_CTRL for number of pipes, * the PIPELINE_SET is true from previous invocation. Clear Pipeline * when add_ctr is 1. This means user wants to switch from pipeline mode * to non-pipeline mode for the same ctx. */ CLEAR_PIPELINE(qctx); /* setting these helps avoid decision branches when * pipelines are not used. */ qctx->p_in = (unsigned char **)∈ qctx->p_out = &out; qctx->p_inlen = &len; } DEBUG_PPL("[%p] Start Cipher operation with num pipes %u\n", ctx, qctx->numpipes); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); return -1; } if ((qat_setup_op_params(ctx) != 1) || (qat_init_op_done_pipe(&done, qctx->numpipes) != 1)) { WARN("Failure in qat_setup_op_params or qat_init_op_done_pipe\n"); return -1; } do { opd = &qctx->qop[pipe].op_data; tls_hdr = GET_TLS_HDR(qctx, pipe); vtls = GET_TLS_VERSION(tls_hdr); s_fbuf = qctx->qop[pipe].src_fbuf; d_fbuf = qctx->qop[pipe].dst_fbuf; s_sgl = &qctx->qop[pipe].src_sgl; d_sgl = &qctx->qop[pipe].src_sgl; inb = &qctx->p_in[pipe][0]; outb = &qctx->p_out[pipe][0]; buflen = qctx->p_inlen[pipe]; if (vtls >= TLS1_1_VERSION) { /* * Note: The OpenSSL framework assumes that the IV field will be part * of the output data. In order to chain HASH and CIPHER we need to * present contiguous SGL to QAT, copy IV to output buffer now and * skip it for chained operation. */ if (inb != outb) memcpy(outb, inb, ivlen); memcpy(opd->pIv, inb, ivlen); inb += ivlen; buflen -= ivlen; plen_adj = ivlen; } else { if (qctx->numpipes > 1) { WARN("Pipe %d tls hdr version < tls1.1\n", pipe); error = 1; break; } #ifdef QAT_OPENSSL_PROVIDER memcpy(opd->pIv, ctx->iv, ivlen); #else memcpy(opd->pIv, EVP_CIPHER_CTX_iv(ctx), ivlen); #endif } /* Calculate payload and padding len */ if (enc) { /* For encryption, payload length is in the header. * For non-TLS use case, plen has already been set above. * For TLS Version > 1.1 the payload length also contains IV len. */ if (vtls >= TLS1_VERSION) plen = GET_TLS_PAYLOAD_LEN(tls_hdr) - plen_adj; if (plen > buflen) { WARN("plen %d > buflen %d\n", plen, buflen); error = 1; break; } /* Compute the padding length using total buffer length, payload * length, digest length and a byte to encode padding len. */ pad_len = buflen - (plen + dlen) - 1; /* If padlen is negative, then size of supplied output buffer * is smaller than required. */ if ((buflen % AES_BLOCK_SIZE) != 0 || pad_len < 0 || pad_len > TLS_MAX_PADDING_LENGTH) { WARN("buffer len[%d] or pad_len[%d] incorrect\n", buflen, pad_len); error = 1; break; } } else if (vtls >= TLS1_VERSION) { /* Decrypt the last block of the buffer to get the pad_len. * Calculate payload len using total length and padlen. * NOTE: plen so calculated does not account for ivlen * if iv is appended for TLS Version >= 1.1 */ unsigned int tmp_padlen = TLS_MAX_PADDING_LENGTH + 1; unsigned int maxpad, res = 0xff; size_t j; uint8_t cmask, b; int rx_len = 0; EVP_CIPHER_CTX *dctx = NULL; int decryptFinal_out_len = 0; int decrypt_error = 0; if ((buflen - dlen) <= TLS_MAX_PADDING_LENGTH) tmp_padlen = (((buflen - dlen) + (AES_BLOCK_SIZE - 1)) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; in_blk = inb + (buflen - tmp_padlen); memcpy(ivec, in_blk - AES_BLOCK_SIZE, AES_BLOCK_SIZE); dctx = EVP_CIPHER_CTX_new(); if (dctx == NULL) { WARN("Failed to create decrypt context dctx.\n"); error = 1; break; } EVP_CIPHER_CTX_init(dctx); EVP_CIPHER_CTX_set_flags(dctx, EVP_CIPH_NO_PADDING); #ifdef QAT_OPENSSL_PROVIDER if (!EVP_DecryptInit_ex(dctx, get_cipher_from_nid(ctx->nid), NULL, qctx->session_data->cipherSetupData.pCipherKey, ivec)) { #else if (!EVP_DecryptInit_ex(dctx, GET_SW_NON_CHAINED_CIPHER(ctx), NULL, qctx->session_data->cipherSetupData.pCipherKey, ivec)) { #endif WARN("DecryptInit error occurred.\n"); decrypt_error = 1; } else { if (!EVP_DecryptUpdate(dctx, out_blk, &rx_len, in_blk, tmp_padlen) || !EVP_DecryptFinal_ex(dctx, out_blk + rx_len, &decryptFinal_out_len)) { WARN("Decrypt error occurred.\n"); decrypt_error = 1; } } EVP_CIPHER_CTX_cleanup(dctx); OPENSSL_free(dctx); dctx = NULL; if (decrypt_error) { error = 1; break; } pad_len = out_blk[tmp_padlen - 1]; /* Determine the maximum amount of padding that could be present */ maxpad = buflen - (dlen + 1); maxpad |= (TLS_MAX_PADDING_LENGTH - maxpad) >> (sizeof(maxpad) * 8 - 8); maxpad &= TLS_MAX_PADDING_LENGTH; /* Check the padding in constant time */ for (j = 0; j <= maxpad; j++) { cmask = qat_constant_time_ge_8(pad_len, j); b = out_blk[tmp_padlen - 1 - j]; res &= ~(cmask & (pad_len ^ b)); } res = qat_constant_time_eq(0xff, res & 0xff); pad_check &= (int)res; /* Adjust the amount of data to digest to be the maximum by setting * pad_len = 0 if the padding check failed or if the padding length * is greater than the maximum padding allowed. This adjustment * is done in constant time. */ pad_check &= qat_constant_time_ge(maxpad, pad_len); pad_len *= pad_check; plen = buflen - (pad_len + 1 + dlen); } opd->messageLenToCipherInBytes = buflen; opd->messageLenToHashInBytes = TLS_VIRT_HDR_SIZE + plen; /* copy tls hdr in flatbuffer's last 13 bytes */ memcpy(d_fbuf[0].pData + (d_fbuf[0].dataLenInBytes - TLS_VIRT_HDR_SIZE), tls_hdr, TLS_VIRT_HDR_SIZE); /* Update the value of payload before HMAC calculation */ SET_TLS_PAYLOAD_LEN((d_fbuf[0].pData + (d_fbuf[0].dataLenInBytes - TLS_VIRT_HDR_SIZE)), plen); if (!qctx->qat_svm) { FLATBUFF_ALLOC_AND_CHAIN(s_fbuf[1], d_fbuf[1], buflen); } else { s_fbuf[1].pData = (Cpa8U *)inb; d_fbuf[1].pData = s_fbuf[1].pData; s_fbuf[1].dataLenInBytes = buflen; d_fbuf[1].dataLenInBytes = buflen; } if ((s_fbuf[1].pData) == NULL) { WARN("Failure in src buffer allocation.\n"); error = 1; break; } if (!qctx->qat_svm) memcpy(d_fbuf[1].pData, inb, buflen - discardlen); if (enc) { i = plen + dlen; if (i < 0 || i > buflen) { WARN("plen %d or dlen %d out of range, buflen %d\n", plen, dlen, buflen); error = 1; break; } /* Add padding to input buffer at end of digest */ for (; i < buflen; i++) d_fbuf[1].pData[i] = pad_len; } else { /* store IV for next cbc operation */ if (vtls < TLS1_1_VERSION) #ifdef QAT_OPENSSL_PROVIDER memcpy(ctx->iv, inb + (buflen - discardlen) - ivlen, ivlen); #else memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), inb + (buflen - discardlen) - ivlen, ivlen); #endif } DUMP_SYM_PERFORM_OP(qat_instance_handles[qctx->inst_num], opd, s_sgl, d_sgl); /* Increment prior to successful submission */ done.num_submitted++; sts = qat_sym_perform_op(qctx->inst_num, &done, opd, s_sgl, d_sgl, &(qctx->session_data->verifyDigest)); if (sts != CPA_STATUS_SUCCESS) { if (qat_get_sw_fallback_enabled() && ((sts == CPA_STATUS_RESTARTING) || (sts == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); fallback = 1; } WARN("Failed to submit request to qat - status = %d\n", sts); error = 1; /* Decrement after failed submission */ done.num_submitted--; break; } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } } while (++pipe < qctx->numpipes); /* If there has been an error during submission of the pipes * indicate to the callback function not to wait for the entire * pipeline. */ if (error == 1) done.num_pipes = pipe; /* If there is nothing to wait for, do not pause or yield */ if (done.num_submitted == 0 || (done.num_submitted == done.num_processed)) { if (done.opDone.job != NULL) { qat_clear_async_event_notification(done.opDone.job); } goto end; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); return -1; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (done.opDone.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(done.opDone.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!done.opDone.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); end: qctx->total_op += done.num_processed; DUMP_SYM_PERFORM_OP_OUTPUT(&(qctx->session_data->verifyDigest), d_sgl); if (error == 0 && (done.opDone.verifyResult == CPA_TRUE)) { retVal = 1 & pad_check; if (retVal == 1) outlen = 0; } else { if (qat_get_sw_fallback_enabled() && done.opDone.verifyResult == CPA_FALSE) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto fallback; } } qat_cleanup_op_done_pipe(&done); pipe = 0; do { if (retVal == 1) { if (!qctx->qat_svm) { memcpy(qctx->p_out[pipe] + plen_adj, qctx->qop[pipe].dst_fbuf[1].pData, qctx->p_inlen[pipe] - discardlen - plen_adj); } else { qctx->p_out[pipe] += plen_adj; qctx->qop[pipe].dst_fbuf[1].pData -= plen_adj; qctx->p_out[pipe] = qctx->qop[pipe].dst_fbuf[1].pData; } outlen += buflen + plen_adj - discardlen; } if (!qctx->qat_svm) qaeCryptoMemFreeNonZero(qctx->qop[pipe].src_fbuf[1].pData); qctx->qop[pipe].src_fbuf[1].pData = NULL; qctx->qop[pipe].dst_fbuf[1].pData = NULL; } while (++pipe < qctx->numpipes); if (enc && vtls < TLS1_1_VERSION) #ifdef QAT_OPENSSL_PROVIDER memcpy(ctx->iv, outb + buflen - discardlen - ivlen, ivlen); #else memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), outb + buflen - discardlen - ivlen, ivlen); #endif #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD cleanup: #endif fallback: if (fallback == 1) { if (PIPELINE_SET(qctx)) { WARN("Pipelines are set when in s/w fallback mode, which is not supported.\n"); return -1; } else { #ifdef QAT_OPENSSL_PROVIDER int sw_ret = 0; sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); if (sw_aes_cbc_cipher.cupdate == NULL) return 0; if (in != NULL) sw_ret = sw_aes_cbc_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, original_len); else sw_ret = sw_aes_cbc_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); *outl = len; if (!sw_ret) return 0; outlen = sw_ret; #else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); retVal = EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx)) (ctx, out, in, original_len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (retVal) outlen = original_len; #endif } } /* Reset the AAD counter forcing that new AAD information is provided * before each repeat invocation of this function. */ qctx->aad_ctr = 0; /* This function can be called again with the same evp_cipher_ctx. */ if (PIPELINE_SET(qctx)) { /* Number of pipes can grow between multiple invocation of this call. * Record the maximum number of pipes used so that data structures can * be allocated accordingly. */ INIT_SEQ_CLEAR_FLAG(qctx, INIT_SEQ_PPL_AADCTR_SET); INIT_SEQ_SET_FLAG(qctx, INIT_SEQ_PPL_USED); qctx->npipes_last_used = qctx->numpipes > qctx->npipes_last_used ? qctx->numpipes : qctx->npipes_last_used; } return outlen; } /****************************************************************************** * function: * CpaStatus qat_sym_perform_op(int inst_num, * void *pCallbackTag, * const CpaCySymOpData *pOpData, * const CpaBufferList *pSrcBuffer, * CpaBufferList *pDstBuffer, * CpaBoolean *pVerifyResult) * * @param inst_num [IN] - The current instance * @param pCallbackTag [IN] - Pointer to op_done struct * @param pOpData [IN] - Operation parameters * @param pSrcBuffer [IN] - Source buffer list * @param pDstBuffer [OUT] - Destination buffer list * @param pVerifyResult [OUT] - Whether hash verified or not * * description: * Wrapper around cpaCySymPerformOp which handles retries for us. * *******************************************************************************/ CpaStatus qat_sym_perform_op(int inst_num, void *pCallbackTag, const CpaCySymOpData * pOpData, const CpaBufferList * pSrcBuffer, CpaBufferList * pDstBuffer, CpaBoolean * pVerifyResult) { CpaStatus status = CPA_STATUS_FAIL; op_done_t *opDone = (op_done_t *)pCallbackTag; unsigned int uiRetry = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); do { status = cpaCySymPerformOp(qat_instance_handles[inst_num], pCallbackTag, pOpData, pSrcBuffer, pDstBuffer, pVerifyResult); if (status == CPA_STATUS_RETRY) { DEBUG("cpaCySymPerformOp Retry.\n"); #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) /* The request will switch to qat sw to process if a retry occurs. */ if (qat_sm4_cbc_coexist) { ++num_sm4_cbc_cipher_retry; qat_sw_sm4_cbc_cipher_req += QAT_SW_SWITCH_MB16; qat_cleanup_op_done(opDone); break; } else { #endif if (opDone->job) { if ((qat_wake_job(opDone->job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(opDone->job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("Failed to wake or pause job\n"); status = CPA_STATUS_FAIL; break; } } else { qatPerformOpRetries++; if (uiRetry >= iMsgRetry && iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { WARN("Maximum retries exceeded\n"); status = CPA_STATUS_FAIL; break; } uiRetry++; usleep(ulPollInterval + ( uiRetry % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); } #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) } #endif } } while (status == CPA_STATUS_RETRY); return status; } qatengine-1.9.0/qat_hw_ciphers.h000066400000000000000000000177321500416242000166510ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_ciphers.h * * This file provides an interface for engine cipher operations * *****************************************************************************/ #ifndef QAT_HW_CIPHERS_H # define QAT_HW_CIPHERS_H # ifdef QAT_HW # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" #ifdef QAT_OPENSSL_PROVIDER #include "qat_prov_cbc.h" #endif # define AES_IV_LEN 16 # define AES_KEY_SIZE_256 32 # define AES_KEY_SIZE_128 16 # define QAT_BYTE_SHIFT 8 # define HMAC_KEY_SIZE 64 # define TLS_VIRT_HDR_SIZE 13 # define TLS_MAX_PADDING_LENGTH 255 /* QAT max supported pipelines may be different from * SSL max supported ones. */ # define QAT_MAX_PIPELINES SSL_MAX_PIPELINES /* Use these flags to mark stages in the * initialisation sequence for pipes. */ # define INIT_SEQ_QAT_CTX_INIT 0x0001 # define INIT_SEQ_HMAC_KEY_SET 0x0002 # define INIT_SEQ_QAT_SESSION_INIT 0x0004 # define INIT_SEQ_TLS_HDR_SET 0x0008 # define INIT_SEQ_PPL_IBUF_SET 0x0100 # define INIT_SEQ_PPL_OBUF_SET 0x0200 # define INIT_SEQ_PPL_BUF_LEN_SET 0x0400 # define INIT_SEQ_PPL_AADCTR_SET 0x0800 # define INIT_SEQ_PPL_USED 0x1000 # define qat_chained_data(ctx) \ ((qat_chained_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx)) # define QAT_COMMON_CIPHER_FLAG EVP_CIPH_FLAG_DEFAULT_ASN1 # define QAT_CBC_FLAGS (QAT_COMMON_CIPHER_FLAG | \ EVP_CIPH_CBC_MODE | \ EVP_CIPH_CUSTOM_IV) # define QAT_CHAINED_FLAG (QAT_CBC_FLAGS | \ EVP_CIPH_FLAG_CUSTOM_CIPHER | \ EVP_CIPH_FLAG_AEAD_CIPHER | \ EVP_CIPH_FLAG_PIPELINE) # define INIT_SEQ_PPL_INIT_COMPLETE (INIT_SEQ_PPL_IBUF_SET | \ INIT_SEQ_PPL_OBUF_SET | \ INIT_SEQ_PPL_AADCTR_SET | \ INIT_SEQ_PPL_BUF_LEN_SET) # define INIT_SEQ_CLEAR_ALL_FLAGS(qctx) ((qctx)->init_flags = 0) # define INIT_SEQ_SET_FLAG(qctx, f) ((qctx)->init_flags |= (f)) # define INIT_SEQ_CLEAR_FLAG(qctx, f) ((qctx)->init_flags &= ~(f)) # define INIT_SEQ_IS_FLAG_SET(qctx,f) ((qctx)->init_flags & (f)) # define TLS_HDR_SET(qctx) ((qctx)->init_flags & INIT_SEQ_TLS_HDR_SET) # define PIPELINE_SET(qctx) \ (((qctx)->init_flags & INIT_SEQ_PPL_INIT_COMPLETE) \ == INIT_SEQ_PPL_INIT_COMPLETE) # define PIPELINE_NOT_SET(qctx) \ (((qctx)->init_flags & INIT_SEQ_PPL_INIT_COMPLETE) \ == 0) # define PIPELINE_USED(qctx) ((qctx)->init_flags & INIT_SEQ_PPL_USED) # define PIPELINE_INCOMPLETE_INIT(qctx) \ (!PIPELINE_SET(qctx) && !PIPELINE_NOT_SET(qctx) \ && !PIPELINE_USED(qctx)) # define CLEAR_PIPELINE(qctx) \ do { \ (qctx)->init_flags &= ~(INIT_SEQ_PPL_INIT_COMPLETE); \ (qctx)->numpipes = 1; \ } while(0) typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; typedef struct prov_aes_hmac_sha_ctx_st PROV_AES_HMAC_SHA_CTX; /* These are QAT API operation parameters */ typedef struct qat_op_params_t { CpaCySymOpData op_data; CpaBufferList src_sgl; CpaBufferList dst_sgl; CpaFlatBuffer src_fbuf[2]; CpaFlatBuffer dst_fbuf[2]; } qat_op_params; typedef struct qat_chained_ctx_t { /* Crypto */ unsigned char *hmac_key; /* Pointer to context cipher data (ctx->cipher_data) that will be used by * Small packet offload feature and the s/w fallback feature. */ void *sw_ctx_cipher_data; /* QAT Session Params */ int inst_num; int qat_svm; CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx session_ctx; int init_flags; unsigned int aad_ctr; char aad[QAT_MAX_PIPELINES][TLS_VIRT_HDR_SIZE]; /* QAT Operation Params are required per pipe in the pipeline. * Hence this is a pointer to a dynamically allocated array with * length equal to QAT_MAX_PIPELINES if pipes are used else 1. */ qat_op_params *qop; unsigned int qop_len; /* Pipeline related Data */ unsigned char **p_in; unsigned char **p_out; size_t *p_inlen; unsigned int numpipes; unsigned int npipes_last_used; unsigned long total_op; unsigned int fallback; } qat_chained_ctx; CpaStatus qat_sym_perform_op(int inst_num, void *pCallbackTag, const CpaCySymOpData * pOpData, const CpaBufferList * pSrcBuffer, CpaBufferList * pDstBuffer, CpaBoolean * pVerifyResult); const EVP_CIPHER *qat_create_cipher_meth(int nid, int keylen); # ifdef QAT_OPENSSL_PROVIDER int qat_chained_ciphers_init(PROV_CIPHER_CTX *ctx, const unsigned char *inkey, size_t keylen, const unsigned char *iv, size_t ivlen, int enc); int qat_chained_ciphers_cleanup(PROV_CIPHER_CTX *ctx); int qat_chained_ciphers_do_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t len); int qat_chained_ciphers_ctrl(PROV_AES_HMAC_SHA_CTX *ctx, int type, int arg, void *ptr); # else int qat_chained_ciphers_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc); int qat_chained_ciphers_cleanup(EVP_CIPHER_CTX *ctx); int qat_chained_ciphers_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_chained_ciphers_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); # endif #endif /* QAT_HW */ #endif /* QAT_HW_CIPHERS_H */ qatengine-1.9.0/qat_hw_config/000077500000000000000000000000001500416242000162765ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/200xx/000077500000000000000000000000001500416242000171575ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/200xx/multi_process/000077500000000000000000000000001500416242000220475ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/200xx/multi_process/200xx_dev0.conf000077500000000000000000000114541500416242000245250ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 1 NumberDcInstances = 0 NumProcesses = 16 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 qatengine-1.9.0/qat_hw_config/200xx/multi_thread/000077500000000000000000000000001500416242000216405ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/200xx/multi_thread/200xx_dev0.conf000077500000000000000000000130641500416242000243150ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 8 NumberDcInstances = 0 NumProcesses = 1 LimitDevAccess = 0 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "UserCY1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "UserCY2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "UserCY3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 # Crypto - User instance #4 Cy4Name = "UserCY4" Cy4IsPolled = 1 # List of core affinities Cy4CoreAffinity = 4 # Crypto - User instance #5 Cy5Name = "UserCY5" Cy5IsPolled = 1 # List of core affinities Cy5CoreAffinity = 5 # Crypto - User instance #6 Cy6Name = "UserCY6" Cy6IsPolled = 1 # List of core affinities Cy6CoreAffinity = 6 # Crypto - User instance #7 Cy7Name = "UserCY7" Cy7IsPolled = 1 # List of core affinities Cy7CoreAffinity = 7 qatengine-1.9.0/qat_hw_config/4xxx/000077500000000000000000000000001500416242000172115ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/4xxx/multi_process/000077500000000000000000000000001500416242000221015ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/4xxx/multi_process/4xxx_dev0.conf000066400000000000000000000122331500416242000246020ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ [GENERAL] ServicesEnabled = asym;sym ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 4 NumberDcInstances = 0 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "UserCY1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "UserCY2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "UserCY3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 qatengine-1.9.0/qat_hw_config/4xxx/multi_thread/000077500000000000000000000000001500416242000216725ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/4xxx/multi_thread/4xxx_dev0.conf000066400000000000000000000140401500416242000243710ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ [GENERAL] ServicesEnabled = asym;sym ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Default heartbeat timer is 1s HeartbeatTimer = 1000 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 512 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 # Disable AT ATEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 12 NumberDcInstances = 0 NumProcesses = 1 LimitDevAccess = 0 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "UserCY1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "UserCY2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "UserCY3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 # Crypto - User instance #4 Cy4Name = "UserCY4" Cy4IsPolled = 1 # List of core affinities Cy4CoreAffinity = 4 # Crypto - User instance #5 Cy5Name = "UserCY5" Cy5IsPolled = 1 # List of core affinities Cy5CoreAffinity = 5 # Crypto - User instance #6 Cy6Name = "UserCY6" Cy6IsPolled = 1 # List of core affinities Cy6CoreAffinity = 6 # Crypto - User instance #7 Cy7Name = "UserCY7" Cy7IsPolled = 1 # List of core affinities Cy7CoreAffinity = 7 # Crypto - User instance #8 Cy8Name = "UserCY8" Cy8IsPolled = 1 # List of core affinities Cy8CoreAffinity = 8 # Crypto - User instance #9 Cy9Name = "UserCY9" Cy9IsPolled = 1 # List of core affinities Cy9CoreAffinity = 9 # Crypto - User instance #10 Cy10Name = "UserCY10" Cy10IsPolled = 1 # List of core affinities Cy10CoreAffinity = 10 # Crypto - User instance #11 Cy11Name = "UserCY11" Cy11IsPolled = 1 # List of core affinities Cy11CoreAffinity = 11 qatengine-1.9.0/qat_hw_config/LICENSE.GPL000066400000000000000000000431031500416242000177250ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. qatengine-1.9.0/qat_hw_config/c3xxx/000077500000000000000000000000001500416242000173535ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c3xxx/multi_process/000077500000000000000000000000001500416242000222435ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c3xxx/multi_process/c3xxx_dev0.conf000066400000000000000000000114541500416242000251120ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 1 NumberDcInstances = 0 NumProcesses = 32 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 qatengine-1.9.0/qat_hw_config/c3xxx/multi_thread/000077500000000000000000000000001500416242000220345ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c3xxx/multi_thread/c3xxx_dev0.conf000066400000000000000000000116321500416242000247010ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 2 NumberDcInstances = 0 NumProcesses = 1 LimitDevAccess = 0 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "UserCY1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 0 qatengine-1.9.0/qat_hw_config/c4xxx/000077500000000000000000000000001500416242000173545ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c4xxx/multi_process/000077500000000000000000000000001500416242000222445ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c4xxx/multi_process/c4xxx_dev0.conf000066400000000000000000000101661500416242000251130ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ [GENERAL] ServicesEnabled = cy ConfigVersion = 2 #Default values for allocating accel units to services #Please ensure that that the number of accel units #for an enabled service are not 0 NumCyAccelUnits = 6 NumDcAccelUnits = 0 #Inline feature is not supported NumInlineAccelUnits = 0 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 DcNumConcurrentRequests = 512 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 statsMisc = 1 # This flag is to enable device auto reset on fatal error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 1 NumberDcInstances = 0 NumProcesses = 16 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 Cy0AcceleratorNumber = 0 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #0 Cy1Name = "UserCY1" Cy1IsPolled = 1 Cy1AcceleratorNumber = 0 # List of core affinities Cy1CoreAffinity = 0 qatengine-1.9.0/qat_hw_config/c4xxx/multi_thread/000077500000000000000000000000001500416242000220355ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c4xxx/multi_thread/c4xxx_dev0.conf000066400000000000000000000101251500416242000246770ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ [GENERAL] ServicesEnabled = cy ConfigVersion = 2 #Default values for allocating accel units to services #Please ensure that that the number of accel units #for an enabled service are not 0 NumCyAccelUnits = 6 NumDcAccelUnits = 0 NumInlineAccelUnits = 0 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #DcNumConcurrentRequests = 512 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 statsMisc = 1 # This flag is to enable device auto reset on fatal error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 2 NumberDcInstances = 0 NumProcesses = 1 LimitDevAccess = 0 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 Cy0AcceleratorNumber = 0 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #0 Cy1Name = "UserCY1" Cy1IsPolled = 1 Cy1AcceleratorNumber = 0 # List of core affinities Cy1CoreAffinity = 0 qatengine-1.9.0/qat_hw_config/c6xx/000077500000000000000000000000001500416242000171665ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c6xx/multi_process/000077500000000000000000000000001500416242000220565ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c6xx/multi_process/c6xx_dev0.conf000066400000000000000000000120171500416242000245340ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 1 NumberDcInstances = 0 NumProcesses = 16 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 qatengine-1.9.0/qat_hw_config/c6xx/multi_thread/000077500000000000000000000000001500416242000216475ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/c6xx/multi_thread/c6xx_dev0.conf000066400000000000000000000134271500416242000243330ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 8 NumberDcInstances = 0 NumProcesses = 1 LimitDevAccess = 0 # Crypto - User instance #0 Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "UserCY1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "UserCY2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "UserCY3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 # Crypto - User instance #4 Cy4Name = "UserCY4" Cy4IsPolled = 1 # List of core affinities Cy4CoreAffinity = 4 # Crypto - User instance #5 Cy5Name = "UserCY5" Cy5IsPolled = 1 # List of core affinities Cy5CoreAffinity = 5 # Crypto - User instance #6 Cy6Name = "UserCY6" Cy6IsPolled = 1 # List of core affinities Cy6CoreAffinity = 6 # Crypto - User instance #7 Cy7Name = "UserCY7" Cy7IsPolled = 1 # List of core affinities Cy7CoreAffinity = 7 qatengine-1.9.0/qat_hw_config/dh895xcc/000077500000000000000000000000001500416242000176355ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/dh895xcc/multi_process/000077500000000000000000000000001500416242000225255ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/dh895xcc/multi_process/dh895xcc_dev0.conf000077500000000000000000000113601500416242000256550ustar00rootroot00000000000000######################################################################### # # @par # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ######################################################################### [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 1 NumberDcInstances = 0 NumProcesses = 32 LimitDevAccess = 1 # Crypto - User space Cy0Name = "UserCY0" Cy0IsPolled = 1 Cy0CoreAffinity = 0-31 qatengine-1.9.0/qat_hw_config/dh895xcc/multi_thread/000077500000000000000000000000001500416242000223165ustar00rootroot00000000000000qatengine-1.9.0/qat_hw_config/dh895xcc/multi_thread/dh895xcc_dev0.conf000077500000000000000000000130171500416242000254470ustar00rootroot00000000000000######################################################################### # # @par # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2025 Intel Corporation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ######################################################################### [GENERAL] ServicesEnabled = cy # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 8 NumberDcInstances = 0 NumProcesses = 1 LimitDevAccess = 0 # Crypto - User space Cy0Name = "UserCY0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "UserCY1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "UserCY2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "UserCY3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 # Crypto - User instance #4 Cy4Name = "UserCY4" Cy4IsPolled = 1 # List of core affinities Cy4CoreAffinity = 4 # Crypto - User instance #5 Cy5Name = "UserCY5" Cy5IsPolled = 1 # List of core affinities Cy5CoreAffinity = 5 # Crypto - User instance #6 Cy6Name = "UserCY6" Cy6IsPolled = 1 # List of core affinities Cy6CoreAffinity = 6 # Crypto - User instance #7 Cy7Name = "UserCY7" Cy7IsPolled = 1 # List of core affinities Cy7CoreAffinity = 7 qatengine-1.9.0/qat_hw_dh.c000066400000000000000000001062371500416242000156010ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_dh.c * * This file provides implementations for Diffie Hellman operations through an * OpenSSL engine * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include "qat_hw_dh.h" #include #include #include "qat_hw_asym_common.h" #include "qat_utils.h" #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_dh.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include #include #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif /* To specify the DH op sizes supported by QAT engine */ #define DH_QAT_RANGE_MIN 768 #if defined(QAT20_OOT) || defined(QAT_HW_INTREE) # define DH_QAT_RANGE_MAX 8192 #else # define DH_QAT_RANGE_MAX 4096 #endif #ifdef ENABLE_QAT_HW_DH static int qat_dh_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); static int qat_dh_init(DH *dh); static int qat_dh_finish(DH *dh); #endif static DH_METHOD *qat_dh_method = NULL; static DH_METHOD *def_dh_method = NULL; DH_METHOD *qat_get_DH_methods(void) { #ifdef ENABLE_QAT_HW_DH int res = 1; if (qat_dh_method != NULL && !qat_reload_algo) return qat_dh_method; qat_free_DH_methods(); if ((qat_dh_method = DH_meth_new("QAT DH method", 0)) == NULL) { WARN("Failure allocating DH methods\n"); QATerr(QAT_F_QAT_GET_DH_METHODS, QAT_R_QAT_ALLOC_DH_METH_FAILURE); return NULL; } if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_DH)) { res &= DH_meth_set_generate_key(qat_dh_method, qat_dh_generate_key); res &= DH_meth_set_compute_key(qat_dh_method, qat_dh_compute_key); res &= DH_meth_set_bn_mod_exp(qat_dh_method, qat_dh_mod_exp); res &= DH_meth_set_init(qat_dh_method, qat_dh_init); res &= DH_meth_set_finish(qat_dh_method, qat_dh_finish); if (res == 0) { WARN("Failure setting DH methods\n"); QATerr(QAT_F_QAT_GET_DH_METHODS, QAT_R_QAT_SET_DH_METH_FAILURE); qat_free_DH_methods(); return NULL; } DEBUG("QAT HW DH registration succeeded\n"); return qat_dh_method; } #endif def_dh_method = (DH_METHOD *)DH_get_default_method(); DEBUG("QAT HW DH is disabled, using OpensSSL SW\n"); return def_dh_method; } void qat_free_DH_methods(void) { if (qat_dh_method != NULL) { DH_meth_free(qat_dh_method); qat_dh_method = NULL; } } #ifdef ENABLE_QAT_HW_DH /* * The DH range check is performed so that if the op sizes are not in the * range supported by QAT engine then fall back to software */ static int dh_range_check(int plen) { int range = 0; if ((plen >= DH_QAT_RANGE_MIN) && (plen <= DH_QAT_RANGE_MAX)) range = 1; return range; } /* Callback to indicate QAT completion of DH generate & compute key */ static void qat_dhCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer * pPV) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } /****************************************************************************** * function: * qat_dh_generate_key(DH * dh) * * description: * Implement Diffie-Hellman phase 1 operations. ******************************************************************************/ int qat_dh_generate_key(DH *dh) { int ok = 0, job_ret = 0, fallback = 0; int generate_new_priv_key = 0; int generate_new_pub_key = 0; unsigned length = 0; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *g = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; const BIGNUM *temp_pub_key = NULL, *temp_priv_key = NULL; int inst_num = QAT_INVALID_INSTANCE; CpaCyDhPhase1KeyGenOpData *opData = NULL; CpaFlatBuffer *pPV = NULL; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); CpaStatus status; op_done_t op_done; size_t buflen; const DH_METHOD *sw_dh_method = DH_OpenSSL(); thread_local_variables_t *tlv = NULL; int qat_svm = QAT_INSTANCE_ANY; # ifndef QAT_HW_DISABLE_DH_PRIME_CHECK unsigned char *prime_buf = NULL; int prime_bytes = 0; # endif DEBUG("QAT HW DH Started\n"); if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return DH_meth_get_generate_key(sw_dh_method)(dh); } if (dh == NULL) { WARN("Input variable dh is null\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_DH_NULL); return 0; } DH_get0_pqg(dh, &p, &q, &g); if (p == NULL || g == NULL) { WARN("Failed to get p, q, g\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_P_Q_G_NULL); return 0; } /* * If the op sizes are not in the range supported by QAT engine then fall * back to software */ if (!dh_range_check(BN_num_bits(p))) { if (sw_dh_method == NULL) { WARN("Failed to get sw_dh_method for %d bits\n", BN_num_bits(p)); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_SW_METHOD_NULL); return 0; } return DH_meth_get_generate_key(sw_dh_method)(dh); } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { WARN("Failed to get an instance - fallback to SW - %s\n", __func__); return DH_meth_get_generate_key(sw_dh_method)(dh); } else { QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; # ifndef QAT_HW_DISABLE_DH_PRIME_CHECK prime_bytes = BN_num_bytes(p); prime_buf = OPENSSL_zalloc(prime_bytes); if (prime_buf == NULL) { WARN("OpenSSL zalloc failed for prime_buf\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_MALLOC_FAILURE); return 0; } if (BN_bn2bin(p, prime_buf)) { /* check MSB and LSB of generated prime. */ if (!(prime_buf[0] & 0x80) || !(prime_buf[prime_bytes - 1] & 0x01)) { OPENSSL_free(prime_buf); DEBUG("Generating key through Software - Param p doesn't have MSB or LSB set.\n"); return DH_meth_get_generate_key(sw_dh_method)(dh); } OPENSSL_free(prime_buf); } else { WARN("BN_bn2bin() returns failure for p.\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_INVALID_LEN); OPENSSL_free(prime_buf); return 0; } # endif DH_get0_key(dh, &temp_pub_key, &temp_priv_key); opData = (CpaCyDhPhase1KeyGenOpData *) OPENSSL_zalloc(sizeof(CpaCyDhPhase1KeyGenOpData)); if (opData == NULL) { WARN("Failure allocating memory for opData\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_OPDATA_MALLOC_FAILURE); return ok; } opData->primeP.pData = NULL; opData->baseG.pData = NULL; opData->privateValueX.pData = NULL; if (temp_priv_key == NULL) { if ((priv_key = BN_new()) == NULL) { WARN("Failed to allocate memory for priv_key\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PRIV_KEY_MALLOC_FAILURE); goto err; } generate_new_priv_key = 1; } else { if ((priv_key = BN_dup(temp_priv_key)) == NULL) { WARN("Failed to duplicate the private key\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PRIV_KEY_DUPLICATE_FAILURE); goto err; } } if (temp_pub_key == NULL) { if ((pub_key = BN_new()) == NULL) { WARN("Failed to allocate memory for pub_key\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PUB_KEY_MALLOC_FAILURE); goto err; } generate_new_pub_key = 1; } else { if ((pub_key = BN_dup(temp_pub_key)) == NULL) { WARN("Failed to duplicate the public key\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PUB_KEY_DUPLICATE_FAILURE); goto err; } } if (generate_new_priv_key) { if (q) { do { if (!BN_rand_range(priv_key, q)) { WARN("Failed to generate random number for range %d\n",BN_num_bits(q)); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE); goto err; } } while (BN_is_zero(priv_key) || BN_is_one(priv_key)); } else { /* secret exponent length */ length = DH_get_length(dh) ? DH_get_length(dh) : BN_num_bits(p) - 1; if (!BN_rand(priv_key, length, 0, 0)) { WARN("Failed to generate random number of length %d\n", length); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE); goto err; } } } buflen = BN_num_bytes(p); pPV = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (pPV == NULL) { WARN("Failed to allocate memory for pPV\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PPV_MALLOC_FAILURE); goto err; } pPV->pData = qat_mem_alloc(buflen, qat_svm, __FILE__, __LINE__); if (pPV->pData == NULL) { WARN("Failed to allocate memory for pPV->pData\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_PPV_PDATA_MALLOC_FAILURE); goto err; } pPV->dataLenInBytes = (Cpa32U) buflen; if ((qat_BN_to_FB(&(opData->primeP), (BIGNUM *)p, qat_svm) != 1) || (qat_BN_to_FB(&(opData->baseG), (BIGNUM *)g, qat_svm) != 1) || (qat_BN_to_FB(&(opData->privateValueX), (BIGNUM *)priv_key, qat_svm) != 1)) { WARN("Failed to convert p, g or priv_key to a flat buffer\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, QAT_R_P_G_PRIV_KEY_CONVERT_TO_FB_FAILURE); goto err; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("KX - %s\n", __func__); do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } CRYPTO_QAT_LOG("KX - %s\n", __func__); DUMP_DH_GEN_PHASE1(qat_instance_handles[inst_num], opData, pPV); status = cpaCyDhKeyGenPhase1(qat_instance_handles[inst_num], qat_dhCallbackFn, &op_done, opData, pPV); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_DH_GEN_PHASE1_OUTPUT(pPV); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); /* Convert the flatbuffer result back to a BN */ BN_bin2bn(pPV->pData, pPV->dataLenInBytes, pub_key); if (!DH_set0_key(dh, pub_key, priv_key)) { WARN("Failure setting pub or priv key\n"); QATerr(QAT_F_QAT_DH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); goto err; } ok = 1; err: if (pPV) { if (pPV->pData) { QAT_MEM_FREE_BUFF(pPV->pData,qat_svm); } OPENSSL_free(pPV); } if (opData) { if (!qat_svm) { if (opData->primeP.pData) qaeCryptoMemFree(opData->primeP.pData); if (opData->baseG.pData) qaeCryptoMemFree(opData->baseG.pData); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->privateValueX, qat_svm); } else { QAT_CLEANSE_FLATBUFF(opData->privateValueX); } OPENSSL_free(opData); } if (!ok) { if (generate_new_pub_key) BN_free(pub_key); if (generate_new_priv_key) BN_clear_free(priv_key); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return DH_meth_get_generate_key(sw_dh_method)(dh); } return ok; } /****************************************************************************** * function: * qat_dh_compute_key(unsigned char *key, * const BIGNUM * in_pub_key, DH * dh) * * description: * Implement Diffie-Hellman phase 2 operations. ******************************************************************************/ int qat_dh_compute_key(unsigned char *key, const BIGNUM *in_pub_key, DH *dh) { int ret = -1, job_ret = 0, fallback = 0; int check_result; int inst_num = QAT_INVALID_INSTANCE; CpaCyDhPhase2SecretKeyGenOpData *opData = NULL; CpaFlatBuffer *pSecretKey = NULL; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); CpaStatus status; op_done_t op_done; size_t buflen; int index = 1; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *g = NULL; const BIGNUM *pub_key = NULL, *priv_key = NULL; const DH_METHOD *sw_dh_method = DH_OpenSSL(); thread_local_variables_t *tlv = NULL; int qat_svm = QAT_INSTANCE_ANY; # ifndef QAT_HW_DISABLE_DH_PRIME_CHECK unsigned char *prime_buf = NULL; int prime_bytes = 0; # endif DEBUG("QAT HW DH Started\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(key == NULL)) { WARN("Invalid variable key is NULL.\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_KEY_NULL); return ret; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return DH_meth_get_compute_key(sw_dh_method)(key, in_pub_key, dh); } if (!dh) { WARN("Input variable dh is null\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_DH_NULL); return ret; } DH_get0_pqg(dh, &p, &q, &g); DH_get0_key(dh, &pub_key, &priv_key); if (p == NULL || priv_key == NULL) { WARN("Failure getting p or priv_key\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_P_Q_G_NULL); return ret; } /* * If the op sizes are not in the range supported by QAT engine then fall * back to software */ if (!dh_range_check(BN_num_bits(p))) { if (sw_dh_method == NULL) { WARN("Failed to get sw_dh_method for bits %d\n", BN_num_bits(p)); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_SW_METHOD_NULL); return ret; } return DH_meth_get_compute_key(sw_dh_method)(key, in_pub_key, dh); } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); return DH_meth_get_compute_key(sw_dh_method)(key, in_pub_key, dh); } else { QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; # ifndef QAT_HW_DISABLE_DH_PRIME_CHECK prime_bytes = BN_num_bytes(p); prime_buf = OPENSSL_zalloc(prime_bytes); if (prime_buf == NULL) { WARN("OpenSSL zalloc failed for prime_buf\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_MALLOC_FAILURE); return ret; } if (BN_bn2bin(p, prime_buf)) { /* check MSB and LSB of generated prime. */ if (!(prime_buf[0] & 0x80) || !(prime_buf[prime_bytes - 1] & 0x01)) { OPENSSL_free(prime_buf); DEBUG("Run compute_key in Software - Param p doesn't have MSB or LSB set.\n"); return DH_meth_get_compute_key(sw_dh_method)(key, in_pub_key, dh);; } OPENSSL_free(prime_buf); } else { WARN("BN_bn2bin() returns failure for p.\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_INVALID_LEN); OPENSSL_free(prime_buf); return ret; } # endif if (!DH_check_pub_key(dh, in_pub_key, &check_result) || check_result) { WARN("Failure checking pub key\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_INVALID_PUB_KEY); return ret; } opData = (CpaCyDhPhase2SecretKeyGenOpData *) OPENSSL_zalloc(sizeof(CpaCyDhPhase2SecretKeyGenOpData)); if (opData == NULL) { WARN("Failure allocating memory for opData\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_OPDATA_MALLOC_FAILURE); return ret; } opData->primeP.pData = NULL; opData->remoteOctetStringPV.pData = NULL; opData->privateValueX.pData = NULL; buflen = BN_num_bytes(p); pSecretKey = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (pSecretKey == NULL) { WARN("Failure allocating memory for pSecretKey\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_SECRET_KEY_MALLOC_FAILURE); goto err; } if (qat_svm) pSecretKey->pData = (Cpa8U*) key; else pSecretKey->pData = qaeCryptoMemAlloc(buflen, __FILE__, __LINE__); if (pSecretKey->pData == NULL) { WARN("Failure allocating memory for pSecretKey data\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_SECRET_KEY_PDATA_MALLOC_FAILURE); goto err; } pSecretKey->dataLenInBytes = (Cpa32U) buflen; if ((qat_BN_to_FB(&(opData->primeP), (BIGNUM *)p, qat_svm) != 1) || (qat_BN_to_FB(&(opData->remoteOctetStringPV), (BIGNUM *)in_pub_key, qat_svm) != 1) || (qat_BN_to_FB(&(opData->privateValueX), (BIGNUM *)priv_key, qat_svm) != 1)) { WARN("Failure converting p, pub_key or priv_key into a flat buffer\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, QAT_R_P_PUB_PRIV_KEY_CONVERT_TO_FB_FAILURE); goto err; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("KX - %s\n", __func__); do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } CRYPTO_QAT_LOG("KX - %s\n", __func__); DUMP_DH_GEN_PHASE2(qat_instance_handles[inst_num], opData, pSecretKey); status = cpaCyDhKeyGenPhase2Secret(qat_instance_handles[inst_num], qat_dhCallbackFn, &op_done, opData, pSecretKey); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_DH_GEN_PHASE2_OUTPUT(pSecretKey); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); if (unlikely(pSecretKey->pData == NULL)) { WARN("pSecretKey->pData is NULL\n"); QATerr(QAT_F_QAT_DH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } /* Remove leading zeros */ if (!qat_svm) { if (!pSecretKey->pData[0]) { while (index < pSecretKey->dataLenInBytes && !pSecretKey->pData[index]) index++; pSecretKey->dataLenInBytes = pSecretKey->dataLenInBytes - index; memcpy(key, &pSecretKey->pData[index],pSecretKey->dataLenInBytes); } else { memcpy(key, pSecretKey->pData, pSecretKey->dataLenInBytes); } } ret = pSecretKey->dataLenInBytes; err: if (pSecretKey) { if (!qat_svm) { if (pSecretKey->pData != NULL) { QAT_CLEANSE_FLATBUFF(*pSecretKey); qaeCryptoMemFreeNonZero(pSecretKey->pData); } } OPENSSL_free(pSecretKey); } if (opData) { QAT_MEM_FREE_FLATBUFF(opData->primeP, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->remoteOctetStringPV, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->privateValueX, qat_svm); OPENSSL_free(opData); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return DH_meth_get_compute_key(sw_dh_method)(key, in_pub_key, dh); } return ret; } /****************************************************************************** * function: * qat_dh_mod_exp(const DH * dh, BIGNUM * r, const BIGNUM * a, * const BIGNUM * p, const BIGNUM * m, BN_CTX * ctx, * BN_MONT_CTX * m_ctx) * * @param dh [IN] - Pointer to a OpenSSL DH struct. * @param r [IN] - Result bignum of mod_exp * @param a [IN] - Base used for mod_exp * @param p [IN] - Exponent used for mod_exp * @param m [IN] - Modulus used for mod_exp * @param ctx [IN] - EVP context. * @param m_ctx [IN] - EVP context for Montgomery multiplication. * * description: * Overridden modular exponentiation function used in DH. * ******************************************************************************/ int qat_dh_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { int ret = 0, fallback = 0; const DH_METHOD *sw_dh_method = DH_OpenSSL(); # ifndef QAT_HW_DISABLE_DH_PRIME_CHECK unsigned char *prime_buf = NULL; int prime_bytes = 0; # endif DEBUG("- Started\n"); if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return DH_meth_get_bn_mod_exp(sw_dh_method)(dh, r, a, p, m, ctx, m_ctx); } # ifndef QAT_HW_DISABLE_DH_PRIME_CHECK prime_bytes = BN_num_bytes(p); prime_buf = OPENSSL_zalloc(prime_bytes); if (prime_buf == NULL) { WARN("OpenSSL zalloc failed for prime_buf\n"); return ret; } if (BN_bn2bin(p, prime_buf)) { /* check MSB and LSB of generated prime. */ if (!(prime_buf[0] & 0x80) || !(prime_buf[prime_bytes - 1] & 0x01)) { OPENSSL_free(prime_buf); DEBUG("Run mod_exp operation in Software - Param p doesn't have MSB or LSB set.\n"); return DH_meth_get_bn_mod_exp(sw_dh_method)(dh, r, a, p, m, ctx, m_ctx); } OPENSSL_free(prime_buf); } else { WARN("BN_bn2bin() returns failure for p.\n"); OPENSSL_free(prime_buf); return ret; } # endif CRYPTO_QAT_LOG("KX - %s\n", __func__); ret = qat_mod_exp(r, a, p, m, &fallback); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return DH_meth_get_bn_mod_exp(sw_dh_method)(dh, r, a, p, m, ctx, m_ctx); } else return ret; } /****************************************************************************** * function: * qat_dh_init(DH * dh) * * @param dh [IN] - Pointer to a OpenSSL DH struct. * * description: * Overridden init function. * Calls the SW Implementation to ensure caching flag is set. * ******************************************************************************/ int qat_dh_init(DH *dh) { return DH_meth_get_init(DH_OpenSSL())(dh); } /****************************************************************************** * function: * qat_dh_finish(DH * dh) * * @param dh [IN] - Pointer to a OpenSSL DH struct. * * description: * Overridden finish function. * Calls the SW Implementation to ensure cached data is freed. * ******************************************************************************/ int qat_dh_finish(DH *dh) { return DH_meth_get_finish(DH_OpenSSL())(dh); } #endif /* ENABLE_QAT_HW_DH */ qatengine-1.9.0/qat_hw_dh.h000066400000000000000000000046251500416242000156040ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_dh.h * * This file provides an interface to Diffie Hellman operations * *****************************************************************************/ #ifndef QAT_HW_DH_H # define QAT_HW_DH_H # include /* Qat engine DH methods declaration */ DH_METHOD *qat_get_DH_methods(void); void qat_free_DH_methods(void); # ifdef ENABLE_QAT_HW_DH int qat_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); int qat_dh_generate_key(DH *dh); # endif #endif /* QAT_HW_DH_H */ qatengine-1.9.0/qat_hw_dsa.c000066400000000000000000001103411500416242000157440ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_dsa.c * * This file provides an implementation of DSA operations for an OpenSSL * engine * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include "qat_hw_dsa.h" #include "qat_utils.h" #include "cpa_cy_dsa.h" #include "qat_hw_asym_common.h" #include #include #include #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_dh.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #include #include /* Qat DSA method structure declaration. */ static DSA_METHOD *qat_dsa_method = NULL; static DSA_METHOD *def_dsa_method = NULL; #ifdef ENABLE_QAT_FIPS # ifdef ENABLE_QAT_HW_DSA extern int qat_fips_kat_test; static const unsigned char kvalue[] = { 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; # endif #endif DSA_METHOD *qat_get_DSA_methods(void) { #ifdef ENABLE_QAT_HW_DSA int res = 1; if (qat_dsa_method != NULL && !qat_reload_algo) return qat_dsa_method; qat_free_DSA_methods(); if ((qat_dsa_method = DSA_meth_new("QAT DSA method", 0)) == NULL) { WARN("Failed to allocate DSA methods\n"); QATerr(QAT_F_QAT_GET_DSA_METHODS, QAT_R_ALLOC_QAT_DSA_METH_FAILURE); return NULL; } if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_DSA)) { res &= DSA_meth_set_sign(qat_dsa_method, qat_dsa_do_sign); res &= DSA_meth_set_sign_setup(qat_dsa_method, qat_dsa_sign_setup); res &= DSA_meth_set_verify(qat_dsa_method, qat_dsa_do_verify); res &= DSA_meth_set_bn_mod_exp(qat_dsa_method, qat_dsa_bn_mod_exp); res &= DSA_meth_set_init(qat_dsa_method, qat_dsa_init); res &= DSA_meth_set_finish(qat_dsa_method, qat_dsa_finish); if (res == 0) { WARN("Failed to set DSA methods\n"); QATerr(QAT_F_QAT_GET_DSA_METHODS, QAT_R_SET_QAT_DSA_METH_FAILURE); qat_free_DSA_methods(); return NULL; } DEBUG("QAT HW DSA registration succeeded\n"); return qat_dsa_method; } #endif def_dsa_method = (DSA_METHOD *)DSA_get_default_method(); DEBUG("QAT HW DSA is disabled, using OpenSSL SW\n"); return def_dsa_method; } void qat_free_DSA_methods(void) { if (qat_dsa_method != NULL) { DSA_meth_free(qat_dsa_method); qat_dsa_method = NULL; def_dsa_method = NULL; } } #ifdef ENABLE_QAT_HW_DSA /* * DSA range Supported in QAT {L,N} = {1024, 160}, {2048, 224} {2048, 256}, * {3072, 256} */ int dsa_qat_range[4][2] = { {1024, 160}, {2048, 224}, {2048, 256}, {3072, 256} }; /* * DSA range check is performed so that if the sizes of P and Q are not in * the range supported by QAT engine then fall back to software */ static int dsa_range_check(int plen, int qlen) { int i, j, range = 0; for (i = 0, j = 0; i < 4; i++) { if ((plen == dsa_qat_range[i][j]) && (qlen == dsa_qat_range[i][j + 1])) { range = 1; break; } } return range; } /* Callback to indicate QAT completion of DSA Sign */ static void qat_dsaSignCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bDsaSignStatus, CpaFlatBuffer * pResultR, CpaFlatBuffer * pResultS) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, bDsaSignStatus); } /* Callback to indicate QAT completion of DSA Verify */ static void qat_dsaVerifyCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bDsaVerifyStatus) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, bDsaVerifyStatus); } /****************************************************************************** * function: * qat_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, * const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, * BN_MONT_CTX *m_ctx) * * @param dsa [IN] - Pointer to a OpenSSL DSA struct. * @param r [IN] - Result bignum of mod_exp * @param a [IN] - Base used for mod_exp * @param p [IN] - Exponent used for mod_exp * @param m [IN] - Modulus used for mod_exp * @param ctx [IN] - EVP context. * @param m_ctx [IN] - EVP context for Montgomery multiplication. * * description: * Overridden modular exponentiation function used in DSA. * ******************************************************************************/ int qat_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { int ret = 0, fallback = 0; DEBUG("- Started\n"); if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); } CRYPTO_QAT_LOG("AU - %s\n", __func__); ret = qat_mod_exp(r, a, p, m, &fallback); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); } else return ret; } /****************************************************************************** * function: * qat_dsa_do_sign(const unsigned char *dgst, int dlen, * DSA *dsa) * * description: * Generate DSA R and S Signatures. ******************************************************************************/ DSA_SIG *qat_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { BIGNUM *r = NULL, *s = NULL; BIGNUM *k = NULL; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *g = NULL; const BIGNUM *pub_key = NULL, *priv_key = NULL; BN_CTX *ctx = NULL; DSA_SIG *sig = NULL; CpaFlatBuffer *pResultR = NULL; CpaFlatBuffer *pResultS = NULL; int inst_num = QAT_INVALID_INSTANCE; CpaCyDsaRSSignOpData *opData = NULL; CpaBoolean bDsaSignStatus; CpaStatus status; size_t buflen; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); const DSA_METHOD *default_dsa_method = DSA_OpenSSL(); int i = 0, job_ret = 0, fallback = 0; thread_local_variables_t *tlv = NULL; int qat_svm = QAT_INSTANCE_ANY; DEBUG("QAT HW DSA Started\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(dlen <= 0)) { WARN("Invalid input param.\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_DLEN_INVALID); return NULL; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return DSA_meth_get_sign(default_dsa_method)(dgst, dlen, dsa); } if (unlikely(dsa == NULL || dgst == NULL)) { WARN("Either dsa %p or dgst %p are NULL\n", dsa, dgst); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_DSA_DGST_NULL); return NULL; } if (*dgst == 0) { DEBUG("- Received zero plaintext and Switched to software mode\n"); return DSA_meth_get_sign(default_dsa_method)(dgst, dlen, dsa); } DSA_get0_pqg(dsa, &p, &q, &g); if (p == NULL || q == NULL || g == NULL) { WARN("Either p %p, q %p, or g %p are NULL\n", p, q, g); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_P_Q_G_NULL); return sig; } i = BN_num_bits(q); /* * If the sizes of P and Q are not in the range supported by QAT engine * then fall back to software */ if (!dsa_range_check(BN_num_bits(p), i)) { if (default_dsa_method == NULL) { WARN("Failed to get default_dsa_method for bits p = %d & q = %d\n", BN_num_bits(p), i); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_SW_METHOD_NULL); return NULL; } return DSA_meth_get_sign(default_dsa_method)(dgst, dlen, dsa); } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); return DSA_meth_get_sign(default_dsa_method)(dgst, dlen, dsa); } else { QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); return NULL; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; opData = (CpaCyDsaRSSignOpData *) OPENSSL_zalloc(sizeof(CpaCyDsaRSSignOpData)); if (opData == NULL) { WARN("Failed to allocate memory for opData\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_OPDATA_MALLOC_FAILURE); return sig; } if ((ctx = BN_CTX_new()) == NULL) { WARN("Failed to allocate memory for ctx\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); if ((k = BN_CTX_get(ctx)) == NULL) { WARN("Failed to allocate k\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_K_ALLOCATE_FAILURE); goto err; } buflen = BN_num_bytes(q); if (dlen > buflen) /* * if the digest length is greater than the size of q use the * BN_num_bits(q) leftmost bits of the digest, see fips 186-3, * 4.2 */ dlen = buflen; #ifdef ENABLE_QAT_FIPS if (qat_fips_kat_test == 0) { do { if (!BN_rand_range(k, q)) { WARN("Failed to generate random number for the range %d\n", dlen); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_K_RAND_GENERATE_FAILURE); goto err; } } while (BN_is_zero(k)); } else { if (!BN_bin2bn(kvalue, sizeof(kvalue), k)) { WARN("Failure to get k value\n"); goto err; } } #else do { if (!BN_rand_range(k, q)) { WARN("Failed to generate random number for the range %d\n", dlen); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_K_RAND_GENERATE_FAILURE); goto err; } } while (BN_is_zero(k)); #endif pResultR = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (!pResultR) { WARN("Failed to allocate memory for pResultR\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_PRESULTR_MALLOC_FAILURE); goto err; } pResultR->pData = qat_mem_alloc(buflen, qat_svm, __FILE__, __LINE__); if (!pResultR->pData) { WARN("Failed to allocate memory for pResultR data\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_PRESULTR_PDATA_MALLOC_FAILURE); goto err; } pResultR->dataLenInBytes = (Cpa32U) buflen; pResultS = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (!pResultS) { WARN("Failed to allocate memory for pResultS\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_PRESULTS_MALLOC_FAILURE); goto err; } pResultS->pData = qat_mem_alloc(buflen, qat_svm,__FILE__, __LINE__); if (!pResultS->pData) { WARN("Failed to allocate memory for pResultS data\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_PRESULTS_PDATA_MALLOC_FAILURE); goto err; } pResultS->dataLenInBytes = (Cpa32U) buflen; DSA_get0_key(dsa, &pub_key, &priv_key); if (priv_key == NULL) { WARN("Unable to get private key\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_PRIV_KEY_NULL); goto err; } if ((qat_BN_to_FB(&(opData->P), p, qat_svm) != 1) || (qat_BN_to_FB(&(opData->Q), q, qat_svm) != 1) || (qat_BN_to_FB(&(opData->G), g, qat_svm) != 1) || (qat_BN_to_FB(&(opData->X), priv_key, qat_svm) != 1) || (qat_BN_to_FB(&(opData->K), k, qat_svm) != 1)) { WARN("Failed to convert p, q, g, priv_key or k to a flat buffer\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_P_Q_G_X_K_CONVERT_TO_FB_FAILURE); goto err; } opData->Z.pData = qat_mem_alloc(dlen, qat_svm,__FILE__, __LINE__); if (!opData->Z.pData) { WARN("Failed to allocate memory for opData pData\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_OPDATA_ZPDATA_MALLOC_FAILURE); goto err; } opData->Z.dataLenInBytes = (Cpa32U) dlen; memcpy(opData->Z.pData, dgst, dlen); sig = DSA_SIG_new(); if (sig == NULL) { WARN("Failed to allocate memory for sig\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, QAT_R_SIG_MALLOC_FAILURE); goto err; } r = BN_new(); s = BN_new(); /* NULL checking of r & s done in DSA_SIG_set0() */ if (DSA_SIG_set0(sig, r, s) == 0) { WARN("Unable to set r and s\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); goto err; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); DSA_SIG_free(sig); sig = NULL; goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); DSA_SIG_free(sig); sig = NULL; goto err; } } CRYPTO_QAT_LOG("AU - %s\n", __func__); do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); DSA_SIG_free(sig); sig = NULL; goto err; } CRYPTO_QAT_LOG("AU - %s\n", __func__); DUMP_DSA_SIGN(qat_instance_handles[inst_num], &op_done, opData, &bDsaSignStatus, pResultR, pResultS); status = cpaCyDsaSignRS(qat_instance_handles[inst_num], qat_dsaSignCallbackFn, &op_done, opData, &bDsaSignStatus, pResultR, pResultS); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); DSA_SIG_free(sig); sig = NULL; goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); DSA_SIG_free(sig); sig = NULL; goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_DSA_SIGN_OUTPUT(bDsaSignStatus, pResultR, pResultS); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DSA_DO_SIGN, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); DSA_SIG_free(sig); sig = NULL; goto err; } qat_cleanup_op_done(&op_done); /* Convert the flatbuffer results back to a BN */ BN_bin2bn(pResultR->pData, pResultR->dataLenInBytes, r); BN_bin2bn(pResultS->pData, pResultS->dataLenInBytes, s); err: if (pResultR) { QAT_MEM_FREE_FLATBUFF(*pResultR, qat_svm); OPENSSL_free(pResultR); } if (pResultS) { QAT_MEM_FREE_FLATBUFF(*pResultS, qat_svm); OPENSSL_free(pResultS); } if (opData) { QAT_MEM_FREE_FLATBUFF(opData->P, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->Q, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->G, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->Z, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->X, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->K, qat_svm); OPENSSL_free(opData); } if (ctx) { if (k) BN_clear(k); BN_CTX_end(ctx); BN_CTX_free(ctx); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return DSA_meth_get_sign(default_dsa_method)(dgst, dlen, dsa); } return sig; } /****************************************************************************** * function: * qat_dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, * BIGNUM **rp) * * description: * Wrapper around the default OpenSSL DSA dsa_sign_setup() function to avoid * a null function pointer. * See the OpenSSL documentation for parameters. ******************************************************************************/ int qat_dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { const DSA_METHOD *default_dsa_method = DSA_OpenSSL(); DEBUG("%s been called \n", __func__); if (unlikely(dsa == NULL || ctx_in == NULL || kinvp == NULL || rp == NULL)) { WARN("Invalid input param.\n"); QATerr(QAT_F_QAT_DSA_SIGN_SETUP, QAT_R_INPUT_PARAM_INVALID); return 0; } return DSA_meth_get_sign_setup(default_dsa_method)(dsa, ctx_in, kinvp, rp); } /****************************************************************************** * function: * qat_dsa_do_verify(const unsigned char *dgst, int dgst_len, * DSA_SIG *sig, DSA *dsa) * * description: * Verify DSA R and S Signatures. ******************************************************************************/ int qat_dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) { BN_CTX *ctx; const BIGNUM *r = NULL, *s = NULL; BIGNUM *z = NULL; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *g = NULL; const BIGNUM *pub_key = NULL, *priv_key = NULL; int ret = -1, i = 0, job_ret = 0, fallback = 0; int inst_num = QAT_INVALID_INSTANCE; CpaCyDsaVerifyOpData *opData = NULL; CpaBoolean bDsaVerifyStatus; CpaStatus status; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); const DSA_METHOD *default_dsa_method = DSA_OpenSSL(); thread_local_variables_t *tlv = NULL; int qat_svm = QAT_INSTANCE_ANY; DEBUG("QAT HW DSA Started\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(dgst_len <= 0)) { WARN("Invalid input param.\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_DGSTLEN_INVALID); return ret; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return DSA_meth_get_verify(default_dsa_method)(dgst, dgst_len, sig, dsa); } if (dsa == NULL || dgst == NULL || sig == NULL) { WARN("Either dsa = %p, dgst = %p or sig = %p are NULL\n", dsa, dgst, sig); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_DSA_DGST_SIG_NULL); return ret; } if (*dgst == 0) { DEBUG("- Received zero plaintext and Switched to software mode\n"); return DSA_meth_get_verify(default_dsa_method)(dgst, dgst_len, sig, dsa); } DSA_get0_pqg(dsa, &p, &q, &g); if (p == NULL || q == NULL || g == NULL) { WARN("Either p = %p, q = %p or g = %p are NULL\n", p, q, g); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_GET_PQG_FAILURE); return ret; } i = BN_num_bits(q); /* * If the sizes of P and Q are not in the range supported by QAT engine * then fall back to software */ if (!dsa_range_check(BN_num_bits(p), i)) { if (default_dsa_method == NULL) { WARN("Failed to get default_dsa_method for bits p = %d & q = %d\n", BN_num_bits(p), i); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_SW_METHOD_NULL); return ret; } return DSA_meth_get_verify(default_dsa_method)(dgst, dgst_len, sig, dsa); } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); return DSA_meth_get_verify(default_dsa_method)(dgst, dgst_len, sig, dsa); } else { QATerr(QAT_F_QAT_DSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); return ret; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; opData = (CpaCyDsaVerifyOpData *) OPENSSL_zalloc(sizeof(CpaCyDsaVerifyOpData)); if (opData == NULL) { WARN("Failed to allocate memory for opData\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_OPDATA_MALLOC_FAILURE); return ret; } if ((ctx = BN_CTX_new()) == NULL) { WARN("Failed to allocate memory for ctx\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); if ((z = BN_CTX_get(ctx)) == NULL) { WARN("Failed to allocate z\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_Z_ALLOCATE_FAILURE); goto err; } DSA_SIG_get0(sig, &r, &s); if (r == NULL || s == NULL) { WARN("Failed to get r or s\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_SIG_GET_R_S_FAILURE); goto err; } if (BN_is_zero(r) || BN_is_negative(r) || BN_ucmp(r, q) >= 0) { WARN("r and q not equal after compare\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_R_Q_COMPARE_FAILURE); goto err; } if (BN_is_zero(s) || BN_is_negative(s) || BN_ucmp(s, q) >= 0) { WARN("s and q not equal after compare\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_S_Q_COMPARE_FAILURE); goto err; } if (dgst_len > (i >> 3)) /* * if the digest length is greater than the size of q use the * BN_num_bits(q) leftmost bits of the digest, see fips 186-3, * 4.2 */ dgst_len = (i >> 3); if (BN_bin2bn(dgst, dgst_len, z) == NULL) { WARN("Failed to convert dgst to big number\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_DGST_BN_CONV_FAILURE); goto err; } DSA_get0_key(dsa, &pub_key, &priv_key); if (pub_key == NULL) { WARN("pub_key is NULL\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_PUB_KEY_NULL); goto err; } if ((qat_BN_to_FB(&(opData->P), p, qat_svm) != 1) || (qat_BN_to_FB(&(opData->Q), q, qat_svm) != 1) || (qat_BN_to_FB(&(opData->G), g, qat_svm) != 1) || (qat_BN_to_FB(&(opData->Y), pub_key, qat_svm) != 1) || (qat_BN_to_FB(&(opData->Z), z, qat_svm) != 1) || (qat_BN_to_FB(&(opData->R), r, qat_svm) != 1) || (qat_BN_to_FB(&(opData->S), s, qat_svm) != 1)) { WARN("Failed to convert p, q, g, pub_key, z, r or s to a flat buffer\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, QAT_R_P_Q_G_Y_Z_R_S_CONVERT_TO_FB_FAILURE); goto err; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_DSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("AU - %s\n", __func__); do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_DSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } CRYPTO_QAT_LOG("AU - %s\n", __func__); DUMP_DSA_VERIFY(qat_instance_handles[inst_num], &op_done, opData, &bDsaVerifyStatus); status = cpaCyDsaVerify(qat_instance_handles[inst_num], qat_dsaVerifyCallbackFn, &op_done, opData, &bDsaVerifyStatus); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_DSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_DSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("bDsaVerifyStatus = %u\n", bDsaVerifyStatus); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult == CPA_TRUE) ret = 1; else if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } qat_cleanup_op_done(&op_done); err: if (opData != NULL) { QAT_MEM_FREE_FLATBUFF(opData->P, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->Q, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->G, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->Y, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->Z, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->R, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->S, qat_svm); OPENSSL_free(opData); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return DSA_meth_get_verify(default_dsa_method)(dgst, dgst_len, sig, dsa); } return ret; } /****************************************************************************** * function: * qat_dsa_init(DSA *dsa) * * @param dsa [IN] - Pointer to a OpenSSL DSA struct. * * description: * Override DSA Init function. * Call SW Implementation to ensure caching flag gets set. * ******************************************************************************/ int qat_dsa_init(DSA *dsa) { return DSA_meth_get_init(DSA_OpenSSL())(dsa); } /****************************************************************************** * function: * qat_dsa_finish(DSA *dsa) * * @param dsa [IN] - Pointer to a OpenSSL DSA struct. * * description: * Override DSA Finish function. * Call SW Implementation to ensure cleanup of cached data. * ******************************************************************************/ int qat_dsa_finish(DSA *dsa) { return DSA_meth_get_finish(DSA_OpenSSL())(dsa); } #endif /* ENABLE_QAT_HW_DSA */ qatengine-1.9.0/qat_hw_dsa.h000066400000000000000000000053751500416242000157630ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * *==================================================================== */ /***************************************************************************** * @file qat_hw_dsa.h * * This file provides an interface for DSA operation * *****************************************************************************/ #ifndef QAT_HW_DSA_H # define QAT_HW_DSA_H # include /* Qat engine DSA methods declaration */ DSA_METHOD *qat_get_DSA_methods(void); void qat_free_DSA_methods(void); # ifndef DISABLE_QAT_HW_DSA int qat_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); DSA_SIG *qat_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); int qat_dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); int qat_dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); int qat_dsa_init(DSA *dsa); int qat_dsa_finish(DSA *dsa); # endif #endif /* QAT_HW_DSA_H */ qatengine-1.9.0/qat_hw_ec.c000066400000000000000000002464501500416242000155770ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_ec.c * * This file provides support for ECDH & ECDSA * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #ifdef QAT_BORINGSSL #include #include #endif /* QAT_BORINGSSL */ #include #include #include #include #include #include "cpa.h" #include "cpa_types.h" #ifdef QAT_BORINGSSL #include "icp_sal_poll.h" #endif #include "cpa_cy_ec.h" #include "cpa_cy_ecdsa.h" #ifdef ENABLE_QAT_HW_SM2 # include "cpa_cy_ecsm2.h" #endif #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_hw_asym_common.h" #include "qat_utils.h" #include "qat_hw_ec.h" #include "qat_evp.h" #if defined(ENABLE_QAT_SW_ECDH) || defined(ENABLE_QAT_SW_ECDSA) # include "qat_sw_ec.h" #endif # define QAT_EC_MIN_RANGE 256 #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" # ifdef ENABLE_QAT_HW_ECDSA extern int qat_fips_kat_test; static const unsigned char kvalue[] = { 0x23, 0xAF, 0x40, 0x74, 0xC9, 0x0A, 0x02, 0xB3, 0xE6, 0x1D, 0x28, 0x6D, 0x5C, 0x87, 0xF4, 0x25, 0xE6, 0xBD, 0xD8, 0x1B }; # endif #endif CpaCyEcFieldType qat_get_field_type(const EC_GROUP *group) { /* For BoringSSL,EC_METHOD_get_field_type only support NID_X9_62_prime_field * and EC_METHOD_get_field_type return NID_X9_62_prime_field directly */ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) return CPA_CY_EC_FIELD_TYPE_PRIME; else return CPA_CY_EC_FIELD_TYPE_BINARY; } #if defined(QAT20_OOT) || defined(QAT_HW_INTREE) int qat_get_curve(CpaCyEcFieldType fieldType) { if (fieldType == CPA_CY_EC_FIELD_TYPE_PRIME) return CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_PRIME; else if (fieldType == CPA_CY_EC_FIELD_TYPE_BINARY) return CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_BINARY; else return CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_KOBLITZ_BINARY; } #endif #ifdef ENABLE_QAT_HW_ECDH /* Callback to indicate QAT completion of EC point multiply */ static void qat_ecCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean multiplyStatus, CpaFlatBuffer * pXk, CpaFlatBuffer * pYk) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, multiplyStatus); } int qat_ecdh_compute_key(unsigned char **outX, size_t *outlenX, unsigned char **outY, size_t *outlenY, const EC_POINT *pub_key, const EC_KEY *ecdh, int *fallback) { BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *h = NULL; const BIGNUM *priv_key = NULL; const EC_GROUP *group = NULL; int ret = 0, job_ret = 0; size_t buflen = 0; int inst_num = QAT_INVALID_INSTANCE; BIGNUM *xP = NULL, *yP = NULL; CpaBoolean bEcStatus = 0; CpaFlatBuffer *pResultX = NULL; CpaFlatBuffer *pResultY = NULL; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); CpaStatus status = CPA_STATUS_FAIL; op_done_t op_done; thread_local_variables_t *tlv = NULL; int curve_name; int sm2_flag = 0; ret = sm2_flag; int qat_svm = QAT_INSTANCE_ANY; DEBUG("QAT HW ECDH Started\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif START_RDTSC(&qat_hw_ecdh_derive_req_prepare); if (unlikely(ecdh == NULL || ((priv_key = EC_KEY_get0_private_key(ecdh)) == NULL) || pub_key == NULL)) { WARN("Either ecdh or priv_key or pub_key is NULL\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL); return ret; } if (fallback == NULL) { WARN("NULL fallback pointer passed in.\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_FALLBACK_POINTER_NULL); return ret; } if ((outX != NULL && outlenX == NULL) || (outY != NULL && outlenY == NULL)) { WARN("Either outX, outY, outlenX or outlenY are NULL\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_OUTX_OUTY_LEN_NULL); return ret; } if ((group = EC_KEY_get0_group(ecdh)) == NULL) { WARN("group is NULL\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_GET_GROUP_FAILURE); return ret; } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; return ret; } else { QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); return ret; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; curve_name = EC_GROUP_get_curve_name(group); # if defined(QAT20_OOT) || defined(QAT_HW_INTREE) # ifdef ENABLE_QAT_HW_SM2 CpaCyEcsm2PointMultiplyOpData *psm2OpData = NULL; # endif CpaCyEcGenericPointMultiplyOpData *pOpData = NULL; # else CpaCyEcPointMultiplyOpData *opData = NULL; # endif # if defined(QAT20_OOT) || defined(QAT_HW_INTREE) # ifdef ENABLE_QAT_HW_SM2 if (curve_name == NID_sm2 || curve_name == NID_sm3) { psm2OpData = (CpaCyEcsm2PointMultiplyOpData *) OPENSSL_zalloc(sizeof(CpaCyEcsm2PointMultiplyOpData)); if (psm2OpData == NULL) { WARN("Failure to allocate psm2OpData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_POPDATA_MALLOC_FAILURE); return ret; } sm2_flag = 1; psm2OpData->k.pData = NULL; psm2OpData->x.pData = NULL; psm2OpData->y.pData = NULL; } # endif if (!sm2_flag) { pOpData = (CpaCyEcGenericPointMultiplyOpData *) OPENSSL_zalloc(sizeof(CpaCyEcGenericPointMultiplyOpData)); if (pOpData == NULL) { WARN("Failure to allocate pOpData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_POPDATA_MALLOC_FAILURE); return ret; } pOpData->pCurve = (CpaCyEcCurve *) qat_mem_alloc(sizeof(CpaCyEcCurve), qat_svm, __FILE__, __LINE__); if (pOpData->pCurve == NULL) { WARN("Failure to allocate pOpData->pCurve\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_POPDATA_PCURVE_MALLOC_FAILURE); OPENSSL_free(pOpData); return ret; } if (outY != NULL) pOpData->generator = CPA_TRUE; else pOpData->generator = CPA_FALSE; pOpData->k.pData = NULL; pOpData->xP.pData = NULL; pOpData->yP.pData = NULL; pOpData->pCurve->parameters.weierstrassParameters.a.pData = NULL; pOpData->pCurve->parameters.weierstrassParameters.b.pData = NULL; pOpData->pCurve->parameters.weierstrassParameters.p.pData = NULL; pOpData->pCurve->parameters.weierstrassParameters.h.pData = NULL; pOpData->pCurve->parameters.weierstrassParameters.h.dataLenInBytes = 0; } # else opData = (CpaCyEcPointMultiplyOpData *) OPENSSL_zalloc(sizeof(CpaCyEcPointMultiplyOpData)); if (opData == NULL) { WARN("Failure to allocate opData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_OPDATA_MALLOC_FAILURE); return ret; } opData->k.pData = NULL; opData->xg.pData = NULL; opData->yg.pData = NULL; opData->a.pData = NULL; opData->b.pData = NULL; opData->q.pData = NULL; opData->h.pData = NULL; opData->h.dataLenInBytes = 0; # endif /* Populate the parameters required for EC point multiply */ if ((ctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); p = BN_CTX_get(ctx); a = BN_CTX_get(ctx); b = BN_CTX_get(ctx); h = BN_CTX_get(ctx); xP = BN_CTX_get(ctx); yP = BN_CTX_get(ctx); if (yP == NULL) { WARN("Failed to allocate p, a, b, xP or yP\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_P_A_B_XP_YP_MALLOC_FAILURE); goto err; } buflen = (EC_GROUP_get_degree(group) + 7) / 8; pResultX = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (pResultX == NULL) { WARN("Failure to allocate pResultX\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRESULTX_MALLOC_FAILURE); goto err; } if (qat_svm && outX != NULL) { *outlenX = (Cpa32U) buflen; *outX = OPENSSL_zalloc(*outlenX); pResultX->pData = (Cpa8U*) *outX; } else { pResultX->pData = qat_mem_alloc(buflen, qat_svm, __FILE__, __LINE__); } if (pResultX->pData == NULL) { WARN("Failure to allocate pResultX->pData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRESULTX_PDATA_MALLOC_FAILURE); goto err; } pResultX->dataLenInBytes = (Cpa32U) buflen; pResultY = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (!pResultY) { WARN("Failure to allocate pResultY\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRESULTY_MALLOC_FAILURE); goto err; } if (qat_svm && outY != NULL) { *outY = OPENSSL_zalloc(*outlenY); pResultY->pData = (Cpa8U*) *outY; } else { pResultY->pData = qat_mem_alloc(buflen, qat_svm, __FILE__, __LINE__); } if (pResultY->pData == NULL) { WARN("Failure to allocate pResultY->pData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRESULTY_PDATA_MALLOC_FAILURE); goto err; } pResultY->dataLenInBytes = (Cpa32U) buflen; if (!EC_GROUP_get_cofactor(group, h, ctx)) { WARN("Failure in get cofactor\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_GET_COFACTOR_FAILURE); goto err; } if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { WARN("Failure to get the curve\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } if (!EC_POINT_get_affine_coordinates(group, pub_key, xP, yP, ctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } # if defined(QAT20_OOT) || defined(QAT_HW_INTREE) # ifdef ENABLE_QAT_HW_SM2 if (curve_name == NID_sm2 || curve_name == NID_sm3) { psm2OpData->fieldType = qat_get_field_type(group); if ((qat_BN_to_FB(&(psm2OpData->k), (BIGNUM *)priv_key, qat_svm) != 1) || (qat_BN_to_FB(&(psm2OpData->x), xP, qat_svm) != 1) || (qat_BN_to_FB(&(psm2OpData->y), yP, qat_svm) != 1)) { WARN("Failure to convert priv_key, x, y to flatbuffer\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE); goto err; } } # endif if (!sm2_flag) { pOpData->pCurve->parameters.weierstrassParameters.fieldType = qat_get_field_type(group); pOpData->pCurve->curveType = qat_get_curve(pOpData->pCurve->parameters.weierstrassParameters.fieldType); if ((qat_BN_to_FB(&(pOpData->k), (BIGNUM *)priv_key, qat_svm) != 1) || (qat_BN_to_FB(&(pOpData->xP), xP, qat_svm) != 1) || (qat_BN_to_FB(&(pOpData->yP), yP, qat_svm) != 1) || (qat_BN_to_FB(&(pOpData->pCurve->parameters.weierstrassParameters.a), a, qat_svm) != 1) || (qat_BN_to_FB(&(pOpData->pCurve->parameters.weierstrassParameters.b), b, qat_svm) != 1) || (qat_BN_to_FB(&(pOpData->pCurve->parameters.weierstrassParameters.p), p, qat_svm) != 1)) { WARN("Failure to convert priv_key, xP, yP, a, b or p to flatbuffer\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRIV_KEY_XP_YP_A_B_P_CONVERT_TO_FB_FAILURE); goto err; } /* Pass Co-factor to Opdata */ if (pOpData->pCurve->parameters.weierstrassParameters.fieldType == CPA_CY_EC_FIELD_TYPE_PRIME) { if (qat_BN_to_FB(&(pOpData->pCurve->parameters.weierstrassParameters.h), h, qat_svm) != 1) { WARN("Failure to convert h to flatbuffer\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_H_CONVERT_TO_FB_FAILURE); goto err; } } /* * This is a special handling required for curves with 'a' co-efficient * of 0. The translation to a flatbuffer results in a zero sized field * but the Quickassist API expects a flatbuffer of size 1 with a value * of zero. As a special case we will create that manually. */ if (pOpData->pCurve->parameters.weierstrassParameters.a.pData == NULL && pOpData->pCurve->parameters.weierstrassParameters.a.dataLenInBytes == 0) { pOpData->pCurve->parameters.weierstrassParameters.a.pData = qat_mem_alloc(1, qat_svm, __FILE__, __LINE__); if (pOpData->pCurve->parameters.weierstrassParameters.a.pData == NULL) { WARN("Failure to allocate pOpData->pCurve->parameters.weierstrassParameters.a.pData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_POPDATA_A_PDATA_MALLOC_FAILURE); goto err; } pOpData->pCurve->parameters.weierstrassParameters.a.dataLenInBytes = 1; pOpData->pCurve->parameters.weierstrassParameters.a.pData[0] = 0; } } # else opData->fieldType = qat_get_field_type(group); if ((qat_BN_to_FB(&(opData->k), (BIGNUM *)priv_key, qat_svm) != 1) || (qat_BN_to_FB(&(opData->xg), xP, qat_svm) != 1) || (qat_BN_to_FB(&(opData->yg), yP, qat_svm) != 1) || (qat_BN_to_FB(&(opData->a), a, qat_svm) != 1) || (qat_BN_to_FB(&(opData->b), b, qat_svm) != 1) || (qat_BN_to_FB(&(opData->q), p, qat_svm) != 1)) { WARN("Failure to convert priv_key, xg, yg, a, b or p to flatbuffer\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRIV_KEY_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE); goto err; } /* Pass Co-factor to Opdata */ if (opData->fieldType == CPA_CY_EC_FIELD_TYPE_PRIME) { if (qat_BN_to_FB(&(opData->h), h, qat_svm) != 1) { WARN("Failure to convert h to flatbuffer\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_H_CONVERT_TO_FB_FAILURE); goto err; } } /* * This is a special handling required for curves with 'a' co-efficient * of 0. The translation to a flatbuffer results in a zero sized field * but the Quickassist API expects a flatbuffer of size 1 with a value * of zero. As a special case we will create that manually. */ if (opData->a.pData == NULL && opData->a.dataLenInBytes == 0) { opData->a.pData = qat_mem_alloc(1, qat_svm,__FILE__, __LINE__); if (opData->a.pData == NULL) { WARN("Failure to allocate opData->a.pData\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_OPDATA_A_PDATA_MALLOC_FAILURE); goto err; } opData->a.dataLenInBytes = 1; opData->a.pData[0] = 0; } # endif tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } #ifdef QAT_BORINGSSL qat_init_op_done(&op_done, qat_svm); #else qat_init_op_done(&op_done); #endif if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("KX - %s\n", __func__); STOP_RDTSC(&qat_hw_ecdh_derive_req_prepare, 1, "[QAT HW ECDH: prepare]"); /* Invoke the crypto engine API for EC Point Multiply */ do { START_RDTSC(&qat_hw_ecdh_derive_req_submit); if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } CRYPTO_QAT_LOG("KX - %s\n", __func__); # if defined(QAT20_OOT) || defined(QAT_HW_INTREE) # ifdef ENABLE_QAT_HW_SM2 if (curve_name == NID_sm2 || curve_name == NID_sm3) { DUMP_EC_SM2_POINT_MULTIPLY(qat_instance_handles[inst_num], psm2OpData, pResultX, pResultY); status = cpaCyEcsm2PointMultiply(qat_instance_handles[inst_num], qat_ecCallbackFn, &op_done, psm2OpData, &bEcStatus, pResultX, pResultY); } # endif if (!sm2_flag) { DUMP_EC_GENERIC_POINT_MULTIPLY(qat_instance_handles[inst_num], pOpData, pResultX, pResultY); status = cpaCyEcGenericPointMultiply(qat_instance_handles[inst_num], qat_ecCallbackFn, &op_done, pOpData, &bEcStatus, pResultX, pResultY); } # else DUMP_EC_POINT_MULTIPLY(qat_instance_handles[inst_num], opData, pResultX, pResultY); status = cpaCyEcPointMultiply(qat_instance_handles[inst_num], qat_ecCallbackFn, &op_done, opData, &bEcStatus, pResultX, pResultY); # endif STOP_RDTSC(&qat_hw_ecdh_derive_req_submit, 1, "[QAT HW ECDH: submit]"); if (status == CPA_STATUS_RETRY) { if (qat_ecdh_coexist && ((curve_name == NID_X9_62_prime256v1) || (curve_name == NID_secp384r1))) { START_RDTSC(&qat_hw_ecdh_derive_req_retry); if (op_done.job) { DEBUG("cpaCyEcPointMultiply Retry \n"); if (outY) { /* key generation */ ++num_ecdh_keygen_retry; qat_sw_ecdh_keygen_req += QAT_SW_SWITCH_MB8; } else { /* compute key */ ++num_ecdh_derive_retry; qat_sw_ecdh_derive_req += QAT_SW_SWITCH_MB8; } *fallback = 1; qat_cleanup_op_done(&op_done); STOP_RDTSC(&qat_hw_ecdh_derive_req_retry, 1, "[QAT HW ECDH: retry]"); goto err; } } else { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } } while (status == CPA_STATUS_RETRY ); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); *fallback = 1; } else { QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } if (qat_ecdh_coexist) { if (outY) ++num_ecdh_hw_keygen_reqs; else ++num_ecdh_hw_derive_reqs; } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_EC_POINT_MULTIPLY_OUTPUT(bEcStatus, pResultX, pResultY); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of request failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); /* KDF, is done in the caller now just copy out bytes */ if (outX != NULL && !qat_svm) { *outlenX = pResultX->dataLenInBytes; *outX = OPENSSL_zalloc(*outlenX); if (*outX == NULL) { WARN("Failure to allocate outX\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_OUTX_MALLOC_FAILURE); goto err; } if (unlikely(pResultX->pData == NULL)) { WARN("pResultX->pData is NULL\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } memcpy(*outX, pResultX->pData, *outlenX); } if (outY != NULL && !qat_svm) { if (*outlenY != pResultY->dataLenInBytes) { WARN("Failed length check of pResultY->dataLenInBytes\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_PRESULTY_LENGTH_CHECK_FAILURE); goto err; } *outY = OPENSSL_zalloc(*outlenY); if (*outY == NULL) { WARN("Failure to allocate outY\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, QAT_R_OUTY_MALLOC_FAILURE); goto err; } if (unlikely(pResultY->pData == NULL)) { WARN("pResultY->pData is NULL\n"); QATerr(QAT_F_QAT_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } memcpy(*outY, pResultY->pData, pResultY->dataLenInBytes); } ret = *outlenX; err: START_RDTSC(&qat_hw_ecdh_derive_req_cleanup); if (pResultX) { if (!qat_svm) qaeCryptoMemFree(pResultX->pData); OPENSSL_free(pResultX); } if (pResultY) { if (!qat_svm) qaeCryptoMemFree(pResultY->pData); OPENSSL_free(pResultY); } # if defined(QAT20_OOT) || defined(QAT_HW_INTREE) # ifdef ENABLE_QAT_HW_SM2 if (curve_name == NID_sm2 || curve_name == NID_sm3) { if (psm2OpData) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(psm2OpData->k, qat_svm); QAT_MEM_FREE_FLATBUFF(psm2OpData->x, qat_svm); QAT_MEM_FREE_FLATBUFF(psm2OpData->y, qat_svm); OPENSSL_free(psm2OpData); } } # endif if (!sm2_flag) { if (pOpData) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(pOpData->k, qat_svm); QAT_MEM_FREE_FLATBUFF(pOpData->xP, qat_svm); QAT_MEM_FREE_FLATBUFF(pOpData->yP, qat_svm); QAT_MEM_FREE_FLATBUFF(pOpData->pCurve->parameters.weierstrassParameters.a, qat_svm); QAT_MEM_FREE_FLATBUFF(pOpData->pCurve->parameters.weierstrassParameters.b, qat_svm); QAT_MEM_FREE_FLATBUFF(pOpData->pCurve->parameters.weierstrassParameters.p, qat_svm); QAT_MEM_FREE_FLATBUFF(pOpData->pCurve->parameters.weierstrassParameters.h, qat_svm); QAT_MEM_FREE_BUFF(pOpData->pCurve, qat_svm); OPENSSL_free(pOpData); } } # else if (opData) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->k, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->xg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->yg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->a, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->b, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->q, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->h, qat_svm); OPENSSL_free(opData); } # endif if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } STOP_RDTSC(&qat_hw_ecdh_derive_req_cleanup, 1, "[QAT HW ECDH: cleanup]"); DEBUG("- Finished\n"); return ret; } int qat_engine_ecdh_compute_key(unsigned char **out, size_t *outlen, const EC_POINT *pub_key, const EC_KEY *ecdh) { int fallback = 0, ret = 0; PFUNC_COMP_KEY comp_key_pfunc = NULL; const EC_GROUP *group = NULL; #ifndef QAT_INSECURE_ALGO int bitlen = 0; #endif DEBUG("QAT HW ECDH Started\n"); EC_KEY_METHOD_get_compute_key((EC_KEY_METHOD *)EC_KEY_OpenSSL(), &comp_key_pfunc); if (comp_key_pfunc == NULL) { WARN("comp_key_pfunc is NULL\n"); QATerr(QAT_F_QAT_ENGINE_ECDH_COMPUTE_KEY, QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL); return ret; } if (ecdh == NULL || (EC_KEY_get0_private_key(ecdh) == NULL)) { WARN("Either ecdh or priv_key is NULL\n"); QATerr(QAT_F_QAT_ENGINE_ECDH_COMPUTE_KEY, QAT_R_ECDH_PRIVATE_KEY_NULL); return ret; } if ((group = EC_KEY_get0_group(ecdh)) == NULL) { WARN("group is NULL\n"); QATerr(QAT_F_QAT_ENGINE_ECDH_COMPUTE_KEY, QAT_R_GET_GROUP_FAILURE); return ret; } if (qat_sw_ecdh_derive_req > 0 || qat_get_qat_offload_disabled()) { fallback = 1; goto exit; } #ifndef QAT_INSECURE_ALGO /* Bits < 256 is not supported in QAT_HW */ bitlen = EC_GROUP_order_bits(group); if (bitlen < QAT_EC_MIN_RANGE) { DEBUG("Curve-Bitlen %d not supported! Using OPENSSL_SW\n", bitlen); fallback = 1; goto exit; } #endif ret = qat_ecdh_compute_key(out, outlen, NULL, NULL, pub_key, ecdh, &fallback); exit: if (fallback == 1) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef ENABLE_QAT_SW_ECDH int curve_name = EC_GROUP_get_curve_name(group); if (qat_ecdh_coexist && ((curve_name == NID_X9_62_prime256v1) || (curve_name == NID_secp384r1))) { DEBUG("- Switched to QAT_SW mode\n"); if (qat_sw_ecdh_derive_req > 0) --qat_sw_ecdh_derive_req; return mb_ecdh_compute_key(out, outlen, pub_key, ecdh); } #endif WARN("- Fallback to software mode.\n"); return (*comp_key_pfunc)(out, outlen, pub_key, ecdh); } DEBUG("- Finished\n"); return ret; } int qat_ecdh_generate_key(EC_KEY *ecdh) { int ok = 0, alloc_priv = 0, alloc_pub = 0; int field_size = 0, fallback = 0; BN_CTX *ctx = NULL; BIGNUM *priv_key = NULL, *order = NULL, *x_bn = NULL, *y_bn = NULL, *tx_bn = NULL, *ty_bn = NULL; EC_POINT *pub_key = NULL; const EC_POINT *gen; const EC_GROUP *group = NULL; unsigned char *temp_xbuf = NULL; unsigned char *temp_ybuf = NULL; size_t temp_xfield_size = 0; size_t temp_yfield_size = 0; PFUNC_GEN_KEY gen_key_pfunc = NULL; #ifndef QAT_INSECURE_ALGO int bitlen = 0; #endif DEBUG("QAT HW ECDH Started\n"); EC_KEY_METHOD_get_keygen((EC_KEY_METHOD *) EC_KEY_OpenSSL(), &gen_key_pfunc); if (gen_key_pfunc == NULL) { WARN("get keygen failed\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_SW_GET_KEYGEN_PFUNC_NULL); return 0; } if (unlikely(ecdh == NULL || ((group = EC_KEY_get0_group(ecdh)) == NULL))) { WARN("Either ecdh or group are NULL\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_ECDH_GROUP_NULL); return 0; } if (qat_sw_ecdh_keygen_req > 0 || qat_get_qat_offload_disabled()) { fallback = 1; goto exit; } #ifndef QAT_INSECURE_ALGO /* Bits < 256 is not supported in QAT_HW */ bitlen = EC_GROUP_order_bits(group); if (bitlen < QAT_EC_MIN_RANGE) { DEBUG("Curve-Bitlen %d not supported! Using OPENSSL_SW\n", bitlen); fallback = 1; goto exit; } #endif if ((ctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); if ((order = BN_CTX_get(ctx)) == NULL) { WARN("Failure to allocate order\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_ORDER_MALLOC_FAILURE); goto err; } if ((priv_key = (BIGNUM *)EC_KEY_get0_private_key(ecdh)) == NULL) { priv_key = BN_new(); if (priv_key == NULL) { WARN("Failure to get priv_key\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_GET_PRIV_KEY_FAILURE); goto err; } alloc_priv = 1; } if (!EC_GROUP_get_order(group, order, ctx)) { WARN("Failure to retrieve order\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_RETRIEVE_ORDER_FAILURE); goto err; } do if (!BN_rand_range(priv_key, order)) { WARN("Failure to generate random value\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE); goto err; } while (BN_is_zero(priv_key)) ; if (alloc_priv) { if (!EC_KEY_set_private_key(ecdh, priv_key)) { WARN("Failure to set private key\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_SET_PRIV_KEY_FAILURE); goto err; } } if ((pub_key = (EC_POINT *)EC_KEY_get0_public_key(ecdh)) == NULL) { pub_key = EC_POINT_new(group); if (pub_key == NULL) { WARN("Failure to allocate pub_key\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_PUB_KEY_MALLOC_FAILURE); goto err; } alloc_pub = 1; } field_size = EC_GROUP_get_degree(group); if (field_size <= 0) { WARN("invalid field_size: %d\n", field_size); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_FIELD_SIZE_INVALID); goto err; } gen = EC_GROUP_get0_generator(group); temp_xfield_size = temp_yfield_size = (field_size + 7) / 8; if ((qat_ecdh_compute_key(&temp_xbuf, &temp_xfield_size, &temp_ybuf, &temp_yfield_size, gen, ecdh, &fallback) <= 0) || (fallback == 1)) { /* * No QATerr is raised here because errors are already handled in * qat_ecdh_compute_key() */ goto err; } x_bn = BN_CTX_get(ctx); y_bn = BN_CTX_get(ctx); tx_bn = BN_CTX_get(ctx); ty_bn = BN_CTX_get(ctx); if (ty_bn == NULL) { WARN("Failure to allocate ctx x_bn, y_bn, tx_bn or ty_bn\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_X_Y_TX_TY_BN_MALLOC_FAILURE); goto err; } x_bn = BN_bin2bn(temp_xbuf, temp_xfield_size, x_bn); y_bn = BN_bin2bn(temp_ybuf, temp_yfield_size, y_bn); if (!EC_POINT_set_affine_coordinates(group, pub_key, x_bn, y_bn, ctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_ECDH_SET_AFFINE_COORD_FAILED); goto err; } if (!EC_POINT_get_affine_coordinates(group, pub_key, tx_bn, ty_bn, ctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, QAT_R_ECDH_GET_AFFINE_COORD_FAILED); goto err; } /* * Check if retrieved coordinates match originals: if not values are * out of range. */ if (BN_cmp(x_bn, tx_bn) || BN_cmp(y_bn, ty_bn)) { WARN("Retrieved coordinates do not match the originals\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); goto err; } if (!EC_KEY_set_public_key(ecdh, pub_key)) { WARN("Error setting pub_key\n"); QATerr(QAT_F_QAT_ECDH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); goto err; } ok = 1; err: if (alloc_pub) EC_POINT_free(pub_key); if (alloc_priv) BN_clear_free(priv_key); if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (temp_xbuf != NULL) OPENSSL_free(temp_xbuf); if (temp_ybuf != NULL) OPENSSL_free(temp_ybuf); DEBUG("- Finished\n"); exit: if (fallback == 1) { #ifdef ENABLE_QAT_SW_ECDH int curve_name = EC_GROUP_get_curve_name(group); if (qat_ecdh_coexist && ((curve_name == NID_X9_62_prime256v1) || (curve_name == NID_secp384r1))) { DEBUG("- Switched to QAT_SW mode\n"); if (qat_sw_ecdh_keygen_req > 0) --qat_sw_ecdh_keygen_req; return mb_ecdh_generate_key(ecdh); } #endif DEBUG("- Switched to software mode\n"); return (*gen_key_pfunc)(ecdh); } return ok; } #endif /* #ifdef ENABLE_QAT_HW_ECDH */ #ifdef ENABLE_QAT_HW_ECDSA #ifndef QAT_BORINGSSL /* Callback to indicate QAT completion of ECDSA Sign */ static void qat_ecdsaSignCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bEcdsaSignStatus, CpaFlatBuffer * pResultR, CpaFlatBuffer * pResultS) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, bEcdsaSignStatus); } #else static void qat_ecdsaSignCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bEcdsaSignStatus, CpaFlatBuffer * pResultR, CpaFlatBuffer * pResultS) { CpaBufferList pBuffer; CpaFlatBuffer *ret_sig = NULL; ECDSA_SIG *s = NULL; size_t bytes_len = 0; pBuffer.pBuffers = NULL; op_done_t *opDone = NULL; int inst_num = QAT_INVALID_INSTANCE; int qat_svm = QAT_INSTANCE_ANY; if (!bEcdsaSignStatus) { WARN("ECDSA sign failed, status %d verifyResult %d\n", status, bEcdsaSignStatus); goto err; } opDone = (op_done_t *)pCallbackTag; if (unlikely(opDone == NULL)) { WARN("opDone is empty in ECDSA callback\n"); goto err; } /* Sync mode */ if (!opDone->job) { return qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, bEcdsaSignStatus); } /* Async mode */ if (!opDone->job->waitctx || !opDone->job->waitctx->data) { WARN("Async job context or data buffer is empty\n"); goto err; } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); } goto err; } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; ret_sig = (CpaFlatBuffer *)(opDone->job->waitctx->data); pBuffer.pBuffers = ret_sig; s = ECDSA_SIG_new(); if (!s) { WARN("Failure to allocate ECDSA_SIG in ECDSA callback\n"); goto err; } BN_bin2bn(pResultR->pData, pResultR->dataLenInBytes, s->r); BN_bin2bn(pResultS->pData, pResultS->dataLenInBytes, s->s); CBB cbb; CBB_zero(&cbb); if (!CBB_init_fixed(&cbb, ret_sig->pData, ret_sig->dataLenInBytes) || !ECDSA_SIG_marshal(&cbb, s) || !CBB_finish(&cbb, NULL, &bytes_len)) { CBB_cleanup(&cbb); } ret_sig->dataLenInBytes = bytes_len; err: if (s) ECDSA_SIG_free(s); if (pResultR) { QAT_MEM_FREE_FLATBUFF(*pResultR, qat_svm); OPENSSL_free(pResultR); } if (pResultS) { QAT_MEM_FREE_FLATBUFF(*pResultS, qat_svm); OPENSSL_free(pResultS); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, &pBuffer, bEcdsaSignStatus); } static void ec_decrypt_op_buf_free(CpaCyEcdsaSignRSOpData * opData, CpaFlatBuffer* out_buf) { int inst_num = QAT_INVALID_INSTANCE; int qat_svm = QAT_INSTANCE_ANY; if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); } } else qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (out_buf) { if (out_buf->pData) { qaeCryptoMemFreeNonZero(out_buf->pData); } OPENSSL_free(out_buf); } if (opData) { QAT_MEM_FREE_FLATBUFF(opData->n, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->m, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->xg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->yg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->a, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->b, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->q, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->k, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->d, qat_svm); OPENSSL_free(opData); } } #endif /* QAT_BORINGSSL */ /* Callback to indicate QAT completion of ECDSA Verify */ static void qat_ecdsaVerifyCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bEcdsaVerifyStatus) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, bEcdsaVerifyStatus); } #ifndef QAT_BORINGSSL int qat_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) { ECDSA_SIG *s; #ifdef ENABLE_QAT_SW_ECDSA const EC_GROUP *group = NULL; int curve_name; #endif if (unlikely(dgst == NULL || eckey == NULL || dlen <= 0)) { /* Check these input params before passing to * RAND_seed(). Rest of the input params. are * checked by qat_ecdsa_do_sign(). */ WARN("Invalid input param.\n"); if (siglen != NULL) *siglen = 0; QATerr(QAT_F_QAT_ECDSA_SIGN, QAT_R_INPUT_PARAM_INVALID); return 0; } #ifdef ENABLE_QAT_SW_ECDSA group = EC_KEY_get0_group(eckey); if(!group) { WARN("Failed to get the group from eckey.\n"); QATerr(QAT_F_QAT_ECDSA_SIGN, QAT_R_GROUP_NULL); return 0; } curve_name = EC_GROUP_get_curve_name(group); if (qat_ecdsa_coexist) { /* Use QAT SW if the curve is P256 or QAT device not enough.*/ if (curve_name == NID_X9_62_prime256v1 || qat_get_qat_offload_disabled()) { return mb_ecdsa_sign(type, dgst, dlen, sig, siglen, kinv, r, eckey); } if ((qat_sw_ecdsa_sign_req > 0) && (curve_name == NID_secp384r1)) { --qat_sw_ecdsa_sign_req; return mb_ecdsa_sign(type, dgst, dlen, sig, siglen, kinv, r, eckey); } } #endif s = qat_ecdsa_do_sign(dgst, dlen, kinv, r, eckey); if (s == NULL) { #ifdef ENABLE_QAT_SW_ECDSA /* Switch to QAT_SW only for P384 curve. */ if (qat_ecdsa_coexist && (curve_name == NID_secp384r1)) { --qat_sw_ecdsa_sign_req; return mb_ecdsa_sign(type, dgst, dlen, sig, siglen, kinv, r, eckey); } #endif WARN("Error ECDSA Sign Operation Failed\n"); if (siglen != NULL) *siglen = 0; QATerr(QAT_F_QAT_ECDSA_SIGN, QAT_R_QAT_ECDSA_DO_SIGN_FAIL); return 0; } *siglen = i2d_ECDSA_SIG(s, &sig); ECDSA_SIG_free(s); return 1; } #endif /* QAT_BORINGSSL */ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { int ok = 0, i, job_ret = 0, fallback = 0; BIGNUM *m = NULL, *order = NULL; BN_CTX *ctx = NULL; const EC_GROUP *group = NULL; ECDSA_SIG *ret = NULL; BIGNUM *ecdsa_sig_r = NULL, *ecdsa_sig_s = NULL; const BIGNUM *priv_key = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *k = NULL; BIGNUM *xg = NULL, *yg = NULL; const EC_POINT *pub_key = NULL; PFUNC_SIGN_SIG sign_sig_pfunc = NULL; CpaFlatBuffer *pResultR = NULL; CpaFlatBuffer *pResultS = NULL; #ifdef QAT_BORINGSSL CpaFlatBuffer *ret_sig = NULL; op_done_t *op_done_bssl = NULL; #endif /* QAT_BORINGSSL */ int inst_num = QAT_INVALID_INSTANCE; CpaCyEcdsaSignRSOpData *opData = NULL; CpaBoolean bEcdsaSignStatus = 0; CpaStatus status = CPA_STATUS_FAIL; size_t buflen = 0; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); const EC_POINT *ec_point = NULL; thread_local_variables_t *tlv = NULL; int curve_name; int qat_svm = QAT_INSTANCE_ANY; #ifndef QAT_INSECURE_ALGO int bitlen = 0; #endif #ifdef ENABLE_QAT_HW_KPT if (eckey && qat_check_ec_wpk(eckey)) { if (is_kpt_mode()) { DEBUG("Run the qat_ecdsa_do_sign in KPT mode.\n"); return qat_hw_kpt_ecdsa_do_sign(dgst, dgst_len, in_kinv, in_r, eckey); } else { WARN("Use the WPK in Non-KPT mode, return failed.\n"); return NULL; } } #endif DEBUG("QAT HW ECDSA Started\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif START_RDTSC(&qat_hw_ecdsa_sign_req_prepare); if (unlikely(dgst == NULL || dgst_len <= 0 || eckey == NULL)) { WARN("Invalid input param.\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_INPUT_PARAM_INVALID); return NULL; } EC_KEY_METHOD_get_sign((EC_KEY_METHOD *) EC_KEY_OpenSSL(), NULL, NULL, &sign_sig_pfunc); if (sign_sig_pfunc == NULL) { WARN("sign_sig_pfunc is NULL\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL); return ret; } /* For the scenario of QAT HW initialization fail. */ if (fallback_to_qat_sw || fallback_to_openssl) { WARN("- Fallback to software mode.\n"); return (*sign_sig_pfunc)(dgst, dgst_len, in_kinv, in_r, eckey); } if (qat_get_qat_offload_disabled()) { fallback = 1; goto err; } group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || priv_key == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return ret; } #ifndef QAT_INSECURE_ALGO /* Bits < 256 is not supported in QAT_HW */ bitlen = EC_GROUP_order_bits(group); if (bitlen < QAT_EC_MIN_RANGE) { DEBUG("Curve-Bitlen %d not supported! Using OPENSSL_SW\n", bitlen); return (*sign_sig_pfunc)(dgst, dgst_len, in_kinv, in_r, eckey); } #endif if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); return (*sign_sig_pfunc)(dgst, dgst_len, in_kinv, in_r, eckey); } else { QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); return ret; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; curve_name = EC_GROUP_get_curve_name(group); if ((ec_point = EC_GROUP_get0_generator(group)) == NULL) { WARN("Failure to retrieve ec_point\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_EC_POINT_RETRIEVE_FAILURE); return ret; } opData = (CpaCyEcdsaSignRSOpData *) OPENSSL_zalloc(sizeof(CpaCyEcdsaSignRSOpData)); if (opData == NULL) { WARN("Failure to allocate opData\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_OPDATA_MALLOC_FAILURE); return ret; } if ((ret = ECDSA_SIG_new()) == NULL) { WARN("Failure to allocate ECDSA_SIG\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_ECDSA_SIG_MALLOC_FAILURE); goto err; } ecdsa_sig_r = BN_new(); ecdsa_sig_s = BN_new(); /* NULL checking of ecdsa_sig_r & ecdsa_sig_s done in ECDSA_SIG_set0() */ if (ECDSA_SIG_set0(ret, ecdsa_sig_r, ecdsa_sig_s) == 0) { WARN("Failure to allocate r and s values to assign to the ECDSA_SIG\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_ECDSA_SIG_SET_R_S_FAILURE); goto err; } if ((ctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); p = BN_CTX_get(ctx); a = BN_CTX_get(ctx); b = BN_CTX_get(ctx); xg = BN_CTX_get(ctx); yg = BN_CTX_get(ctx); m = BN_CTX_get(ctx); k = BN_CTX_get(ctx); order = BN_CTX_get(ctx); if (order == NULL) { WARN("Failure to allocate p, a, b, xg, yg, m, k, r or order\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_P_A_B_XG_YG_M_K_R_ORDER_MALLOC_FAILURE); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { WARN("Failure to get order from group\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_EC_LIB); goto err; } i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { WARN("Failure to convert dgst to m\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { WARN("Failure to truncate m\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_BN_LIB); goto err; } opData->fieldType = qat_get_field_type(group); #ifdef QAT_BORINGSSL if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { #else if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { #endif /* QAT_BORINGSSL */ WARN("Failure to get the curve\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); goto err; } if (!EC_POINT_get_affine_coordinates(group, ec_point, xg, yg, ctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); goto err; } if (qat_BN_to_FB(&(opData->d), (BIGNUM *)priv_key, qat_svm) != 1 || qat_BN_to_FB(&(opData->m), m, qat_svm) != 1 || qat_BN_to_FB(&(opData->xg), xg, qat_svm) != 1 || qat_BN_to_FB(&(opData->yg), yg, qat_svm) != 1 || qat_BN_to_FB(&(opData->a), a, qat_svm) != 1 || qat_BN_to_FB(&(opData->b), b, qat_svm) != 1 || qat_BN_to_FB(&(opData->q), p, qat_svm) != 1) { WARN("Failed to convert d, m, xg, yg, a, b or p to a flatbuffer\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_PRIV_KEY_M_XG_YG_A_B_P_CONVERT_TO_FB_FAILURE); goto err; } /* * This is a special handling required for curves with 'a' co-efficient * of 0. The translation to a flatbuffer results in a zero sized field * but the Quickassist API expects a flatbuffer of size 1 with a value * of zero. As a special case we will create that manually. */ if (opData->a.pData == NULL && opData->a.dataLenInBytes == 0) { opData->a.pData = qat_mem_alloc(1, qat_svm, __FILE__, __LINE__); if (opData->a.pData == NULL) { WARN("Failure to allocate opData->a.pData\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_OPDATA_PDATA_MALLOC_FAILURE); goto err; } opData->a.dataLenInBytes = 1; opData->a.pData[0] = 0; } #ifdef ENABLE_QAT_FIPS if (in_kinv == NULL || in_r == NULL) { if (qat_fips_kat_test == 0) { do if (!BN_rand_range(k, order)) { WARN("Failure to get random number k\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_K_RAND_GENERATE_FAILURE); goto err; } while (BN_is_zero(k)); } else { if (!BN_bin2bn(kvalue, sizeof(kvalue), k)) { WARN("Failure to get k value\n"); goto err; } } #else if (in_kinv == NULL || in_r == NULL) { do if (!BN_rand_range(k, order)) { WARN("Failure to get random number k\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_K_RAND_GENERATE_FAILURE); goto err; } while (BN_is_zero(k)); #endif if ((qat_BN_to_FB(&(opData->k), k, qat_svm)) != 1) { WARN("Failed to convert k to a flatbuffer\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_K_CONVERT_TO_FB_FAILURE); goto err; } if ((qat_BN_to_FB(&(opData->n), order, qat_svm)) != 1) { WARN("Failed to convert order to a flatbuffer\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_K_ORDER_CONVERT_TO_FB_FAILURE); goto err; } } else { if ((qat_BN_to_FB(&(opData->k), (BIGNUM *)in_kinv, qat_svm)) != 1) { WARN("Failed to convert in_kinv to a flatbuffer\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_IN_KINV_CONVERT_TO_FB_FAILURE); goto err; } if ((qat_BN_to_FB(&(opData->n), (BIGNUM *)in_r, qat_svm)) != 1) { WARN("Failed to convert in_r to a flatbuffer\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_IN_R_CONVERT_TO_FB_FAILURE); goto err; } } buflen = EC_GROUP_get_degree(group); pResultR = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (pResultR == NULL) { WARN("Failure to allocate pResultR\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_PRESULTR_MALLOC_FAILURE); goto err; } pResultR->pData = qat_mem_alloc(buflen, qat_svm,__FILE__, __LINE__); if (pResultR->pData == NULL) { WARN("Failure to allocate pResultR->pData\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_PRESULTR_PDATA_MALLOC_FAILURE); goto err; } pResultR->dataLenInBytes = (Cpa32U) buflen; pResultS = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (pResultS == NULL) { WARN("Failure to allocate pResultS\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_PRESULTS_MALLOC_FAILURE); goto err; } pResultS->pData = qat_mem_alloc(buflen, qat_svm,__FILE__, __LINE__); if (pResultS->pData == NULL) { WARN("Failure to allocate pResultS->pData\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_PRESULTS_PDATA_MALLOC_FAILURE); goto err; } pResultS->dataLenInBytes = (Cpa32U) buflen; /* perform ECDSA sign */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); goto err; } #ifdef QAT_BORINGSSL qat_init_op_done(&op_done, qat_svm); #else qat_init_op_done(&op_done); #endif if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } #ifdef QAT_BORINGSSL if (op_done.job) { ret_sig = (CpaFlatBuffer *) OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (ret_sig == NULL) { WARN("Failure to allocate ret_sig\n"); goto err; } ret_sig->pData = qat_mem_alloc(ECDSA_size(eckey), qat_svm, __FILE__, __LINE__); if (ret_sig->pData == NULL) { WARN("Failure to allocate ret_sig->pData\n"); goto err; } ret_sig->dataLenInBytes = (Cpa32U)ECDSA_size(eckey); op_done.job->waitctx->data = ret_sig; op_done_bssl = (op_done_t *)op_done.job->copy_op_done(&op_done, sizeof(op_done), (void (*)(void *, void *, int))ec_decrypt_op_buf_free); } #endif /* QAT_BORINGSSL */ STOP_RDTSC(&qat_hw_ecdsa_sign_req_prepare, 1, "[QAT HW ECDSA: prepare]"); do { START_RDTSC(&qat_hw_ecdsa_sign_req_submit); if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { #ifdef QAT_BORINGSSL op_done.job->free_op_done(op_done_bssl); #endif qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } DUMP_ECDSA_SIGN(qat_instance_handles[inst_num], opData, pResultR, pResultS); #ifndef QAT_BORINGSSL status = cpaCyEcdsaSignRS(qat_instance_handles[inst_num], qat_ecdsaSignCallbackFn, &op_done, opData, &bEcdsaSignStatus, pResultR, pResultS); #else if (op_done.job) { status = cpaCyEcdsaSignRS(qat_instance_handles[inst_num], qat_ecdsaSignCallbackFn, op_done_bssl, opData, &bEcdsaSignStatus, pResultR, pResultS); } else { DEBUG("Running sync mode for ECDSA request\n"); status = cpaCyEcdsaSignRS(qat_instance_handles[inst_num], qat_ecdsaSignCallbackFn, &op_done, opData, &bEcdsaSignStatus, pResultR, pResultS); } #endif /* QAT_BORINGSSL */ STOP_RDTSC(&qat_hw_ecdsa_sign_req_submit, 1, "[QAT HW ECDSA: submit]"); if (status == CPA_STATUS_RETRY) { DEBUG("cpaCyEcdsaSignRS Retry \n"); if (qat_ecdsa_coexist && (curve_name == NID_secp384r1)) { START_RDTSC(&qat_hw_ecdsa_sign_req_retry); ++num_ecdsa_sign_retry; qat_sw_ecdsa_sign_req += QAT_SW_SWITCH_MB8; fallback = 1; qat_cleanup_op_done(&op_done); STOP_RDTSC(&qat_hw_ecdsa_sign_req_retry, 1, "[QAT HW ECDSA: retry]"); goto err; } else { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { #ifndef QAT_BORINGSSL if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } #endif } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { #ifdef QAT_BORINGSSL op_done.job->free_op_done(op_done_bssl); #endif qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); #ifdef QAT_BORINGSSL if (op_done.job) op_done.job->free_op_done(op_done_bssl); #endif goto err; } } } #ifdef QAT_BORINGSSL if (op_done.job != NULL) { qat_cleanup_op_done(&op_done); if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ret; } #endif if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } if (qat_ecdsa_coexist) ++num_ecdsa_hw_sign_reqs; do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { #ifdef QAT_BORINGSSL /* Support inline polling in current scenario */ if(getEnableInlinePolling()) { status = icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); if (status == CPA_STATUS_FAIL) { WARN("icp_sal_CyPollInstance failed - status %d\n", status); QATerr(QAT_F_QAT_ECDSA_DO_SIGN, QAT_R_POLL_INSTANCE_FAILURE); qat_cleanup_op_done(&op_done); goto err; } ECDSA_INLINE_POLLING_USLEEP(); } else { sched_yield(); } #else sched_yield(); #endif /* QAT_BORINGSSL */ } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_ECDSA_SIGN_OUTPUT(bEcdsaSignStatus, pResultR, pResultS); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_ECDSA_DO_SIGN, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); /* Convert the flatbuffer results back to a BN */ BN_bin2bn(pResultR->pData, pResultR->dataLenInBytes, ecdsa_sig_r); BN_bin2bn(pResultS->pData, pResultS->dataLenInBytes, ecdsa_sig_s); ok = 1; err: START_RDTSC(&qat_hw_ecdsa_sign_req_cleanup); if (!ok) { ECDSA_SIG_free(ret); ret = NULL; } #ifdef QAT_BORINGSSL if (ret_sig) { QAT_MEM_FREE_FLATBUFF(*ret_sig, qat_svm); OPENSSL_free(ret_sig); } #endif /* QAT_BORINGSSL */ if (pResultR) { QAT_MEM_FREE_FLATBUFF(*pResultR, qat_svm); OPENSSL_free(pResultR); } if (pResultS) { QAT_MEM_FREE_FLATBUFF(*pResultS, qat_svm); OPENSSL_free(pResultS); } if (opData) { QAT_MEM_FREE_FLATBUFF(opData->n, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->m, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->xg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->yg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->a, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->b, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->q, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->k, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->d, qat_svm); OPENSSL_free(opData); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } STOP_RDTSC(&qat_hw_ecdsa_sign_req_cleanup, 1, "[QAT HW ECDSA: cleanup]"); if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); if (qat_ecdsa_coexist) { DEBUG("- Switch to QAT_SW mode.\n"); return NULL; } else { WARN("- Fallback to software mode.\n"); return (*sign_sig_pfunc)(dgst, dgst_len, in_kinv, in_r, eckey); } } DEBUG("- Finished\n"); return ret; } /*- * returns * 1: correct signature * 0: incorrect signature * -1: error */ int qat_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) { ECDSA_SIG *s; const unsigned char *p = sigbuf; unsigned char *der = NULL; int derlen = -1; int ret = -1; s = ECDSA_SIG_new(); if (s == NULL) { WARN("Failure to allocate ECDSA_SIG s\n"); QATerr(QAT_F_QAT_ECDSA_VERIFY, QAT_R_S_NULL); return ret; } if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) { WARN("Failure to convert sig_buf and sig_len to s\n"); QATerr(QAT_F_QAT_ECDSA_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_ECDSA_SIG(s, &der); if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0) { WARN("Failure ECDSA_SIG s contains trailing garbage\n"); QATerr(QAT_F_QAT_ECDSA_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } ret = qat_ecdsa_do_verify(dgst, dgst_len, s, eckey); err: OPENSSL_free(der); ECDSA_SIG_free(s); return ret; } int qat_ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = -1, job_ret = 0, fallback = 0, i = 0; BN_CTX *ctx = NULL; const EC_GROUP *group = NULL; const EC_POINT *pub_key = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL; const EC_POINT *ec_point = NULL; PFUNC_VERIFY_SIG verify_sig_pfunc = NULL; int inst_num = QAT_INVALID_INSTANCE; BIGNUM *xg = NULL, *yg = NULL, *xp = NULL, *yp = NULL; BIGNUM *order = NULL, *m = NULL; const BIGNUM *sig_r = NULL, *sig_s = NULL; CpaCyEcdsaVerifyOpData *opData = NULL; CpaBoolean bEcdsaVerifyStatus = 0; CpaStatus status = CPA_STATUS_FAIL; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); thread_local_variables_t *tlv = NULL; int qat_svm = QAT_INSTANCE_ANY; #ifndef QAT_INSECURE_ALGO int bitlen = 0; #endif DEBUG("QAT HW ECDSA Started\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(dgst == NULL || dgst_len <= 0)) { WARN("Invalid input param.\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_INPUT_PARAM_INVALID); return ret; } EC_KEY_METHOD_get_verify((EC_KEY_METHOD *) EC_KEY_OpenSSL(), NULL, &verify_sig_pfunc); if (verify_sig_pfunc == NULL) { WARN("verify_sig_pfunc is NULL\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_SW_GET_VERIFY_SIG_PFUNC_NULL); return ret; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); return (*verify_sig_pfunc)(dgst, dgst_len, sig, eckey); } /* check input values */ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { WARN("eckey, group, pub_key or sig are NULL\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_ECKEY_GROUP_PUBKEY_SIG_NULL); return ret; } #ifndef QAT_INSECURE_ALGO /* Bits < 256 is not supported in QAT_HW */ bitlen = EC_GROUP_order_bits(group); if (bitlen < QAT_EC_MIN_RANGE) { DEBUG("Curve-Bitlen %d not supported! Using OPENSSL_SW\n", bitlen); return (*verify_sig_pfunc)(dgst, dgst_len, sig, eckey); } #endif if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); return (*verify_sig_pfunc)(dgst, dgst_len, sig, eckey); } else { QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); return ret; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if ((ec_point = EC_GROUP_get0_generator(group)) == NULL) { WARN("Failure to retrieve ec_point\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_RETRIEVE_EC_POINT_FAILURE); return ret; } opData = (CpaCyEcdsaVerifyOpData *) OPENSSL_zalloc(sizeof(CpaCyEcdsaVerifyOpData)); if (opData == NULL) { WARN("Failure to allocate opData\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_OPDATA_MALLOC_FAILURE); return ret; } if ((ctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); p = BN_CTX_get(ctx); a = BN_CTX_get(ctx); b = BN_CTX_get(ctx); xg = BN_CTX_get(ctx); yg = BN_CTX_get(ctx); xp = BN_CTX_get(ctx); yp = BN_CTX_get(ctx); m = BN_CTX_get(ctx); order = BN_CTX_get(ctx); if (order == NULL) { WARN("Failure to allocate p, a, b, xg, yg, xp, yp, m or order\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_P_A_B_XG_YG_XP_YP_M_ORDER_FAILURE); goto err; } if (!EC_GROUP_get_order(group, order, ctx)) { WARN("Failure to get order from group\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } ECDSA_SIG_get0((ECDSA_SIG *)sig, &sig_r, &sig_s); if (BN_is_zero(sig_r) || BN_is_negative(sig_r) || BN_ucmp(sig_r, order) >= 0 || BN_is_zero(sig_s) || BN_is_negative(sig_s) || BN_ucmp(sig_s, order) >= 0) { WARN("ECDSA_SIG sig is invalid\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); ret = 0; /* signature is invalid */ goto err; } /* digest -> m */ i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * dgst_len > i) dgst_len = (i + 7) / 8; if (!BN_bin2bn(dgst, dgst_len, m)) { WARN("Failure to convert dgst to m\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { WARN("Failure to truncate m\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } opData->fieldType = qat_get_field_type(group); #ifdef QAT_BORINGSSL if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) { #else if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { #endif /* QAT_BORINGSSL */ WARN("Failure to get the curve\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } if (!EC_POINT_get_affine_coordinates(group, ec_point, xg, yg, ctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } if (!EC_POINT_get_affine_coordinates(group, pub_key, xp, yp, ctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } if ((qat_BN_to_FB(&(opData->m), m, qat_svm) != 1) || (qat_BN_to_FB(&(opData->xg), xg, qat_svm) != 1) || (qat_BN_to_FB(&(opData->yg), yg, qat_svm) != 1) || (qat_BN_to_FB(&(opData->a), a, qat_svm) != 1) || (qat_BN_to_FB(&(opData->b), b, qat_svm) != 1) || (qat_BN_to_FB(&(opData->q), p, qat_svm) != 1) || (qat_BN_to_FB(&(opData->n), order, qat_svm) != 1) || (qat_BN_to_FB(&(opData->r), (BIGNUM *)sig_r, qat_svm) != 1) || (qat_BN_to_FB(&(opData->s), (BIGNUM *)sig_s, qat_svm) != 1) || (qat_BN_to_FB(&(opData->xp), xp, qat_svm) != 1) || (qat_BN_to_FB(&(opData->yp), yp, qat_svm) != 1)) { WARN("Failed to convert m, xg, yg, a, b, p, order, sig_r, sig_s, xp or yp to a flatbuffer\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE); goto err; } /* * This is a special handling required for curves with 'a' co-efficient * of 0. The translation to a flatbuffer results in a zero sized field * but the Quickassist API expects a flatbuffer of size 1 with a value * of zero. As a special case we will create that manually. */ if (opData->a.pData == NULL && opData->a.dataLenInBytes == 0) { opData->a.pData = qat_mem_alloc(1, qat_svm, __FILE__, __LINE__); if (opData->a.pData == NULL) { WARN("Failure to allocate opData->a.pData\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, QAT_R_OPDATA_DATA_MALLOC_FAILURE); goto err; } opData->a.dataLenInBytes = 1; opData->a.pData[0] = 0; } /* perform ECDSA verify */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } #ifdef QAT_BORINGSSL qat_init_op_done(&op_done, qat_svm); #else qat_init_op_done(&op_done); #endif if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } DUMP_ECDSA_VERIFY(qat_instance_handles[inst_num], opData); status = cpaCyEcdsaVerify(qat_instance_handles[inst_num], qat_ecdsaVerifyCallbackFn, &op_done, opData, &bEcdsaVerifyStatus); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_ECDSA_DO_VERIFY, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("bEcdsaVerifyStatus = %u\n", bEcdsaVerifyStatus); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult == CPA_TRUE) ret = 1; else if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } qat_cleanup_op_done(&op_done); err: if (opData) { QAT_MEM_FREE_FLATBUFF(opData->r, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->s, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->n, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->m, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->xg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->yg, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->a, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->b, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->q, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->xp, qat_svm); QAT_MEM_FREE_FLATBUFF(opData->yp, qat_svm); OPENSSL_free(opData); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return (*verify_sig_pfunc)(dgst, dgst_len, sig, eckey); } DEBUG("- Finished\n"); return ret; } #ifdef QAT_BORINGSSL /* Referred to boringssl/crypto/ecdsa_extra/ecdsa_asn1.c */ int qat_ecdsa_sign_bssl(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey) { int ret = 0; DEBUG("Start qat_ecdsa_sign_bssl\n"); ASYNC_JOB* current_job = (ASYNC_JOB*)ASYNC_get_current_job(); ECDSA_SIG *s = qat_ecdsa_do_sign(digest, digest_len, NULL, NULL, eckey); if (s == NULL) { *sig_len = 0; goto err; } if (current_job) { *sig_len = 0; ret = -1; goto err; } CBB cbb; CBB_zero(&cbb); size_t len; if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || !ECDSA_SIG_marshal(&cbb, s) || !CBB_finish(&cbb, NULL, &len)) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); CBB_cleanup(&cbb); *sig_len = 0; goto err; } *sig_len = (unsigned)len; ret = 1; err: if (current_job) { current_job->tlv_destructor(NULL); } ECDSA_SIG_free(s); return ret; } #endif /* QAT_BORINGSSL */ #endif /* #ifdef ENABLE_QAT_HW_ECDSA */ qatengine-1.9.0/qat_hw_ec.h000066400000000000000000000071051500416242000155740ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_ec.h * * This file provides an interface to ECDH & ECDSA operations * *****************************************************************************/ #ifndef QAT_HW_EC_H # define QAT_HW_EC_H # include # ifdef ENABLE_QAT_HW_ECDSA # ifndef QAT_BORINGSSL int qat_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey); # else int qat_ecdsa_sign_bssl(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey); # endif /* QAT_BORINGSSL */ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dlen, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); int qat_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); int qat_ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); # endif # ifdef ENABLE_QAT_HW_ECDH /* Qat engine ECDH methods declaration */ int qat_ecdh_compute_key(unsigned char **outX, size_t *outlenX, unsigned char **outY, size_t *outlenY, const EC_POINT *pub_key, const EC_KEY *ecdh, int *fallback); int qat_engine_ecdh_compute_key(unsigned char **out, size_t *outlen, const EC_POINT *pub_key, const EC_KEY *ecdh); int qat_ecdh_generate_key(EC_KEY *ecdh); # endif # ifdef ENABLE_QAT_HW_SM2 EVP_PKEY_METHOD *qat_sm2_pmeth(void); # endif #endif /* QAT_HW_EC_H */ qatengine-1.9.0/qat_hw_ecx.c000066400000000000000000001441241500416242000157620ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2019-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_ecx.c * * This file provides an implementation of X25519 and X448 operations for an * OpenSSL engine. * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include "e_qat.h" #include "qat_utils.h" #include "qat_hw_asym_common.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_ecx.h" #else # include "qat_evp.h" #endif #ifdef ENABLE_QAT_SW_ECX # include "qat_sw_ecx.h" #endif #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_key.h" #include "cpa_cy_ec.h" #include "qat_common.h" #ifdef ENABLE_QAT_HW_ECX int reverse_bytes(unsigned char *tobuffer, unsigned char *frombuffer, unsigned int tosize, unsigned int fromsize) { int i = 0; if (tobuffer == NULL || frombuffer == NULL) { WARN("Either tobuffer or frombuffer is NULL \n"); return 0; } if (fromsize == X448_KEYLEN) i = 8; /* Adds zeros at the beginning for 64 byte alignment */ /* Reverse bytes and copy to dest buffer */ for (; i < tosize; i++) { tobuffer[i] = frombuffer[--fromsize]; if (fromsize <=0) break; } return 1; } /****************************************************************************** * function: * void qat_ecx_cb(void *pCallbackTag, * CpaStatus status, * void *pOpdata, * CpaBoolean multiplyStatus, * CpaFlatBuffer *pXk, * CpaFlatBuffer *pYk) * * @param pCallbackTag [IN] - Pointer to user data * @param status [IN] - Status of the operation * @param pOpData [IN] - Pointer to operation data included in the request * @param multiplyStatus [IN] - Status of the point multiplication. * @param pXk [IN] - Pointer to the output buffer, provided in the request * invoking this callback, containing the x coordinate * of resultant EC point. * @param pYk [IN] - Pointer to the output buffer, provided in the request * invoking this callback, containing the y coordinate * of resultant EC point. * * description: * Callback to indicate the completion of an X25519 or X448 point multiply * operation offloaded to the QAT driver. * ******************************************************************************/ void qat_ecx_cb(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean multiplyStatus, CpaFlatBuffer *pXk, CpaFlatBuffer *pYk) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, multiplyStatus); } static void qat_pkey_ecx_keygen_op_data_free(CpaFlatBuffer *pXk, CpaCyEcMontEdwdsPointMultiplyOpData *qat_ecx_op_data, int qat_keylen, int qat_svm) { /* Clean the memory. */ if (pXk != NULL) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(*pXk, qat_svm); OPENSSL_free(pXk); } if (NULL != qat_ecx_op_data) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(qat_ecx_op_data->k, qat_svm); QAT_MEM_FREE_BUFF(qat_ecx_op_data, qat_svm); } } /* For OpenSSL 3.0, ECX25519 and ECX448 are not supported due to * the structure of EVP_PKEY_CTX and EVP_PKEY changed a lot, * Therefore, this function is wrapped to avoid the issue * introduced by reinforced casting of EVP_PKEY_CTX. */ # ifdef QAT_OPENSSL_PROVIDER static void *qat_pkey_ecx_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg) #else static int qat_pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey, int type) #endif { CpaCyEcMontEdwdsPointMultiplyOpData *qat_ecx_op_data = NULL; int ret = 0; int job_ret = 0; CpaStatus status = CPA_STATUS_FAIL; CpaBoolean multiplyStatus = CPA_TRUE; CpaFlatBuffer *pXk = NULL; Cpa8U keylen = 0; Cpa8U qat_keylen = 0; op_done_t op_done; int qatPerformOpRetries = 0; int iMsgRetry = getQatMsgRetryCount(); unsigned long int ulPollInterval = getQatPollInterval(); int inst_num = QAT_INVALID_INSTANCE; thread_local_variables_t *tlv = NULL; int fallback = 0; ECX_KEY *key = NULL; unsigned char *privkey = NULL; unsigned char *pubkey = NULL; int is_ecx_448 = 0; int qat_svm = QAT_INSTANCE_ANY; # ifndef QAT_OPENSSL_PROVIDER int (*sw_fn_ptr)(EVP_PKEY_CTX *, EVP_PKEY *) = NULL; #else QAT_GEN_CTX *gctx = ctx; # endif DEBUG("QAT HW ECX Started\n"); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL.\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); return 0; } key = OPENSSL_zalloc(sizeof(*key)); if (key == NULL) { WARN("Cannot allocate key.\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_MALLOC_FAILURE); return 0; } /* In OpenSSL 3, the structure of ECX_KEY has changed a lot, * one of the most important changes is the introduction of * a reference count variable as well as a lock variable. * When the EVP_PKEY_free() function is finally called to * reclaim memory, openssl will first decrease the reference * count before freeing its memory. Since this variable is * generated by qatengine, we must update its reference * count accordingly, otherwise it will trigger openssl's panic. */ #if defined(QAT_OPENSSL_3) && defined(QAT_OPENSSL_PROVIDER) # if OPENSSL_VERSION_NUMBER < 0x30200000 key->references = 1; key->lock = CRYPTO_THREAD_lock_new(); # else key->references.val = 1; # endif # ifdef QAT_OPENSSL_PROVIDER key->type = gctx->type; # endif #endif #ifndef QAT_OPENSSL_PROVIDER switch (type) { case EVP_PKEY_X25519: is_ecx_448 = 0; keylen = qat_keylen = X25519_KEYLEN; DEBUG("EVP_PKEY_X25519\n"); break; case EVP_PKEY_X448: is_ecx_448 = 1; keylen = X448_KEYLEN; qat_keylen = QAT_X448_DATALEN; DEBUG("EVP_PKEY_X448\n"); break; default: WARN("Unsupported NID: %d\n", type); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); OPENSSL_free(key); return 0; } if (qat_sw_ecx_keygen_req > 0 || qat_get_qat_offload_disabled()) { fallback = 1; goto err; } #else switch (gctx->type) { case ECX_KEY_TYPE_X25519: is_ecx_448 = 0; keylen = key->keylen = X25519_KEYLEN; qat_keylen = X25519_KEYLEN; DEBUG("EVP_PKEY_X25519\n"); break; case ECX_KEY_TYPE_X448: is_ecx_448 = 1; keylen = key->keylen = X448_KEYLEN; qat_keylen = QAT_X448_DATALEN; DEBUG("EVP_PKEY_X448\n"); break; default: WARN("Unsupported NID: %d\n", gctx->type); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); #ifdef QAT_OPENSSL_3 # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(key->lock); # endif #endif OPENSSL_free(key); return 0; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode.\n"); #ifdef QAT_OPENSSL_3 # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(key->lock); # endif #endif OPENSSL_free(key); if (!is_ecx_448) { typedef void* (*sw_prov_fun_ptr)(void *, OSSL_CALLBACK*, void*); sw_prov_fun_ptr sw_fn_ptr = get_default_x25519_keymgmt().gen; return sw_fn_ptr(ctx, osslcb, cbarg); } else if (is_ecx_448) { typedef void* (*sw_prov_fun_ptr)(void *, OSSL_CALLBACK*, void*); sw_prov_fun_ptr sw_fn_ptr = get_default_x448_keymgmt().gen; return sw_fn_ptr(ctx, osslcb, cbarg); } } #endif if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; goto err; } else { QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); #if defined(QAT_OPENSSL_3) && defined(QAT_OPENSSL_PROVIDER) # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(key->lock); # endif #endif OPENSSL_free(key); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; qat_ecx_op_data = (CpaCyEcMontEdwdsPointMultiplyOpData *) qat_mem_alloc(sizeof(CpaCyEcMontEdwdsPointMultiplyOpData), qat_svm, __FILE__, __LINE__); if (NULL == qat_ecx_op_data) { WARN("Failed to allocate memory for qat_ecx_op_data\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_MALLOC_FAILURE); #if defined(QAT_OPENSSL_3) && defined(QAT_OPENSSL_PROVIDER) # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(key->lock); # endif #endif OPENSSL_free(key); return 0; } memset(qat_ecx_op_data, 0, sizeof(CpaCyEcMontEdwdsPointMultiplyOpData)); qat_ecx_op_data->k.pData = (Cpa8U *)qat_mem_alloc(qat_keylen, qat_svm, __FILE__, __LINE__); if (qat_ecx_op_data->k.pData == NULL) { WARN("Failure to allocate k.pData.\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_MALLOC_FAILURE); goto err; } qat_ecx_op_data->k.dataLenInBytes = (Cpa32U)qat_keylen; pubkey = key->pubkey; privkey = key->privkey = OPENSSL_secure_zalloc(keylen); if (privkey == NULL) { WARN("Cannot allocate privkey.\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_MALLOC_FAILURE); goto err; } if (RAND_priv_bytes(privkey, keylen) <= 0) { WARN("RAND function failed for privkey.\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); goto err; } pXk = (CpaFlatBuffer *)OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (NULL == pXk) { WARN("Failed to allocate memory for pXk\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_MALLOC_FAILURE); goto err; } pXk->pData = (Cpa8U *)qat_mem_alloc(qat_keylen, qat_svm, __FILE__, __LINE__); if (NULL == pXk->pData) { WARN("Failed to allocate memory for pXk data\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_MALLOC_FAILURE); goto err; } pXk->dataLenInBytes = qat_keylen; qat_ecx_op_data->generator = CPA_TRUE; qat_ecx_op_data->curveType = is_ecx_448 ? CPA_CY_EC_MONTEDWDS_CURVE448_TYPE : CPA_CY_EC_MONTEDWDS_CURVE25519_TYPE; if (0 == reverse_bytes(qat_ecx_op_data->k.pData, privkey, qat_keylen, keylen)) { WARN("Failed to reverse bytes for submission of data to QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); goto err; } /* ---- Perform the operation ---- */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } DUMP_EC_MONTEDWDS_POINT_MULTIPLY(qat_instance_handles[inst_num], qat_ecx_op_data, pXk, pYk); DEBUG("Calling cpaCyEcMontEdwdsPointMultiply.\n"); status = cpaCyEcMontEdwdsPointMultiply(qat_instance_handles[inst_num], qat_ecx_cb, &op_done, qat_ecx_op_data, &multiplyStatus, pXk, NULL); if (status == CPA_STATUS_RETRY) { if (qat_ecx_coexist && !is_ecx_448) { if (op_done.job) { DEBUG("cpaCyEcMontEdwdsPointMultiply Retry \n"); ++num_ecx_keygen_retry; qat_sw_ecx_keygen_req += QAT_SW_SWITCH_MB8; fallback = 1; qat_cleanup_op_done(&op_done); goto err; } } else { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } } while (status == CPA_STATUS_RETRY); if (CPA_STATUS_SUCCESS != status) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } if (qat_ecx_coexist) { ++num_ecx_hw_keygen_reqs; } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_EC_POINT_MULTIPLY_OUTPUT(multiplyStatus, pXk, pYk); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); if (0 == reverse_bytes(pubkey, pXk->pData, keylen, qat_keylen)) { WARN("Failed to reverse bytes for data received from QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_KEYGEN, ERR_R_INTERNAL_ERROR); goto err; } #ifdef QAT_OPENSSL_3 key->haspubkey = 1; #endif #ifdef QAT_OPENSSL_PROVIDER qat_pkey_ecx_keygen_op_data_free(pXk, qat_ecx_op_data, qat_keylen, qat_svm); return key; #else EVP_PKEY_assign(pkey, (is_ecx_448 ? EVP_PKEY_X448 : EVP_PKEY_X25519), key); ret = 1; #endif err: qat_pkey_ecx_keygen_op_data_free(pXk, qat_ecx_op_data, qat_keylen, qat_svm); /* For success case cleanup will be taken care by calling application */ if (!ret) { if (NULL != privkey) { OPENSSL_secure_free(privkey); privkey = NULL; } if (NULL != key) { #if defined(QAT_OPENSSL_3) && defined(QAT_OPENSSL_PROVIDER) # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(key->lock); # endif #endif OPENSSL_free(key); key = NULL; } } if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef QAT_OPENSSL_PROVIDER if (is_ecx_448 == 0) { typedef void* (*sw_prov_fun_ptr)(void *, OSSL_CALLBACK*, void*); sw_prov_fun_ptr sw_fun_ptr = get_default_x25519_keymgmt().gen; return sw_fun_ptr(ctx, osslcb, cbarg); } else if (is_ecx_448 == 1) { typedef void* (*sw_prov_fun_ptr)(void *, OSSL_CALLBACK*, void*); sw_prov_fun_ptr sw_fun_ptr = get_default_x448_keymgmt().gen; return sw_fun_ptr(ctx, osslcb, cbarg); } #else #ifdef ENABLE_QAT_SW_ECX if (qat_ecx_coexist && !is_ecx_448) { DEBUG("- Switched to QAT_SW mode\n"); if (qat_sw_ecx_keygen_req > 0) --qat_sw_ecx_keygen_req; return multibuff_x25519_keygen(ctx, pkey); } #endif WARN("- Fallback to software mode.\n"); EVP_PKEY_meth_get_keygen((EVP_PKEY_METHOD *) (is_ecx_448 ? sw_x448_pmeth : sw_x25519_pmeth), NULL, &sw_fn_ptr); ret = (*sw_fn_ptr)(ctx, pkey); #endif } #ifdef QAT_OPENSSL_PROVIDER return NULL; #else return ret; #endif } # ifdef QAT_OPENSSL_PROVIDER void *qat_pkey_ecx448_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg) { return qat_pkey_ecx_keygen(ctx, osslcb, cbarg); } void *qat_pkey_ecx25519_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg) { return qat_pkey_ecx_keygen(ctx, osslcb, cbarg); } #else int qat_pkey_ecx448_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return qat_pkey_ecx_keygen(ctx, pkey, EVP_PKEY_X448); } int qat_pkey_ecx25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return qat_pkey_ecx_keygen(ctx, pkey, EVP_PKEY_X25519); } #endif #ifdef QAT_OPENSSL_PROVIDER static int qat_validate_ecx_derive(void *ctx, const unsigned char **privkey, const unsigned char **pubkey) #else static int qat_validate_ecx_derive(EVP_PKEY_CTX *ctx, const unsigned char **privkey, const unsigned char **pubkey) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_ECX_CTX *ecxctx = (QAT_ECX_CTX *)ctx; if (ecxctx == NULL || ecxctx->key->privkey == NULL) { WARN("ecxctx or ecxctx->key->privkey is NULL\n"); QATerr(QAT_F_QAT_VALIDATE_ECX_DERIVE, QAT_R_INVALID_PRIVATE_KEY); return 0; } *privkey = ecxctx->key->privkey; *pubkey = ecxctx->peerkey->pubkey; #else const ECX_KEY *ecxkey, *peerecxkey; EVP_PKEY *pkey = NULL; EVP_PKEY *peerkey = NULL; if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx)) == NULL || (peerkey = EVP_PKEY_CTX_get0_peerkey(ctx)) == NULL) { WARN("ctx->pkey or ctx->peerkey is NULL\n"); QATerr(QAT_F_QAT_VALIDATE_ECX_DERIVE, QAT_R_KEYS_NOT_SET); return 0; } ecxkey = (const ECX_KEY *)EVP_PKEY_get0((const EVP_PKEY *)pkey); peerecxkey = (const ECX_KEY *)EVP_PKEY_get0((const EVP_PKEY *)peerkey); if (ecxkey == NULL || ecxkey->privkey == NULL) { WARN("ecxkey or ecxkey->privkey is NULL\n"); QATerr(QAT_F_QAT_VALIDATE_ECX_DERIVE, QAT_R_INVALID_PRIVATE_KEY); return 0; } if (peerecxkey == NULL) { WARN("peerecxkey is NULL\n"); QATerr(QAT_F_QAT_VALIDATE_ECX_DERIVE, QAT_R_INVALID_PEER_KEY); return 0; } *privkey = ecxkey->privkey; *pubkey = peerecxkey->pubkey; #endif return 1; } #ifdef QAT_OPENSSL_PROVIDER int qat_pkey_ecx_derive25519(void *ctx, unsigned char *key, size_t *keylen, size_t outlen) #else int qat_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) #endif { CpaCyEcMontEdwdsPointMultiplyOpData *qat_ecx_op_data = NULL; #ifndef QAT_OPENSSL_PROVIDER int (*sw_fn_ptr)(EVP_PKEY_CTX *, unsigned char *, size_t *) = NULL; #endif int ret = 0; int job_ret = 0; CpaStatus status = CPA_STATUS_FAIL; CpaBoolean multiplyStatus = CPA_TRUE; CpaFlatBuffer *pXk = NULL; const unsigned char *privkey = NULL, *pubkey = NULL; op_done_t op_done; int qatPerformOpRetries = 0; int iMsgRetry = getQatMsgRetryCount(); unsigned long int ulPollInterval = getQatPollInterval(); int inst_num = QAT_INVALID_INSTANCE; thread_local_variables_t *tlv = NULL; int fallback = 0; int qat_svm = QAT_INSTANCE_ANY; DEBUG("QAT HW ECX Started\n"); START_RDTSC(&qat_hw_ecx_derive_req_prepare); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); return 0; } #ifdef QAT_OPENSSL_PROVIDER if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode.\n"); typedef int (*sw_prov_fun_ptr)(void *, unsigned char*, size_t*, size_t); sw_prov_fun_ptr sw_fun_ptr = get_default_x25519_keyexch().derive; return sw_fun_ptr(ctx, key, keylen, outlen); } #else if (qat_sw_ecx_derive_req > 0 || qat_get_qat_offload_disabled()) { fallback = 1; goto err; } #endif if (!qat_validate_ecx_derive(ctx, &privkey, &pubkey)) return 0; if (key == NULL) { *keylen = X25519_KEYLEN; return 1; } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; goto err; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; qat_ecx_op_data = (CpaCyEcMontEdwdsPointMultiplyOpData *) qat_mem_alloc(sizeof(CpaCyEcMontEdwdsPointMultiplyOpData), qat_svm, __FILE__, __LINE__); if (NULL == qat_ecx_op_data) { WARN("Failed to allocate memory for qat_ecx_op_data\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_MALLOC_FAILURE); return 0; } memset(qat_ecx_op_data, 0, sizeof(CpaCyEcMontEdwdsPointMultiplyOpData)); qat_ecx_op_data->k.pData = (Cpa8U *)qat_mem_alloc(X25519_KEYLEN, qat_svm, __FILE__, __LINE__); if (qat_ecx_op_data->k.pData == NULL) { WARN("Failure to allocate k.pData.\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_MALLOC_FAILURE); goto err; } qat_ecx_op_data->k.dataLenInBytes = X25519_KEYLEN; qat_ecx_op_data->x.pData = (Cpa8U *)qat_mem_alloc(X25519_KEYLEN, qat_svm, __FILE__, __LINE__); if (qat_ecx_op_data->x.pData == NULL) { WARN("Failure to allocate x.pData.\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_MALLOC_FAILURE); goto err; } qat_ecx_op_data->x.dataLenInBytes = X25519_KEYLEN; pXk = (CpaFlatBuffer *)OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (NULL == pXk) { WARN("Failed to allocate memory for pXk\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_MALLOC_FAILURE); goto err; } pXk->pData = (Cpa8U *)qat_mem_alloc(X25519_KEYLEN, qat_svm, __FILE__, __LINE__); if (NULL == pXk->pData) { WARN("Failed to allocate memory for pXk data\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_MALLOC_FAILURE); goto err; } pXk->dataLenInBytes = X25519_KEYLEN; qat_ecx_op_data->generator = CPA_FALSE; qat_ecx_op_data->curveType = CPA_CY_EC_MONTEDWDS_CURVE25519_TYPE; if (0 == reverse_bytes(qat_ecx_op_data->k.pData,(unsigned char *)privkey, X25519_KEYLEN, X25519_KEYLEN)) { WARN("Failed to reverse bytes for submission of data to QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); goto err; } if (0 == reverse_bytes(qat_ecx_op_data->x.pData, (unsigned char *)pubkey, X25519_KEYLEN, X25519_KEYLEN)) { WARN("Failed to reverse bytes for submission of data to QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); goto err; } /* ---- Perform the operation ---- */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } STOP_RDTSC(&qat_hw_ecx_derive_req_prepare, 1, "[QAT HW ECX: prepare]"); do { START_RDTSC(&qat_hw_ecx_derive_req_submit); if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } DUMP_EC_MONTEDWDS_POINT_MULTIPLY(qat_instance_handles[inst_num], qat_ecx_op_data, pXk, pYk); DEBUG("Calling cpaCyEcMontEdwdsPointMultiply.\n"); status = cpaCyEcMontEdwdsPointMultiply(qat_instance_handles[inst_num], qat_ecx_cb, &op_done, qat_ecx_op_data, &multiplyStatus, pXk, NULL); STOP_RDTSC(&qat_hw_ecx_derive_req_submit, 1, "[QAT HW ECX: submit]"); if (status == CPA_STATUS_RETRY) { if (qat_ecx_coexist) { if (op_done.job) { START_RDTSC(&qat_hw_ecx_derive_req_retry); DEBUG("cpaCyEcMontEdwdsPointMultiply Retry \n"); ++num_ecx_derive_retry; qat_sw_ecx_derive_req += QAT_SW_SWITCH_MB8; fallback = 1; qat_cleanup_op_done(&op_done); STOP_RDTSC(&qat_hw_ecx_derive_req_retry, 1, "[QAT HW ECX: retry]"); goto err; } } else { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } } while (status == CPA_STATUS_RETRY); if (CPA_STATUS_SUCCESS != status) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } if (qat_ecx_coexist) ++num_ecx_hw_derive_reqs; do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_EC_POINT_MULTIPLY_OUTPUT(multiplyStatus, pXk, pYk); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); if (0 == reverse_bytes(key, pXk->pData, X25519_KEYLEN, X25519_KEYLEN)) { WARN("Failed to reverse bytes for data received from QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE25519, ERR_R_INTERNAL_ERROR); goto err; } *keylen = X25519_KEYLEN; ret = 1; err: START_RDTSC(&qat_hw_ecx_derive_req_cleanup); /* Clean the memory. */ if (pXk != NULL) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(*pXk, qat_svm); OPENSSL_free(pXk); } if (NULL != qat_ecx_op_data) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(qat_ecx_op_data->k, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(qat_ecx_op_data->x, qat_svm); QAT_MEM_FREE_BUFF(qat_ecx_op_data, qat_svm); } STOP_RDTSC(&qat_hw_ecx_derive_req_cleanup, 1, "[QAT HW ECX: cleanup]"); if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef QAT_OPENSSL_PROVIDER typedef int (*sw_prov_fun_ptr)(void *, unsigned char*, size_t*, size_t); sw_prov_fun_ptr sw_fun_ptr = get_default_x25519_keyexch().derive; return sw_fun_ptr(ctx, key, keylen, outlen); #else #ifdef ENABLE_QAT_SW_ECX if (qat_ecx_coexist) { DEBUG("- Switched to QAT_SW mode\n"); if (qat_sw_ecx_derive_req > 0) --qat_sw_ecx_derive_req; return multibuff_x25519_derive(ctx, key, keylen); } #endif WARN("- Fallback to software mode.\n"); EVP_PKEY_meth_get_derive((EVP_PKEY_METHOD *)sw_x25519_pmeth, NULL, &sw_fn_ptr); ret = (*sw_fn_ptr)(ctx, key, keylen); #endif } return ret; } #ifdef QAT_OPENSSL_PROVIDER int qat_pkey_ecx_derive448(void *ctx, unsigned char *key, size_t *keylen, size_t outlen) #else int qat_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) #endif { CpaCyEcMontEdwdsPointMultiplyOpData *qat_ecx_op_data = NULL; #ifndef QAT_OPENSSL_PROVIDER int (*sw_fn_ptr)(EVP_PKEY_CTX *, unsigned char *, size_t *) = NULL; #endif int ret = 0; int job_ret = 0; CpaStatus status = CPA_STATUS_FAIL; CpaBoolean multiplyStatus = CPA_TRUE; CpaFlatBuffer *pXk = NULL; const unsigned char *privkey = NULL, *pubkey = NULL; op_done_t op_done; int qatPerformOpRetries = 0; int iMsgRetry = getQatMsgRetryCount(); unsigned long int ulPollInterval = getQatPollInterval(); int inst_num = QAT_INVALID_INSTANCE; thread_local_variables_t *tlv = NULL; int fallback = 0; int qat_svm = QAT_INSTANCE_ANY; DEBUG("QAT HW ECX Started\n"); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); return 0; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode.\n"); #ifdef QAT_OPENSSL_PROVIDER typedef int (*sw_prov_fun_ptr)(void *, unsigned char*, size_t*, size_t); sw_prov_fun_ptr sw_fun_ptr = get_default_x448_keyexch().derive; return sw_fun_ptr(ctx, key, keylen, outlen); #else EVP_PKEY_meth_get_derive((EVP_PKEY_METHOD *)sw_x448_pmeth, NULL, &sw_fn_ptr); ret = (*sw_fn_ptr)(ctx, key, keylen); if (ret != 1) { WARN("s/w pkey_ecx_derive448 fn failed.\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); } return ret; #endif } if (!qat_validate_ecx_derive(ctx, &privkey, &pubkey)) return 0; if (key == NULL) { *keylen = X448_KEYLEN; return 1; } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; goto err; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; qat_ecx_op_data = (CpaCyEcMontEdwdsPointMultiplyOpData *) qat_mem_alloc(sizeof(CpaCyEcMontEdwdsPointMultiplyOpData), qat_svm, __FILE__, __LINE__); if (NULL == qat_ecx_op_data) { WARN("Failed to allocate memory for qat_ecx_op_data\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_MALLOC_FAILURE); return 0; } memset(qat_ecx_op_data, 0, sizeof(CpaCyEcMontEdwdsPointMultiplyOpData)); qat_ecx_op_data->k.pData = (Cpa8U *)qat_mem_alloc(QAT_X448_DATALEN, qat_svm, __FILE__, __LINE__); if (qat_ecx_op_data->k.pData == NULL) { WARN("Failure to allocate k.pData.\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_MALLOC_FAILURE); goto err; } qat_ecx_op_data->k.dataLenInBytes = QAT_X448_DATALEN; qat_ecx_op_data->x.pData = (Cpa8U *)qat_mem_alloc(QAT_X448_DATALEN, qat_svm, __FILE__, __LINE__); if (qat_ecx_op_data->x.pData == NULL) { WARN("Failure to allocate x.pData.\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_MALLOC_FAILURE); goto err; } qat_ecx_op_data->x.dataLenInBytes = QAT_X448_DATALEN; pXk = (CpaFlatBuffer *)OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (NULL == pXk) { WARN("Failed to allocate memory for pXk\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_MALLOC_FAILURE); goto err; } pXk->pData = (Cpa8U *)qat_mem_alloc(QAT_X448_DATALEN, qat_svm, __FILE__, __LINE__); if (NULL == pXk->pData) { WARN("Failed to allocate memory for pXk data\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_MALLOC_FAILURE); goto err; } pXk->dataLenInBytes = QAT_X448_DATALEN; qat_ecx_op_data->generator = CPA_FALSE; qat_ecx_op_data->curveType = CPA_CY_EC_MONTEDWDS_CURVE448_TYPE; if (0 == reverse_bytes(qat_ecx_op_data->k.pData,(unsigned char *)privkey, QAT_X448_DATALEN, X448_KEYLEN)) { WARN("Failed to reverse bytes for submission of data to QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); goto err; } if (0 == reverse_bytes(qat_ecx_op_data->x.pData, (unsigned char *)pubkey, QAT_X448_DATALEN, X448_KEYLEN)) { WARN("Failed to reverse bytes for submission of data to QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); goto err; } /* ---- Perform the operation ---- */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } DUMP_EC_MONTEDWDS_POINT_MULTIPLY(qat_instance_handles[inst_num], qat_ecx_op_data, pXk, pYk); DEBUG("Calling cpaCyEcMontEdwdsPointMultiply.\n"); status = cpaCyEcMontEdwdsPointMultiply(qat_instance_handles[inst_num], qat_ecx_cb, &op_done, qat_ecx_op_data, &multiplyStatus, pXk, NULL); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (CPA_STATUS_SUCCESS != status) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_EC_POINT_MULTIPLY_OUTPUT(multiplyStatus, pXk, pYk); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); if (0 == reverse_bytes(key, pXk->pData, X448_KEYLEN, QAT_X448_DATALEN)) { WARN("Failed to reverse bytes for data received from QAT driver\n"); QATerr(QAT_F_QAT_PKEY_ECX_DERIVE448, ERR_R_INTERNAL_ERROR); goto err; } *keylen = X448_KEYLEN; ret = 1; err: /* Clean the memory. */ if (pXk != NULL) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(*pXk, qat_svm); OPENSSL_free(pXk); } if (NULL != qat_ecx_op_data) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(qat_ecx_op_data->k, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(qat_ecx_op_data->x, qat_svm); QAT_MEM_FREE_BUFF(qat_ecx_op_data, qat_svm); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef QAT_OPENSSL_PROVIDER typedef int (*sw_prov_fun_ptr)(void *, unsigned char*, size_t*, size_t); sw_prov_fun_ptr sw_fun_ptr = get_default_x448_keyexch().derive; return sw_fun_ptr(ctx, key, keylen, outlen); #else EVP_PKEY_meth_get_derive((EVP_PKEY_METHOD *)sw_x448_pmeth, NULL, &sw_fn_ptr); ret = (*sw_fn_ptr)(ctx, key, keylen); #endif } return ret; } # ifndef QAT_OPENSSL_PROVIDER int qat_pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { DEBUG("Started\n"); /* Only need to handle peer key for derivation */ if (type == EVP_PKEY_CTRL_PEER_KEY) return 1; return -2; } # endif #endif /* ENABLE_QAT_HW_ECX */ qatengine-1.9.0/qat_hw_gcm.c000066400000000000000000002220411500416242000157440ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_gcm.c * * This file contains the engine implementations for GCM cipher operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include "e_qat.h" #include "qat_utils.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_sym.h" #include "qat_evp.h" #include "qat_hw_gcm.h" #include "qat_hw_ciphers.h" #include #include #include #include #include #include #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #ifdef ENABLE_QAT_HW_GCM # ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; # endif /****************************************************************************** * function: * qat_session_data_init(EVP_CIPHER_CTX *ctx, * qat_aes_gcm_ctx *qctx, * const unsigned char* key, * int keylen, * const unsigned char* iv, * int ivlen, * int enc) * * @param ctx [IN] - pointer to the evp context * @param qctx [IN] - pointer to the qat context * @param key [IN] - pointer to the cipher key * @param iv [IN] - pointer to the iv this maybe NULL. * @param enc [IN] - whether we are doing encryption (1) or decryption (0). * * description: * This function is to create QAT specific session data. * It is called from the function qat_aes_gcm_init(). * * It will return 1 if successful and 0 on failure. ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_session_data_init(QAT_GCM_CTX *ctx, const unsigned char* key, int keylen, const unsigned char* iv, int ivlen, int enc) #else static int qat_session_data_init(EVP_CIPHER_CTX *ctx, qat_gcm_ctx *qctx, const unsigned char* key, const unsigned char* iv, int enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #endif DEBUG("QAT HW GCM Started\n"); if (NULL == qctx || NULL == ctx) { WARN("qctx or ctx is NULL\n"); QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_QCTX_CTX_NULL); return 0; } if (key != NULL) { if (qctx->qat_svm) { if (qctx->cipher_key){ OPENSSL_free(qctx->cipher_key); qctx->cipher_key = NULL; } #ifdef QAT_OPENSSL_PROVIDER qctx->cipher_key = OPENSSL_zalloc(keylen); #else qctx->cipher_key = OPENSSL_zalloc(EVP_CIPHER_CTX_key_length(ctx)); #endif } else { if (qctx->cipher_key) { qaeCryptoMemFreeNonZero(qctx->cipher_key); qctx->cipher_key = NULL; } #ifdef QAT_OPENSSL_PROVIDER qctx->cipher_key = qaeCryptoMemAlloc(keylen, __FILE__, __LINE__); #else qctx->cipher_key = qaeCryptoMemAlloc(EVP_CIPHER_CTX_key_length(ctx), __FILE__, __LINE__); #endif } if (qctx->cipher_key == NULL) { WARN("Unable to allocate memory for qctx->cipher_key.\n"); QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_KEY_MALLOC_FAILURE); return 0; } #ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->cipher_key, key, keylen); #else memcpy(qctx->cipher_key, key, EVP_CIPHER_CTX_key_length(ctx)); #endif qctx->key_set = 1; } if (iv != NULL && qctx->iv_set) { qctx->OpData.pIv = qctx->iv; qctx->OpData.ivLenInBytes = qctx->iv_len; } if (NULL == qctx->session_data) { qctx->session_data = OPENSSL_zalloc(sizeof(CpaCySymSessionSetupData)); if (NULL == qctx->session_data) { WARN("session setup data zalloc failure\n"); QATerr(QAT_F_QAT_SESSION_DATA_INIT, QAT_R_SSD_MALLOC_FAILURE); return 0; } } /* Set priority and operation of this session */ qctx->session_data->sessionPriority = CPA_CY_PRIORITY_HIGH; qctx->session_data->symOperation = CPA_CY_SYM_OP_ALGORITHM_CHAINING; /* --- Cipher configuration --- */ /* Cipher algorithm and mode */ qctx->session_data->cipherSetupData.cipherAlgorithm = CPA_CY_SYM_CIPHER_AES_GCM; /* Cipher key length */ #ifdef QAT_OPENSSL_PROVIDER qctx->session_data->cipherSetupData.cipherKeyLenInBytes = (Cpa32U)keylen; #else qctx->session_data->cipherSetupData.cipherKeyLenInBytes = (Cpa32U)EVP_CIPHER_CTX_key_length(ctx); #endif if (qctx->key_set){ qctx->session_data->cipherSetupData.pCipherKey = (Cpa8U *)qctx->cipher_key; #ifdef QAT_OPENSSL_PROVIDER qctx->session_data->cipherSetupData.cipherKeyLenInBytes = (Cpa32U)qctx->keylen; #endif } /* Operation to perform */ if (enc) { qctx->session_data->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT; qctx->session_data->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; } else { qctx->session_data->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; qctx->session_data->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER; } /* --- Hash Configuration --- */ /* Set the hash mode and the length of the digest */ qctx->session_data->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_AES_GCM; qctx->session_data->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH; qctx->session_data->hashSetupData.digestResultLenInBytes = EVP_GCM_TLS_TAG_LEN; /* For GCM authKey and authKeyLen are not required. * This information is provided by the cipherKey in cipherSetupData */ qctx->session_data->hashSetupData.authModeSetupData.authKey = NULL; qctx->session_data->hashSetupData.authModeSetupData.authKeyLenInBytes = 0; /* Set the length of the AAD to the default value */ qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = 0; /* Tag follows immediately after the region to hash */ qctx->session_data->digestIsAppended = CPA_FALSE; /* digestVerify is not required to be set. For GCM authenticated * encryption this value is understood to be CPA_FALSE during encryption and * CPA_TRUE during decryption */ qctx->init_params_set = 1; return 1; } /****************************************************************************** * function: * qat_aes_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, * int keylen, const unsigned char *iv, int ivlen, * int enc) * * @param ctx [IN] - pointer to existing context * @param inKey [IN] - input cipher key * @param iv [IN] - initialisation vector * @param enc [IN] - 1 encrypt 0 decrypt * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the cipher and hash algorithm parameters for this * EVP context. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_aes_gcm_init(QAT_GCM_CTX *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) #else int qat_aes_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX* qctx = NULL; int nid = 0; QAT_EVP_CIPHER sw_aes_gcm_cipher; #else qat_gcm_ctx* qctx = NULL; #endif int ret = 0; if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_INIT, QAT_R_CTX_NULL); return 0; } DEBUG("CTX = %p, key = %p, iv = %p, enc = %d\n", (void*)ctx, (void*)inkey, (void*)iv, enc); #ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_GCM_CTX *)ctx; qctx->iv = (Cpa8U *)qctx->iv; qctx->next_iv = (Cpa8U *)qctx->next_iv; qctx->enc = enc; nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); #else qctx = QAT_GCM_GET_CTX(ctx); #endif /* Initialise a QAT session and set the cipher keys*/ if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_INIT, QAT_R_QCTX_NULL); return 0; } if (qat_get_sw_fallback_enabled()) { #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); /* Run the software init function */ ret = EVP_CIPHER_meth_get_init(GET_SW_AES_GCM_CIPHER(ctx)) (ctx, inkey, iv, enc); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); #else OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (enc) { if (!qctx->sw_ctx) qctx->sw_ctx = sw_aes_gcm_cipher.newctx(ctx); ret = sw_aes_gcm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } else { if (!qctx->sw_ctx) qctx->sw_ctx = sw_aes_gcm_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); ret = sw_aes_gcm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } #endif if (ret != 1) goto err; } if (!inkey && !iv) { DEBUG("key and IV not set\n"); return 1; } qctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (qctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); goto err; } qctx->qat_svm = !qat_instance_details[qctx->inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (NULL == qctx->iv) { /* The length of the IV in the TLS case is fixed = 12 Bytes */ qctx->iv_len = QAT_GCM_TLS_TOTAL_IV_LEN; #ifdef QAT_OPENSSL_PROVIDER qctx->iv = qat_mem_alloc(GCM_IV_MAX_SIZE, qctx->qat_svm, __FILE__, __LINE__); #else qctx->iv = qat_mem_alloc(EVP_CIPHER_CTX_iv_length(ctx), qctx->qat_svm, __FILE__, __LINE__); #endif if (qctx->iv == NULL) { WARN("iv is NULL.\n"); QATerr(QAT_F_QAT_AES_GCM_INIT, QAT_R_IV_MALLOC_FAILURE); goto err; } } #ifdef QAT_OPENSSL_PROVIDER if (!qctx->next_iv) qctx->next_iv = OPENSSL_zalloc(EVP_MAX_IV_LENGTH); #endif if (iv) { /* Set the value of the IV */ memcpy(qctx->iv, iv, qctx->iv_len); memcpy(qctx->next_iv, iv, qctx->iv_len); qctx->iv_set = 1; DUMPL("iv", iv, qctx->iv_len); } qctx->tls_aad_len = -1; qctx->tag_len = -1; qctx->iv_gen = 0; qctx->tag_set = 0; /* Initialize QAT session */ #ifdef QAT_OPENSSL_PROVIDER if (0 == qat_session_data_init(ctx, inkey, keylen, iv, ivlen, enc)) { #else if (0 == qat_session_data_init(ctx, qctx, inkey, iv, enc)) { #endif WARN("qat_session_data_init failed.\n"); goto err; } return 1; err: if (NULL != qctx->iv) { #ifndef QAT_OPENSSL_PROVIDER if (qctx->iv != EVP_CIPHER_CTX_iv_noconst(ctx)) { #else if (qctx->iv != ctx->iv) { #endif QAT_MEM_FREE_NONZERO_BUFF(qctx->iv, qctx->qat_svm); qctx->iv = NULL; } } QAT_MEM_FREE_BUFF(qctx->cipher_key, qctx->qat_svm); return ret; } /****************************************************************************** * * function: * aes_gcm_increment_counter(unsigned char *ifc) * * @param ifc [IN,OUT] - pointer to invocation field counter * * description: * Increment provided invocation field counter (64-bit int) by 1 * *******************************************************************************/ static inline void qat_aes_gcm_inc_ctr(unsigned char* ifc) { int inv_field_size = 8; unsigned char byte; /* Loop over ifc starting with the least significant byte * and work towards the most significant byte of ifc*/ do { --inv_field_size; byte = ifc[inv_field_size]; /* Increment by one and copy back to invocation field */ ++byte; ifc[inv_field_size] = byte; if (byte) return; } while (inv_field_size); } /****************************************************************************** * function: * qat_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, * int type, int arg, void *ptr) * * @param ctx [IN] - pointer to existing context * @param type [IN] - type of request either * EVP_CTRL_AEAD_SET_MAC_KEY or EVP_CTRL_AEAD_TLS1_AAD * @param arg [IN] - size of the pointed to by ptr * @param ptr [IN] - input buffer contain the necessary parameters * * @retval x The return value is dependent on the type of request being made * EVP_CTRL_AEAD_SET_MAC_KEY return of 1 is success * EVP_CTRL_AEAD_TLS1_AAD return value indicates the amount * for padding to be applied to the SSL/TLS record * @retval -1 function failed * * description: * This function is a generic control interface provided by the EVP API. For * chained requests this interface is used for setting the hmac key value for * authentication of the SSL/TLS record. * The second type is used to specify the TLS virtual header which is used * in the authentication calculation and to identify record payload size. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_aes_gcm_ctrl(void *ctx, int type, int arg, void *ptr) #else int qat_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX* qctx = NULL; #else qat_gcm_ctx *qctx = NULL; int ret_sw = 0; #endif unsigned int plen = 0; int enc = 0; int ret = 0; if (NULL == ctx) { WARN("ctx is NULL.\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_GCM_CTX *)ctx; qctx->iv = (Cpa8U *)qctx->iv; qctx->next_iv = (Cpa8U *)qctx->next_iv; #else qctx = QAT_GCM_GET_CTX(ctx); #endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_QCTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER enc = QAT_GCM_GET_ENC(qctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif switch (type) { case EVP_CTRL_INIT: DEBUG("EVP_CTRL_INIT, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); qctx->key_set = 0; qctx->iv_len = 0; qctx->iv_set = 0; qctx->iv_gen = 0; qctx->tls_aad_len = -1; qctx->tag_len = -1; qctx->tag_set = 0; #ifndef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx_cipher_data == NULL && qat_get_sw_fallback_enabled()) { unsigned int sw_size = 0; sw_size = EVP_CIPHER_impl_ctx_size(GET_SW_AES_GCM_CIPHER(ctx)); qctx->sw_ctx_cipher_data = OPENSSL_zalloc(sw_size); if (qctx->sw_ctx_cipher_data == NULL) { WARN("Unable to allocate memory for sw_ctx_cipher_data\n"); return -1; } goto sw_ctrl; } #endif return 1; case EVP_CTRL_GET_IVLEN: DEBUG("EVP_CTRL_GCM_GET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); *(int*)ptr = qctx->iv_len; ret = 1; goto sw_ctrl; case EVP_CTRL_GCM_SET_IVLEN: DEBUG("EVP_CTRL_GCM_SET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); /* At the moment we support only IV with length of 12 Bytes. * This is the length of the IV in TLS. * * If the user wants to use an IV with different length we should * implement the function J0 as described in GCM standard */ if (QAT_GCM_TLS_TOTAL_IV_LEN != arg) { WARN("Unsupported IV length %d\n", arg); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_IV_LEN_NOT_SUPPORTED); return 0; } ret = 1; goto sw_ctrl; case EVP_CTRL_GCM_SET_TAG: DEBUG("EVP_CTRL_GCM_SET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (arg <= QAT_GCM_TAG_MIN_LEN || arg > QAT_GCM_TAG_MAX_LEN || enc) { WARN("TAG length invalid or invalid operation enc\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_SET_TAG_INVALID_OP); return 0; } if (EVP_GCM_TLS_TAG_LEN != arg) { WARN("TAG length %d not supported. Accepted value = 16\n", arg); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_IV_LEN_NOT_SUPPORTED); return 0; } if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx) || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_INVALID_PTR); return 0; } /* ctx->buf is a static buffer of size * EVP_MAX_BLOCK_LENGTH = 32 */ if (ptr) { memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), ptr, arg); qctx->tag_set = 1; } qctx->tag_len = arg; ret = 1; goto sw_ctrl; case EVP_CTRL_GCM_GET_TAG: DEBUG("EVP_CTRL_GCM_GET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (arg <= QAT_GCM_TAG_MIN_LEN || arg > QAT_GCM_TAG_MAX_LEN || !enc) { WARN("TAG length invalid or invalid operation (!enc)\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_SET_TAG_INVALID_OP); return 0; } if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx) || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_INVALID_PTR); return 0; } memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(ctx), arg); return 1; case EVP_CTRL_GCM_SET_IV_FIXED: DEBUG("EVP_CTRL_GCM_SET_IV_FIXED, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_INVALID_PTR); return 0; } /* Special case: -1 length restores whole IV */ if (arg == -1) { memcpy(qctx->next_iv, ptr, qctx->iv_len); qctx->iv_gen = 1; ret = 1; goto sw_ctrl; } /* Fixed field must be at least 4 bytes (EVP_GCM_TLS_FIXED_IV_LEN) * and invocation field at least 8 (EVP_GCM_TLS_EXPLICIT_IV_LEN) */ if ((arg < EVP_GCM_TLS_FIXED_IV_LEN) || (qctx->iv_len - arg) < EVP_GCM_TLS_EXPLICIT_IV_LEN) { WARN("IV length invalid\n"); return 0; } if (arg != EVP_GCM_TLS_FIXED_IV_LEN) { WARN("IV length not supported\n"); return 0; } if (arg) { #ifdef QAT_OPENSSL_PROVIDER if (qctx->next_iv != NULL) #endif memcpy(qctx->next_iv, ptr, arg); } /* Generate the explicit part of the IV for encryption */ #ifdef QAT_OPENSSL_PROVIDER if (qctx->next_iv != NULL) #endif if (enc && RAND_bytes(qctx->next_iv + arg, qctx->iv_len - arg) <= 0) { WARN("Error while generating random explicit IV\n"); if (!qat_get_sw_fallback_enabled()) QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_RAND_FAILURE); ret = 0; goto sw_ctrl; } qctx->iv_gen = 1; ret = 1; goto sw_ctrl; case EVP_CTRL_GCM_IV_GEN: /* Called in TLS case before encryption */ DEBUG("EVP_CTRL_GCM_IV_GEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (qctx->sw_tls_ctrl != TLS_CIPHER_SW_CTRL) goto sw_ctrl; if (NULL == qctx->iv || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_IV_NULL_PTR_INVALID); return 0; } if (0 == qctx->iv_gen) { WARN("Operation is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_IV_GEN_INVALID); return 0; } /* Set the IV that will be used in the current operation */ memcpy(qctx->iv, qctx->next_iv, qctx->iv_len); if (arg <= 0 || arg > qctx->iv_len) { arg = qctx->iv_len; } /* Copy the explicit IV in the output buffer */ memcpy(ptr, qctx->next_iv + qctx->iv_len - arg, arg); /* Invocation field will be at least 8 bytes in size and * so no need to check wrap around or increment more than * last 8 bytes. */ qat_aes_gcm_inc_ctr(qctx->next_iv + qctx->iv_len - 8); qctx->iv_set = 1; return 1; case EVP_CTRL_GCM_SET_IV_INV: /* Called in TLS case before decryption */ DEBUG("EVP_CTRL_GCM_SET_IV_INV, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (qctx->sw_tls_ctrl != TLS_CIPHER_SW_CTRL) goto sw_ctrl; if (0 == qctx->iv_gen || enc) { WARN("Operation is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_IV_NVALID); return 0; } if (NULL == qctx->iv || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_IV_INVALID); return 0; } /* Retrieve the explicit IV from the message buffer */ memcpy(qctx->next_iv + qctx->iv_len - arg, ptr, arg); /* Set the IV that will be used in the current operation */ memcpy(qctx->iv, qctx->next_iv, qctx->iv_len); qctx->iv_set = 1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: DEBUG("EVP_CTRL_AEAD_TLS1_AAD, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (TLS_VIRT_HDR_SIZE != arg) { WARN("AAD length is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_AAD_LEN_INVALID); return 0; } /* Allocate the memory only the first time */ if (qctx->tls_aad_len < 0) { int aad_buffer_len = TLS_VIRT_HDR_SIZE; DEBUG("Allocating memory for AAD in TLS sync\n"); /* For QAT the length of the buffer for AAD must be multiple * of block size */ if (aad_buffer_len % AES_BLOCK_SIZE) { aad_buffer_len += AES_BLOCK_SIZE - (aad_buffer_len % AES_BLOCK_SIZE); DEBUG("Adjusting AAD buffer length = %d\n", aad_buffer_len); } qctx->aad = qat_mem_alloc(aad_buffer_len, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->aad) { WARN("Unable to allocate memory for TLS header\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_AAD_MALLOC_FAILURE); return 0; } /* Set the flag to mark the TLS case */ qctx->tls_aad_len = TLS_VIRT_HDR_SIZE; /* Set the length of the AAD in the session * The session hasn't been initialized yet here and this value * should never change in the TLS case */ if (qctx->session_data != NULL) qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = TLS_VIRT_HDR_SIZE; } if (NULL == qctx->aad || NULL == ptr) { WARN("Memory pointer is not valid\n"); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_AAD_INVALID_PTR); return 0; } /* Copy the header from p into the buffer */ memcpy(qctx->aad, ptr, TLS_VIRT_HDR_SIZE); /* Extract the length of the payload from the TLS header */ plen = qctx->aad[arg - QAT_GCM_TLS_PAYLOADLENGTH_MSB_OFFSET] << QAT_BYTE_SHIFT | qctx->aad[arg - QAT_GCM_TLS_PAYLOADLENGTH_LSB_OFFSET]; DEBUG("IN plen = %d\n", plen); DUMPL("IN qctx->aad", qctx->aad, TLS_VIRT_HDR_SIZE); /* The payload contains the explicit IV -> correct the length */ plen -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!enc) { plen -= EVP_GCM_TLS_TAG_LEN; } /* Fix the length like in the SW version of GCM */ qctx->aad[TLS_VIRT_HDR_SIZE - QAT_GCM_TLS_PAYLOADLENGTH_MSB_OFFSET] = plen >> QAT_BYTE_SHIFT; qctx->aad[TLS_VIRT_HDR_SIZE - QAT_GCM_TLS_PAYLOADLENGTH_LSB_OFFSET] = plen; DEBUG("OUT plen = %d\n", plen); DUMPL("OUT qctx->aad", qctx->aad, TLS_VIRT_HDR_SIZE); /* Return the length of the TAG */ ret = EVP_GCM_TLS_TAG_LEN; goto sw_ctrl; default: WARN("Invalid type %d\n", type); QATerr(QAT_F_QAT_AES_GCM_CTRL, QAT_R_INVALID_CTRL_TYPE); return -1; } sw_ctrl: #ifndef QAT_OPENSSL_PROVIDER if (qat_get_sw_fallback_enabled()) { if (type != EVP_CTRL_GCM_SET_IV_INV && type != EVP_CTRL_GCM_IV_GEN) EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_sw = EVP_CIPHER_meth_get_ctrl(GET_SW_AES_GCM_CIPHER(ctx)) (ctx, type, arg, ptr); if (type != EVP_CTRL_GCM_SET_IV_INV && type != EVP_CTRL_GCM_IV_GEN) EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (ret_sw <= 0) { WARN("s/w chained ciphers ctrl function failed.\n"); return ret_sw; } return ret_sw; } #endif return ret; } /****************************************************************************** * function: * qat_aes_gcm_cleanup(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_aes_gcm_cleanup(void *ctx) #else int qat_aes_gcm_cleanup(EVP_CIPHER_CTX *ctx) #endif { #ifdef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; # endif QAT_GCM_CTX *qctx = NULL; #else qat_gcm_ctx *qctx = NULL; #endif CpaStatus sts = 0; CpaCySymSessionSetupData* session_data = NULL; CpaBoolean sessionInUse = CPA_FALSE; int ret_val = 1; DEBUG("- Entering\n"); if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_CLEANUP, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_GCM_CTX *)ctx; qctx->iv = (Cpa8U *)qctx->iv; #else qctx = QAT_GCM_GET_CTX(ctx); #endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_CLEANUP, QAT_R_QCTX_NULL); return 0; } /* Wait for in-flight requests before removing session */ if (qctx->qat_ctx != NULL) { do { cpaCySymSessionInUse(qctx->qat_ctx, &sessionInUse); } while (sessionInUse); } session_data = qctx->session_data; if (session_data) { /* Remove the session */ if (qctx->qat_ctx) { if (is_instance_available(qctx->inst_num)) { sts = cpaCySymRemoveSession(qat_instance_handles[qctx->inst_num], qctx->qat_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, sts = %d.!\n", sts); ret_val = 0; /* Lets not return yet and instead make a best effort to * cleanup the rest to avoid memory leaks */ } } /* Cleanup the memory */ QAT_MEM_FREE_NONZERO_BUFF(qctx->qat_ctx, qctx->qat_svm); } if (!qctx->qat_svm) QAT_MEM_FREE_NONZERO_BUFF(qctx->aad, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->srcBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->dstBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->iv, qctx->qat_svm); QAT_MEM_FREE_BUFF(qctx->cipher_key, qctx->qat_svm); QAT_MEM_FREE_BUFF(qctx->OpData.pDigestResult, qctx->qat_svm); #ifdef QAT_OPENSSL_PROVIDER if (qctx->next_iv) { OPENSSL_free(qctx->next_iv); qctx->next_iv = NULL; } #endif session_data->cipherSetupData.pCipherKey = NULL; OPENSSL_clear_free(session_data, sizeof(CpaCySymSessionSetupData)); } qctx->is_session_init = 0; #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif #ifndef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx_cipher_data) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } #else if (qctx->sw_ctx) { OPENSSL_free(qctx->sw_ctx); qctx->sw_ctx = NULL; } #endif return ret_val; } /****************************************************************************** * * function: * * static void qat_gcm_cb(void *pCallbackTag, CpaStatus status, * const CpaCySymOp operationType, * void *pOpData, CpaBufferList *pDstBuffer, * CpaBoolean verifyResult) * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. Cast to op_done_pipe_t. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: Callback to indicate the completion of crypto operation ******************************************************************************/ static void qat_gcm_cb(void *pCallbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList *pDstBuffer, CpaBoolean verifyResult) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); } DEBUG("status is = %d | verifyResult is = %d | tag function called %p \n", status, verifyResult, (struct COMPLETION_STRUCT *)pCallbackTag); qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, verifyResult); } /****************************************************************************** * function: * qat_aes_gcm_session_init(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function synchronises the initialisation of the QAT session and * pre-allocates the necessary buffers for the session. ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_aes_gcm_session_init(void *ctx, int *fallback) #else static int qat_aes_gcm_session_init(EVP_CIPHER_CTX *ctx, int *fallback) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX* qctx = NULL; #else qat_gcm_ctx* qctx = NULL; #endif CpaCySymSessionSetupData *sessionSetupData = NULL; Cpa32U sessionCtxSize = 0; CpaCySymSessionCtx pSessionCtx = NULL; int numBuffers = 1, enc = 0; int sts = -1; DEBUG("- Entering\n"); if (NULL == ctx) { WARN("parameter ctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_GCM_CTX *)ctx; qctx->iv = (Cpa8U *)qctx->iv; enc = QAT_GCM_GET_ENC(qctx); #else qctx = QAT_GCM_GET_CTX(ctx); enc = EVP_CIPHER_CTX_encrypting(ctx); #endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, QAT_R_QCTX_NULL); return 0; } /* All parameters have not been set yet or we have already been * initialised. */ if ((1 != qctx->init_params_set) || (1 == qctx->is_session_init)) { WARN("Parameters not set or session already initialised\n"); if (qat_get_sw_fallback_enabled()) { *fallback = 1; } return 0; } sessionSetupData = qctx->session_data; if (NULL == sessionSetupData) { WARN("sessionSetupData is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, QAT_R_SSD_NULL); return 0; } qctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (qctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } return 0; } qctx->qat_svm = !qat_instance_details[qctx->inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; /* Update digestResultLenInBytes with qctx->tag_len if both lengths are mismatch for decryption */ if (!enc) { DEBUG("digestResultLenInBytes = %d, tag len = %d\n", sessionSetupData->hashSetupData.digestResultLenInBytes, qctx->tag_len); if (!(qctx->tag_len < 0) && sessionSetupData->hashSetupData.digestResultLenInBytes != qctx->tag_len) { sessionSetupData->hashSetupData.digestResultLenInBytes = qctx->tag_len; DEBUG("Taglen updated\n"); } } sts = cpaCySymSessionCtxGetSize(qat_instance_handles[qctx->inst_num], sessionSetupData, &sessionCtxSize); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); if (qat_get_sw_fallback_enabled()) { *fallback = 1; } return 0; } pSessionCtx = (CpaCySymSessionCtx) qat_mem_alloc(sessionCtxSize, qctx->qat_svm, __FILE__, __LINE__); if (NULL == pSessionCtx) { WARN("pSessionCtx malloc failed\n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); return 0; } DUMP_SESSION_SETUP_DATA(sessionSetupData); sts = cpaCySymInitSession(qat_instance_handles[qctx->inst_num], qat_gcm_cb, sessionSetupData, pSessionCtx); if (sts == CPA_STATUS_SUCCESS) { if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } } else { WARN("cpaCySymInitSession failed! Status = %d\n", sts); QAT_MEM_FREE_BUFF(pSessionCtx, qctx->qat_svm); if (qat_get_sw_fallback_enabled() && ((sts == CPA_STATUS_RESTARTING) || (sts == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; return 0; } else { WARN("- No QAT instance available and s/w fallback not enabled.\n"); return 0; } } qctx->qat_ctx = pSessionCtx; /* Setup meta data for buffer lists */ sts = cpaCyBufferListGetMetaSize(qat_instance_handles[qctx->inst_num], numBuffers, &(qctx->meta_size)); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetBufferSize failed.\n"); QAT_MEM_FREE_BUFF(pSessionCtx, qctx->qat_svm); if (qat_get_sw_fallback_enabled()) { *fallback = 1; return 0; } QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); } qctx->srcBufferList.numBuffers = numBuffers; qctx->srcBufferList.pBuffers = &qctx->srcFlatBuffer; qctx->srcBufferList.pUserData = NULL; qctx->dstBufferList.numBuffers = numBuffers; qctx->dstBufferList.pBuffers = &qctx->dstFlatBuffer; qctx->dstBufferList.pUserData = NULL; if (qctx->meta_size) { qctx->srcBufferList.pPrivateMetaData = qat_mem_alloc(qctx->meta_size, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->srcBufferList.pPrivateMetaData) { WARN("srcBufferList.pPrivateMetaData is NULL.\n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); QAT_MEM_FREE_NONZERO_BUFF(pSessionCtx, qctx->qat_svm); return 0; } qctx->dstBufferList.pPrivateMetaData = qat_mem_alloc(qctx->meta_size, qctx->qat_svm, __FILE__, __LINE__); if (NULL == qctx->dstBufferList.pPrivateMetaData) { WARN("dstBufferList.pPrivateMetaData is NULL.\n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, ERR_R_INTERNAL_ERROR); QAT_MEM_FREE_NONZERO_BUFF(qctx->srcBufferList.pPrivateMetaData, qctx->qat_svm); qctx->srcBufferList.pPrivateMetaData = NULL; QAT_MEM_FREE_NONZERO_BUFF(pSessionCtx, qctx->qat_svm); return 0; } } else { qctx->srcBufferList.pPrivateMetaData = NULL; qctx->dstBufferList.pPrivateMetaData = NULL; } /* Create the OpData structure to remove this processing from the data * path */ qctx->OpData.sessionCtx = qctx->qat_ctx; qctx->OpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL; /* Set the IV */ /* Set the AAD */ qctx->OpData.pAdditionalAuthData = qctx->aad; DUMPL("qctx->OpData.pAdditionalAuthData", qctx->OpData.pAdditionalAuthData, qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); /* All the data in the buffer must be encrypted */ qctx->OpData.cryptoStartSrcOffsetInBytes = 0; /* Following parameters are ignored in GCM */ qctx->OpData.messageLenToHashInBytes = 0; qctx->OpData.hashStartSrcOffsetInBytes = 0; qctx->OpData.pDigestResult = qat_mem_alloc(EVP_GCM_TLS_TAG_LEN, qctx->qat_svm,__FILE__, __LINE__); if (qctx->OpData.pDigestResult == NULL) { WARN("Unable to allocate memory for qctx->OpData.pDigestResult \n"); QATerr(QAT_F_QAT_AES_GCM_SESSION_INIT, QAT_R_KEY_MALLOC_FAILURE); QAT_MEM_FREE_NONZERO_BUFF(qctx->srcBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qctx->dstBufferList.pPrivateMetaData, qctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(pSessionCtx, qctx->qat_svm); qctx->srcBufferList.pPrivateMetaData = NULL; qctx->dstBufferList.pPrivateMetaData = NULL; return 0; } qctx->is_session_init = 1; return 1; } /****************************************************************************** * function: * qat_aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * const unsigned char *in, size_t len) * * @param ctx [IN] - pointer to existing context * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval 0 function failed * @retval 1 function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * This is the function used in the TLS case. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_aes_gcm_tls_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) #else int qat_aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = NULL; int nid; QAT_EVP_CIPHER sw_aes_gcm_cipher; #else qat_gcm_ctx *qctx = NULL; #endif CpaStatus sts = 0; op_done_t op_done; int ret_val = -1; int job_ret = 0; int enc = 0; int fallback = 0; unsigned int message_len = 0; unsigned int buffer_len = 0; thread_local_variables_t *tlv = NULL; CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); /* Encrypt/decrypt must be performed in place */ if (NULL == in || out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) { WARN("Input parameters are not valid.\n"); QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, QAT_R_INVALID_LEN); return -1; } if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, QAT_R_CTX_NULL); return -1; } #ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_GCM_CTX *)ctx; qctx->iv = (Cpa8U *)qctx->iv; nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); #else qctx = QAT_GCM_GET_CTX(ctx); #endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, QAT_R_QCTX_NULL); return -1 ; } #ifdef QAT_OPENSSL_PROVIDER enc = QAT_GCM_GET_ENC(qctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void*)ctx, (void*)out, (void*)in, len); /* The key has been set in the init function: no need to check it here*/ /* Initialize the session if not done before */ if (0 == qctx->is_session_init) { #ifdef QAT_OPENSSL_PROVIDER if (0 == qat_aes_gcm_session_init(qctx, &fallback)) { #else if (0 == qat_aes_gcm_session_init(ctx, &fallback)) { #endif WARN("Unable to initialise Cipher context.\n"); goto err; } } /* Encryption: generate explicit IV and write to start of buffer. * Decryption: read the explicit IV from start of buffer */ qctx->sw_tls_ctrl = TLS_CIPHER_SW_CTRL; #ifdef QAT_OPENSSL_PROVIDER if (qat_aes_gcm_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) { WARN("vaesgcm_ciphers_ctrl Failed\n"); qctx->sw_tls_ctrl = 0; goto err; } #else if (EVP_CIPHER_CTX_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) { qctx->sw_tls_ctrl = 0; goto err; } #endif qctx->sw_tls_ctrl = 0; DUMPL("Post ctrl IV: ", qctx->iv, qctx->iv_len); DUMPL("Post ctrl next IV: ", qctx->next_iv, qctx->iv_len); DUMPL("qctx->OpData.pAdditionalAuthData", qctx->OpData.pAdditionalAuthData, qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); /* Set the generated IV to OpData */ if (qctx->iv_set) { qctx->OpData.pIv = qctx->iv; qctx->OpData.ivLenInBytes = qctx->iv_len; } /* If key or IV not set, throw error here and return. */ if (!qctx->key_set || !qctx->iv_set) { WARN("Cipher key or IV not set.\n"); if (qat_get_sw_fallback_enabled()) { fallback = 1; goto err; } QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, QAT_R_KEY_IV_NOT_SET); goto err; } /* Include the explicit part of the IV at the beginning of the output */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; /* This is the length of the message that must be encrypted */ message_len = len - (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN); /* The buffer must have enough memory to save also the TAG */ buffer_len = message_len + EVP_GCM_TLS_TAG_LEN; /* Build request/response buffers */ /* Allocate the memory of the FlatBuffer and copy the payload */ if (!qctx->qat_svm) qctx->srcFlatBuffer.pData = qaeCryptoMemAlloc(buffer_len, __FILE__, __LINE__); else qctx->srcFlatBuffer.pData = (Cpa8U *)in; if (NULL == qctx->srcFlatBuffer.pData) { WARN("src/dst buffer allocation.\n"); goto err; } if (!qctx->qat_svm) qctx->dstFlatBuffer.pData = qctx->srcFlatBuffer.pData; else qctx->dstFlatBuffer.pData = (Cpa8U *)out; if (!enc) { /* Decryption: the tag is appended and must be copied to the buffer */ if (!qctx->qat_svm) memcpy(qctx->srcFlatBuffer.pData, in, message_len); memcpy(qctx->OpData.pDigestResult, in + message_len, EVP_GCM_TLS_TAG_LEN); qctx->tag_len = EVP_GCM_TLS_TAG_LEN; } else { /* Encryption: copy only the payload */ if (!qctx->qat_svm) memcpy(qctx->srcFlatBuffer.pData, in, message_len); } /* The operation is done in place in the buffers * The variables in and out remain separate */ qctx->srcFlatBuffer.dataLenInBytes = message_len; qctx->srcBufferList.pUserData = NULL; qctx->dstFlatBuffer.dataLenInBytes = message_len; qctx->dstBufferList.pUserData = NULL; qctx->OpData.messageLenToCipherInBytes = message_len; tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); DUMP_SYM_PERFORM_OP_GCM_CCM(qat_instance_handles[qctx->inst_num], qctx->OpData, qctx->srcBufferList, qctx->dstBufferList); sts = qat_sym_perform_op(qctx->inst_num, &op_done, &(qctx->OpData), &(qctx->srcBufferList), &(qctx->dstBufferList), &(qctx->session_data->verifyDigest)); if (sts != CPA_STATUS_SUCCESS) { if (!qctx->qat_svm) { qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } qat_cleanup_op_done(&op_done); WARN("cpaCySymPerformOp failed sts=%d.\n",sts); if (qat_get_sw_fallback_enabled() && (sts == CPA_STATUS_RESTARTING || sts == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); } goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_AES_GCM_TLS_CIPHER, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); if (enc && CPA_STATUS_SUCCESS == op_done.status) { #ifdef QAT_OPENSSL_PROVIDER *padlen = len; ret_val = 1; #else ret_val = len; #endif DEBUG("Encryption succeeded\n"); } else if (!enc && CPA_TRUE == op_done.verifyResult) { #ifdef QAT_OPENSSL_PROVIDER *padlen = message_len; ret_val = 1; #else ret_val = message_len; #endif DEBUG("Decryption succeeded\n"); } else { if (enc) DEBUG("Encryption failed\n"); else DEBUG("Decryption failed\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; /* Probably already set anyway */ } } DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(qctx->dstBufferList); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); qat_cleanup_op_done(&op_done); if (fallback) goto err; if (!qctx->qat_svm) { memcpy(out, qctx->dstFlatBuffer.pData, message_len); qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } memcpy(out + message_len, qctx->OpData.pDigestResult, EVP_GCM_TLS_TAG_LEN); DUMPL("pDigestResult", qctx->OpData.pDigestResult, EVP_GCM_TLS_TAG_LEN); err: /* Don't reuse the IV */ qctx->iv_set = 0; if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_GCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); #else sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (sw_aes_gcm_cipher.cupdate == NULL) return 0; if (in != NULL) ret_val = sw_aes_gcm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); else ret_val = sw_aes_gcm_cipher.cfinal(qctx->sw_ctx, out, padlen, outsize); *padlen = len; if (!ret_val) return 0; #endif } return ret_val; } /****************************************************************************** * function: * qat_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * size_t *padlen, const unsigned char *in, * size_t len) * * @param ctx [IN] - pointer to existing context * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval len function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * This is the implementation of the Update case: the AAD is added by calling * UpdateEncrypt() with out == NULL. * This is the case used in the speed test. * * The flag EVP_CIPH_FLAG_CUSTOM_CIPHER is required to have the Update function * working correctly when out == NULL, that is when setting the AAD. * When this flag is enabled, the function must return -1 in case of failure and * the length of the output (value >= 0) for success. * * QAT vs SW Engine * ================ * * In the Update use case, the behavior of the functions is different between * the QAT and the SW engine. * * EVP Function SW Engine QAT Engine * ---------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * * This doesn't impact the TLS case because Update and Final are considered * a single operation like in the QAT engine. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_aes_gcm_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) #else int qat_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = NULL; const int RET_SUCCESS = 1; int nid; QAT_EVP_CIPHER sw_aes_gcm_cipher; #else qat_gcm_ctx *qctx = NULL; const int RET_SUCCESS = 0; #endif CpaStatus sts = 0; op_done_t op_done; const int RET_FAIL = -1; int ret_val = RET_FAIL; int job_ret = 0; int enc = 0; size_t aad_len = 0; int aad_buffer_len = 0; unsigned buffer_len = 0; int fallback = 0; thread_local_variables_t *tlv = NULL; CRYPTO_QAT_LOG("CIPHER - %s\n", __func__); if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_CIPHER, QAT_R_CTX_NULL); return RET_FAIL; } #ifdef QAT_OPENSSL_PROVIDER qctx = (QAT_GCM_CTX *)ctx; qctx->iv = (Cpa8U *)qctx->iv; nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); #else qctx = QAT_GCM_GET_CTX(ctx); #endif if (NULL == qctx) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_AES_GCM_CIPHER, QAT_R_QCTX_NULL); return RET_FAIL; } #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif #ifdef QAT_OPENSSL_PROVIDER enc = QAT_GCM_GET_ENC(qctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void*)ctx, (void*)out, (void*)in, len); /* Distinguish the Update and TLS case */ if (qctx->tls_aad_len >= 0) { #ifdef QAT_OPENSSL_PROVIDER return qat_aes_gcm_tls_cipher(ctx, out, padlen, outsize, in, len); #else return qat_aes_gcm_tls_cipher(ctx, out, in, len); #endif } /* If either key or IV not set, throw error here. */ if (!qctx->key_set || !qctx->iv_set) { WARN("Cipher key or IV not set.\n"); if (qat_get_sw_fallback_enabled()) { fallback = 1; ret_val = RET_FAIL; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto err; } QATerr(QAT_F_QAT_AES_GCM_CIPHER, QAT_R_KEY_IV_NOT_SET); return RET_FAIL; } if (in) { /* This is called when doing Update */ if (NULL == out) { DEBUG("in != NULL && out == NULL -> Adding AAD\n"); aad_len = len; /* Check if the length of the AAD has changed */ if (qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes != aad_len) { /* Free the memory used for the previous AAD */ if (qctx->aad) { if (!qctx->qat_svm) qaeCryptoMemFreeNonZero(qctx->aad); qctx->aad = NULL; } /* For QAT the length of the buffer for AAD must be multiple of block size */ aad_buffer_len = aad_len; if (aad_buffer_len % AES_BLOCK_SIZE) { aad_buffer_len += AES_BLOCK_SIZE - (aad_buffer_len % AES_BLOCK_SIZE); DEBUG("Adjusting AAD buffer length = %d\n", aad_buffer_len); } if (!qctx->qat_svm) { qctx->aad = qaeCryptoMemAlloc(aad_buffer_len, __FILE__, __LINE__); if (NULL == qctx->aad) { WARN("Unable to allocate memory for AAD\n"); QATerr(QAT_F_QAT_AES_GCM_CIPHER, ERR_R_INTERNAL_ERROR); goto err; } } /* Set the length of the AAD */ qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes = aad_len; } #ifdef QAT_OPENSSL_PROVIDER *padlen = aad_len; #endif if (!qctx->qat_svm) memcpy(qctx->aad, in, aad_len); else qctx->aad = (Cpa8U *) in; DUMPL("qctx->aad", qctx->aad, aad_len); /* The pAdditionalAuthData will be initialized firstly in * qat_aes_gcm_session_init(), but the AAD can be updated * for several times. So it is very important to update the * AAD pointer in qat OpData structure in time. */ qctx->OpData.pAdditionalAuthData = qctx->aad; /* In this case no data is actually encrypted/decrypted. * The return value follows the standard rule of OpenSSL: success -> 1 */ if (qat_get_sw_fallback_enabled()) { fallback = 1; ret_val = 1; goto err; } return 1; } else { /* The key has been set in the init function: no need to check it */ if (0 == qctx->is_session_init) { #ifdef QAT_OPENSSL_PROVIDER if (0 == qat_aes_gcm_session_init(qctx, &fallback)) { #else if (0 == qat_aes_gcm_session_init(ctx, &fallback)) { #endif WARN("Unable to initialise Cipher context.\n"); if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); goto err; } return RET_FAIL; } } /* Update buffer length as tag length if input buffer length is zero */ if (len == 0) buffer_len = EVP_GCM_TLS_TAG_LEN; else buffer_len = len; /* Build request/response buffers */ /* Allocate the memory of the FlatBuffer and copy the payload */ if (!qctx->qat_svm) qctx->srcFlatBuffer.pData = qaeCryptoMemAlloc(buffer_len, __FILE__, __LINE__); else qctx->srcFlatBuffer.pData = (Cpa8U *)in; if (NULL == qctx->srcFlatBuffer.pData) { WARN("src/dst buffer allocation.\n"); QATerr(QAT_F_QAT_AES_GCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } if (!qctx->qat_svm) { qctx->dstFlatBuffer.pData = qctx->srcFlatBuffer.pData; memcpy(qctx->srcFlatBuffer.pData, in, len); } else { qctx->dstFlatBuffer.pData = (Cpa8U *)out; } /* The operation is done in place in the buffers * The variables in and out remain separate */ qctx->srcFlatBuffer.dataLenInBytes = buffer_len; qctx->srcBufferList.pUserData = NULL; qctx->dstFlatBuffer.dataLenInBytes = buffer_len; qctx->dstBufferList.pUserData = NULL; qctx->OpData.messageLenToCipherInBytes = len; /* Decryption: set the digest (tag) for verification * This is different from SW implementation. Here we have a single * function to decrypt AND verify */ if (!enc) { /* Copy EVP_GCM_TLS_TAG_LEN bytes from tag buffer as the maximum tag length can only be EVP_GCM_TLS_TAG_LEN */ #ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->OpData.pDigestResult, qctx->buf, EVP_GCM_TLS_TAG_LEN); #else if (NULL == EVP_CIPHER_CTX_buf_noconst(ctx)) { WARN("Tag not set\n"); if (!qctx->qat_svm) { qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } return RET_FAIL; } else { memcpy(qctx->OpData.pDigestResult, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_GCM_TLS_TAG_LEN); } #endif } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_AES_GCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); qat_cleanup_op_done(&op_done); QATerr(QAT_F_QAT_AES_GCM_CIPHER, ERR_R_INTERNAL_ERROR); return RET_FAIL; } } DUMP_SYM_PERFORM_OP_GCM_CCM(qat_instance_handles[qctx->inst_num], qctx->OpData, qctx->srcBufferList, qctx->dstBufferList); DUMPL("AAD: ", qctx->OpData.pAdditionalAuthData, qctx->session_data->hashSetupData.authModeSetupData.aadLenInBytes); sts = qat_sym_perform_op(qctx->inst_num, &op_done, &(qctx->OpData), &(qctx->srcBufferList), &(qctx->dstBufferList), &(qctx->session_data->verifyDigest)); if (sts != CPA_STATUS_SUCCESS) { if (!qctx->qat_svm) { qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } qat_cleanup_op_done(&op_done); WARN("cpaCySymPerformOp failed sts=%d.\n",sts); if (qat_get_sw_fallback_enabled() && (sts == CPA_STATUS_RESTARTING || sts == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } else { QATerr(QAT_F_QAT_AES_GCM_CIPHER, ERR_R_INTERNAL_ERROR); } goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_AES_GCM_CIPHER, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, 0)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(qctx->dstBufferList); if (enc && op_done.status == CPA_STATUS_SUCCESS) { ret_val = len; DEBUG("Encryption succeeded\n"); } else if (!enc && (CPA_TRUE == op_done.verifyResult)) { ret_val = len; DEBUG("Decryption succeeded\n"); } else { if (enc) DEBUG("Encryption failed\n"); else DEBUG("Decryption failed\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG( "Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; /* Probably already set anyway */ WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); } } QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); qat_cleanup_op_done(&op_done); if (fallback) goto err; if (enc) { /* After encryption, copy the TAG from the buffer to the ctx */ #ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->buf, qctx->OpData.pDigestResult, EVP_GCM_TLS_TAG_LEN); DUMPL("TAG calculated by QAT", qctx->buf, 16); #else memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), qctx->OpData.pDigestResult, EVP_GCM_TLS_TAG_LEN); DUMPL("TAG calculated by QAT", EVP_CIPHER_CTX_buf_noconst(ctx), 16); #endif qctx->tag_len = EVP_GCM_TLS_TAG_LEN; qctx->tag_set = 1; } if (!qctx->qat_svm) { memcpy(out, qctx->dstFlatBuffer.pData, len); qaeCryptoMemFreeNonZero(qctx->srcFlatBuffer.pData); qctx->srcFlatBuffer.pData = NULL; qctx->dstFlatBuffer.pData = NULL; } #ifdef QAT_OPENSSL_PROVIDER *padlen = len; #endif return ret_val; } } else { /* This is executed when Final is called */ if (!enc) { # if OPENSSL_VERSION_NUMBER < 0x30200000 if (qctx->tag_len < 0) { return RET_FAIL; } # endif /* Don't reuse the IV */ qctx->iv_set = 0; if (qat_get_sw_fallback_enabled() && !qctx->tag_set) { fallback = 1; } DEBUG("Decrypt Final()\n"); /* The SW implem here compares the TAGs and returns -1 if they are different. * Now the TAGs are checked when decrypting the payload so Final always return success */ ret_val = RET_SUCCESS; goto err; } DEBUG("Encrypt Final()\n"); /* The SW implem here copy the TAG to ctx->buf so that it can be * retrieved using ctrl() with GET_TAG. * Now the TAG is appended and has already been copied to that location * hence we do nothing. */ /* Don't reuse the IV */ qctx->iv_set = 0; if (qat_get_sw_fallback_enabled() && !qctx->tag_set) fallback = 1; ret_val = RET_SUCCESS; } err: if (fallback) { #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_do_cipher(GET_SW_AES_GCM_CIPHER(ctx)) (ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); #else sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (sw_aes_gcm_cipher.cupdate == NULL) return 0; if (in != NULL) ret_val = sw_aes_gcm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); else ret_val = sw_aes_gcm_cipher.cfinal(qctx->sw_ctx, out, padlen, outsize); *padlen = len; if (!ret_val) return RET_FAIL; #endif } return ret_val; } #endif qatengine-1.9.0/qat_hw_gcm.h000066400000000000000000000151571500416242000157610ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_gcm.h * * This file provides a interface for AES-GCM operations * *****************************************************************************/ #ifndef QAT_HW_GCM_H #define QAT_HW_GCM_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "cpa_cy_drbg.h" #ifdef QAT_OPENSSL_PROVIDER #include "qat_prov_ciphers.h" #endif # define AES_GCM_IV_LEN 12 # define QAT_GCM_GET_CTX(ctx) (EVP_CIPHER_CTX_get_cipher_data(ctx)) # define QAT_GCM_GET_ENC(ctx) ((ctx)->enc) # define QAT_GCM_TLS_TOTAL_IV_LEN (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN) # define QAT_GCM_TLS_PAYLOADLENGTH_MSB_OFFSET 2 # define QAT_GCM_TLS_PAYLOADLENGTH_LSB_OFFSET 1 /* The length of valid GCM Tag must be between 0 and 16 Bytes */ # define QAT_GCM_TAG_MIN_LEN 0 # define QAT_GCM_TAG_MAX_LEN 16 # define QAT_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_GCM_MODE \ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_AEAD_CIPHER \ | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT) # define GET_SW_AES_GCM_CIPHER(ctx) \ qat_gcm_cipher_sw_impl(EVP_CIPHER_CTX_type(ctx)) #define TLS_CIPHER_SW_CTRL 0x004d /* AES-GCM context */ typedef struct qat_aes_gcm_ctx_t { /* QAT Session Params */ int inst_num; CpaCySymSessionSetupData* session_data; CpaCySymSessionCtx qat_ctx; int init_params_set; /* This flag is set to 1 when the session has been initialized */ int is_session_init; /* QAT Op Params */ CpaCySymOpData OpData; /* TODO Both buffer point to the same area of memory * and the operation is done in place. * Why am I using 2 separate buffers instead of one like in GCM sample? * Do I need to allocate and use separate metadata? */ CpaBufferList srcBufferList; CpaBufferList dstBufferList; CpaFlatBuffer srcFlatBuffer; CpaFlatBuffer dstFlatBuffer; /* -- Crypto -- */ /* Pointer to the IV that is used in the current operation: * - In Sync case this points to the contiguous memory buffer that is * sent to the HW * - In asynch this point to the static memory in evp_ctx->iv hence it * must not be alloc or free */ Cpa8U *iv; /* IV that will be used in the next operation: * In the SW engine the IV in the context and the IV used by the cipher * are stored in different variables. * This is a separate value and can be modified without affecting * the current operation. * For example: TLS case increment the IV before doing the encryption, * but the current operation still used the not-incremented IV */ Cpa8U next_iv[EVP_MAX_IV_LENGTH]; /* Length of the IV (it is always 12 Byte for GCM in TLS case */ unsigned int iv_len; /* Flag that indicates whether the IV has been set * TODO The value is set correctly but never read and actually used... */ unsigned char iv_set; /* This flag is used to control the generation of the IV */ unsigned char iv_gen; /* The tag is saved in evp_ctx->buf */ int tag_len; /* Pointer to AAD. * In the TLS case this will contain the TLS header */ Cpa8U *aad; /* -- TLS data -- */ /* Length of the AAD in the TLS case. * This is used like a flag: when Update case this is set to -1*/ int tls_aad_len; /* Size of the meta data for the driver * It cannot allocate memory so this must be done by the user application */ unsigned int meta_size; /* Pointer to pCipherKey */ Cpa8U *cipher_key; /* Flag to keep track of key passed */ int key_set; int qat_svm; void *sw_ctx_cipher_data; int fallback; int sw_tls_ctrl; int tag_set; } qat_gcm_ctx; #ifdef QAT_OPENSSL_PROVIDER int qat_aes_gcm_init(QAT_GCM_CTX *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_aes_gcm_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len); int qat_aes_gcm_ctrl(void *ctx, int type, int arg, void *ptr); int qat_aes_gcm_cleanup(void *ctx); #else int qat_aes_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc); int qat_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_aes_gcm_cleanup(EVP_CIPHER_CTX *ctx); int qat_aes_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); #endif #endif /* QAT_HW_GCM_H */ qatengine-1.9.0/qat_hw_hkdf.c000066400000000000000000001122251500416242000161140ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2019-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hkdf.c * * This file provides an implementation of the HKDF operations for an * OpenSSL engine * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include "openssl/ossl_typ.h" #include "openssl/kdf.h" #include "openssl/evp.h" #include "openssl/ssl.h" #include "qat_evp.h" #include "qat_utils.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_hw_hkdf.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_key.h" #ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; #endif /* These limits are based on QuickAssist limits. * OpenSSL is more generous but better to restrict and fail * early on here if they are exceeded rather than later on * down in the driver. */ #define QAT_HKDF_INFO_MAXBUF 1024 /* Have a store of the s/w EVP_PKEY_METHOD for software fallback purposes. */ #ifndef QAT_OPENSSL_3 /* Only for OpenSSL 1.1.1. For OpenSSL 3, we use the default provider for SW fallback */ static const EVP_PKEY_METHOD *sw_hkdf_pmeth = NULL; #endif static EVP_PKEY_METHOD *_hidden_hkdf_pmeth = NULL; #ifdef ENABLE_QAT_HW_HKDF void qat_hkdf_pkey_methods(void) { EVP_PKEY_meth_set_init(_hidden_hkdf_pmeth, qat_hkdf_init); EVP_PKEY_meth_set_cleanup(_hidden_hkdf_pmeth, qat_hkdf_cleanup); #ifndef QAT_OPENSSL_PROVIDER EVP_PKEY_meth_set_derive(_hidden_hkdf_pmeth, NULL, qat_hkdf_derive); #endif EVP_PKEY_meth_set_ctrl(_hidden_hkdf_pmeth, qat_hkdf_ctrl, NULL); } #endif EVP_PKEY_METHOD *qat_hkdf_pmeth(void) { if (_hidden_hkdf_pmeth) { if (!qat_reload_algo) return _hidden_hkdf_pmeth; EVP_PKEY_meth_free(_hidden_hkdf_pmeth); } if ((_hidden_hkdf_pmeth = EVP_PKEY_meth_new(EVP_PKEY_HKDF, 0)) == NULL) { QATerr(QAT_F_QAT_HKDF_PMETH, ERR_R_INTERNAL_ERROR); return NULL; } #ifndef QAT_OPENSSL_3 /* Now save the current (non-offloaded) hkdf pmeth to sw_hkdf_pmeth */ /* for software fallback purposes */ if ((sw_hkdf_pmeth = EVP_PKEY_meth_find(EVP_PKEY_HKDF)) == NULL) { QATerr(QAT_F_QAT_HKDF_PMETH, ERR_R_INTERNAL_ERROR); return NULL; } #endif #ifdef ENABLE_QAT_HW_HKDF if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_HKDF)) { qat_hkdf_pkey_methods(); qat_hw_hkdf_offload = 1; DEBUG("QAT HW HKDF Registration succeeded\n"); } else { qat_hw_hkdf_offload = 0; } #endif if (!qat_hw_hkdf_offload) { #ifndef QAT_OPENSSL_PROVIDER DEBUG("QAT HW HKDF is disabled, using OpenSSL SW\n"); #endif #ifndef QAT_OPENSSL_3 EVP_PKEY_meth_copy(_hidden_hkdf_pmeth, sw_hkdf_pmeth); #else /* Although QATEngine supports software fallback to the default provider when * using the OpenSSL 3 legacy engine API, if it fails during the registration * phase, the pkey method cannot be set correctly because the OpenSSL3 legacy * engine framework no longer provides a standard method for HKDF, PRF and SM2. * https://github.com/openssl/openssl/issues/19047 */ # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) # ifdef ENABLE_QAT_HW_HKDF qat_openssl3_hkdf_fallback = 1; qat_hkdf_pkey_methods(); return _hidden_hkdf_pmeth; # endif # endif EVP_PKEY_meth_free(_hidden_hkdf_pmeth); return NULL; #endif } return _hidden_hkdf_pmeth; } #ifdef ENABLE_QAT_HW_HKDF /****************************************************************************** * function: * qat_hkdf_init(EVP_PKEY_CTX *ctx) * * @param ctx [IN] - PKEY Context structure pointer * * @param [OUT] - Status * * description: * Qat HKDF init function ******************************************************************************/ int qat_hkdf_init(EVP_PKEY_CTX *ctx) { QAT_HKDF_CTX *qat_hkdf_ctx = NULL; int inst_num = QAT_INVALID_INSTANCE; #ifndef QAT_OPENSSL_3 int (*sw_init_fn_ptr)(EVP_PKEY_CTX *) = NULL; int ret = 0; #endif if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); QATerr(QAT_F_QAT_HKDF_INIT, ERR_R_INTERNAL_ERROR); return 0; } qat_hkdf_ctx = OPENSSL_zalloc(sizeof(*qat_hkdf_ctx)); if (qat_hkdf_ctx == NULL) { WARN("Cannot allocate qat_hkdf_ctx\n"); QATerr(QAT_F_QAT_HKDF_INIT, ERR_R_MALLOC_FAILURE); return 0; } if ((inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); } qat_hkdf_ctx->qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; #ifndef QAT_OPENSSL_3 /* Software Ctrl functions are called here */ QAT_HKDF_PKEY_CTX *kctx; EVP_PKEY_meth_get_init((EVP_PKEY_METHOD *)sw_hkdf_pmeth, &sw_init_fn_ptr); kctx = OPENSSL_zalloc(sizeof(*kctx)); qat_hkdf_ctx->sw_hkdf_ctx_data = kctx; EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx->sw_hkdf_ctx_data); ret = (*sw_init_fn_ptr)(ctx); if (ret != 1) { WARN("s/w hkdf_init fn failed.\n"); QATerr(QAT_F_QAT_HKDF_INIT, ERR_R_INTERNAL_ERROR); return ret; } EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx); #endif qat_hkdf_ctx->hkdf_op_data = (CpaCyKeyGenHKDFOpData *) qat_mem_alloc(sizeof(CpaCyKeyGenHKDFOpData), qat_hkdf_ctx->qat_svm, __FILE__, __LINE__); if (NULL == qat_hkdf_ctx->hkdf_op_data) { WARN("Failed to allocate memory for hkdf_op_data\n"); QATerr(QAT_F_QAT_HKDF_INIT, ERR_R_MALLOC_FAILURE); return 0; } memset(qat_hkdf_ctx->hkdf_op_data, 0, sizeof(CpaCyKeyGenHKDFOpData)); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx); return 1; } /****************************************************************************** * function: * qat_hkdf_cleanup(EVP_PKEY_CTX *ctx) * * @param ctx [IN] - PKEY Context structure pointer * * description: * Clear the QAT specific data stored in qat_hkdf_ctx ******************************************************************************/ void qat_hkdf_cleanup(EVP_PKEY_CTX *ctx) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif QAT_HKDF_CTX *qat_hkdf_ctx = NULL; #ifndef QAT_OPENSSL_3 void (*sw_cleanup_fn_ptr)(EVP_PKEY_CTX *) = NULL; #endif if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return; } qat_hkdf_ctx = (QAT_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx); if (qat_hkdf_ctx == NULL) { WARN("qat_hkdf_ctx is NULL\n"); return; } #ifndef QAT_OPENSSL_3 if (qat_hkdf_ctx->fallback == 1 || qat_get_qat_offload_disabled() || qat_get_sw_fallback_enabled()) { DEBUG("- Switched to software mode or fallback mode enabled.\n"); /* Clean up the sw_hkdf_ctx_data created by the init function */ EVP_PKEY_meth_get_cleanup((EVP_PKEY_METHOD *)sw_hkdf_pmeth, &sw_cleanup_fn_ptr); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx->sw_hkdf_ctx_data); (*sw_cleanup_fn_ptr)(ctx); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx); } #else /* Cleanup the memory used for sw fallback */ OPENSSL_cleanse(qat_hkdf_ctx->sw_ikm, qat_hkdf_ctx->sw_ikm_size); OPENSSL_cleanse(qat_hkdf_ctx->sw_info, qat_hkdf_ctx->sw_info_size); OPENSSL_cleanse(qat_hkdf_ctx->sw_salt, qat_hkdf_ctx->sw_salt_size); #endif if (qat_hkdf_ctx->hkdf_op_data) { if (qat_hkdf_ctx->hkdf_op_data->seedLen) OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->seed, qat_hkdf_ctx->hkdf_op_data->seedLen); if (qat_hkdf_ctx->hkdf_op_data->secretLen) OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->secret, qat_hkdf_ctx->hkdf_op_data->secretLen); if (qat_hkdf_ctx->hkdf_op_data->infoLen) OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->info, qat_hkdf_ctx->hkdf_op_data->infoLen); if (qat_hkdf_ctx->hkdf_op_data->label[0].labelLen) { OPENSSL_cleanse(&qat_hkdf_ctx->hkdf_op_data->label[0], qat_hkdf_ctx->hkdf_op_data->label[0].labelLen); qat_hkdf_ctx->hkdf_op_data->numLabels = 0; } QAT_MEM_FREE_NONZERO_BUFF(qat_hkdf_ctx->hkdf_op_data, qat_hkdf_ctx->qat_svm); } qat_hkdf_ctx->fallback = 0; #ifdef QAT_OPENSSL_PROVIDER OPENSSL_free(qat_hkdf_ctx->prefix); qat_hkdf_ctx->prefix = NULL; OPENSSL_free(qat_hkdf_ctx->data); qat_hkdf_ctx->data = NULL; OPENSSL_free(qat_hkdf_ctx->label); qat_hkdf_ctx->label = NULL; #endif OPENSSL_free(qat_hkdf_ctx); EVP_PKEY_CTX_set_data(ctx, NULL); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } /****************************************************************************** * function: * qat_hkdf_ctrl(EVP_PKEY_CTX *ctx, * int type, * int p1, * void *p2) * * @param ctx [IN] - PKEY Context structure pointer * @param type [IN] - Type * @param p1 [IN] - Length/Size * @param *p2 [IN] - Data * * @param [OUT] - Status * * description: * Qat HKDF control function ******************************************************************************/ int qat_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (unlikely(ctx == NULL)) { WARN("Invalid input param.\n"); return 0; } QAT_HKDF_CTX *qat_hkdf_ctx = (QAT_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx); #ifndef QAT_OPENSSL_3 int (*sw_ctrl_fn_ptr)(EVP_PKEY_CTX *, int, int, void *) = NULL; int ret = 0; #endif if (unlikely(qat_hkdf_ctx == NULL)) { WARN("qat_hkdf_ctx cannot be NULL\n"); return 0; } #ifndef QAT_OPENSSL_3 /* Software Ctrl functions are called here */ EVP_PKEY_meth_get_ctrl((EVP_PKEY_METHOD *)sw_hkdf_pmeth, &sw_ctrl_fn_ptr, NULL); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx->sw_hkdf_ctx_data); ret = (*sw_ctrl_fn_ptr)(ctx, type, p1, p2); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx); if (ret != 1) { WARN("S/W hkdf_ctrl fn failed\n"); return ret; } #endif switch (type) { case EVP_PKEY_CTRL_HKDF_MD: if (unlikely(p2 == NULL)) { WARN("Invalid input param.\n"); return 0; } qat_hkdf_ctx->qat_md = p2; return 1; case EVP_PKEY_CTRL_HKDF_MODE: qat_hkdf_ctx->mode = p1; return 1; case EVP_PKEY_CTRL_HKDF_SALT: if (p1 == 0 || p2 == NULL) return 1; if (p1 < 0) { WARN("Input param p1 length less than zero\n"); return 0; } if (qat_hkdf_ctx->hkdf_op_data == NULL) { WARN("hkdf_op_data is NULL\n"); return 0; } #ifdef QAT_OPENSSL_3 /* Setup the sw fallback parameters */ OPENSSL_cleanse(qat_hkdf_ctx->sw_salt, QAT_KDF_MAX_SEED_SZ); memcpy(qat_hkdf_ctx->sw_salt, p2, p1); qat_hkdf_ctx->sw_salt_size = p1; #endif OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->seed, qat_hkdf_ctx->hkdf_op_data->seedLen); qat_hkdf_ctx->hkdf_op_data->seedLen = 0; memcpy(qat_hkdf_ctx->hkdf_op_data->seed, p2, p1); qat_hkdf_ctx->hkdf_op_data->seedLen = p1; return 1; case EVP_PKEY_CTRL_HKDF_KEY: if (p1 < 0) { WARN("Input param p1 length less than zero\n"); return 0; } if (qat_hkdf_ctx->hkdf_op_data == NULL) { WARN("hkdf_op_data is NULL\n"); return 0; } #ifdef QAT_OPENSSL_3 /* Setup the sw fallback parameters */ OPENSSL_cleanse(qat_hkdf_ctx->sw_ikm, QAT_KDF_MAX_KEY_SZ); memcpy(qat_hkdf_ctx->sw_ikm, p2, p1); qat_hkdf_ctx->sw_ikm_size = p1; #endif OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->secret, qat_hkdf_ctx->hkdf_op_data->secretLen); qat_hkdf_ctx->hkdf_op_data->secretLen = 0; memcpy(qat_hkdf_ctx->hkdf_op_data->secret, p2, p1); qat_hkdf_ctx->hkdf_op_data->secretLen = p1; return 1; case EVP_PKEY_CTRL_HKDF_INFO: if (p1 == 0 || p2 == NULL) return 1; if (qat_hkdf_ctx->hkdf_op_data == NULL) { WARN("hkdf_op_data is NULL\n"); return 0; } if (p1 < 0 || p1 > (int) QAT_HKDF_INFO_MAXBUF - qat_hkdf_ctx->hkdf_op_data->infoLen) { WARN("info p1 %d is out of range\n", p1); return 0; } #ifdef QAT_OPENSSL_3 /* Setup the sw fallback parameters */ OPENSSL_cleanse(qat_hkdf_ctx->sw_info, QAT_KDF_MAX_INFO_SZ); memcpy(qat_hkdf_ctx->sw_info, p2, p1); qat_hkdf_ctx->sw_info_size = p1; #endif OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->info, qat_hkdf_ctx->hkdf_op_data->infoLen); qat_hkdf_ctx->hkdf_op_data->infoLen = 0; memcpy(qat_hkdf_ctx->hkdf_op_data->info, p2, p1); qat_hkdf_ctx->hkdf_op_data->infoLen = p1; return 1; #ifdef QAT_OPENSSL_PROVIDER case EVP_PKEY_CTRL_HKDF_PREFIX: if (p1 == 0 || p2 == NULL) return 1; if (qat_hkdf_ctx->hkdf_op_data == NULL) { WARN("hkdf_op_data is NULL\n"); return 0; } qat_hkdf_ctx->prefix = OPENSSL_zalloc(p1); if (qat_hkdf_ctx->prefix == NULL) { WARN("Cannot allocate qat_hkdf_ctx\n"); QATerr(QAT_F_QAT_HKDF_CTRL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(qat_hkdf_ctx->prefix, p2, p1); qat_hkdf_ctx->prefix_len = p1; return 1; case EVP_PKEY_CTRL_HKDF_DATA: if (p1 == 0 || p2 == NULL) return 1; if (qat_hkdf_ctx->hkdf_op_data == NULL) { WARN("hkdf_op_data is NULL\n"); return 0; } qat_hkdf_ctx->data = OPENSSL_zalloc(p1); if (qat_hkdf_ctx->data == NULL) { WARN("Cannot allocate qat_hkdf_ctx\n"); QATerr(QAT_F_QAT_HKDF_CTRL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(qat_hkdf_ctx->data, p2, p1); qat_hkdf_ctx->data_len = p1; return 1; case EVP_PKEY_CTRL_HKDF_LABEL: if (p1 == 0 || p2 == NULL) return 1; if (qat_hkdf_ctx->hkdf_op_data == NULL) { WARN("hkdf_op_data is NULL\n"); return 0; } qat_hkdf_ctx->hkdf_op_data->numLabels = 1; qat_hkdf_ctx->label = OPENSSL_zalloc(p1); qat_hkdf_ctx->label_len = p1; if (qat_hkdf_ctx->label == NULL) { WARN("Cannot allocate qat_hkdf_ctx\n"); QATerr(QAT_F_QAT_HKDF_CTRL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(qat_hkdf_ctx->label, p2, p1); return 1; #endif default: WARN("Invalid type %d\n", type); return -2; } /* switch */ } /****************************************************************************** * function: * void qat_hkdf_cb(void *pCallbackTag, * CpaStatus status, * void *pOpdata, * CpaFlatBuffer *pOut) * * @param pCallbackTag [IN] - Pointer to user data * @param status [IN] - Status of the operation * @param pOpData [IN] - Pointer to operation data of the request * @param out [IN] - Pointer to the output buffer * * description: * Callback to indicate the completion of HKDF ******************************************************************************/ static void qat_hkdf_cb(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer * pOut) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_kdf_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } /****************************************************************************** * function: * qat_get_cipher_suite(QAT_HKDF_CTX *qat_hkdf_ctx) * * @param qat_hkdf_ctx [IN] - HKDF context * @param cipher_suite [OUT] - Ptr to cipher suite in CPA format * * description: * Retrieve the cipher suite from the hkdf context and convert it to * the CPA format ******************************************************************************/ int qat_get_cipher_suite(QAT_HKDF_CTX * qat_hkdf_ctx) { const EVP_MD *md = NULL; if (qat_hkdf_ctx == NULL) { WARN("qat_hkdf_ctx %p is NULL.\n", qat_hkdf_ctx); return 0; } md = qat_hkdf_ctx->qat_md; if (md == NULL) { WARN("md is NULL.\n"); return 0; } switch (EVP_MD_type(md)) { case NID_sha256: qat_hkdf_ctx->cipher_suite = CPA_CY_HKDF_TLS_AES_128_GCM_SHA256; break; case NID_sha384: qat_hkdf_ctx->cipher_suite = CPA_CY_HKDF_TLS_AES_256_GCM_SHA384; break; #if defined(QAT20_OOT) case NID_sm3: WARN("HKDF based on SM3 not supported\n"); return 0; #endif default: WARN("Unsupported HKDF hash type\n"); return 0; } return 1; } /****************************************************************************** * function: * qat_set_hkdf_mode(HKDF *qat_hkdf_ctx) * * @param qat_hkdf_ctx [IN] - HKDF context * * description: * Set the mode into hkdf_op_data from the hkdf context ******************************************************************************/ static int qat_set_hkdf_mode(QAT_HKDF_CTX * qat_hkdf_ctx) { if (qat_hkdf_ctx == NULL) { WARN("Either qat_hkdf_ctx %p is NULL\n", qat_hkdf_ctx); return 0; } switch (qat_hkdf_ctx->mode) { case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp = CPA_CY_HKDF_KEY_EXTRACT; break; case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: #ifdef QAT_OPENSSL_PROVIDER if (!strcmp((const char*)kdf_name, "HKDF")) qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp = CPA_CY_HKDF_KEY_EXPAND; if(!strcmp((const char*)kdf_name, "TLS13-KDF")) qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp = CPA_CY_HKDF_KEY_EXPAND_LABEL; #else qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp = CPA_CY_HKDF_KEY_EXPAND; #endif break; case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp = CPA_CY_HKDF_KEY_EXTRACT_EXPAND; break; default: WARN("Unknown HKDF mode \n"); return 0; } return 1; } #ifdef QAT_OPENSSL_3 /****************************************************************************** * function: * default_provider_HKDF_derive(QAT_HKDF_CTX *qat_hkdf_ctx, * unsigned char *out, * size_t olen) * * @param qat_hkdf_ctx [IN] - HKDF context * @param out [OUT] - Ptr to the key that will be generated * @param olen [IN] - Length of the key * * description: * HKDF SW fallback function. Using default provider of OpenSSL 3 ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int default_provider_HKDF_derive(QAT_HKDF_CTX *qat_hkdf_ctx, unsigned char *out, size_t olen, const OSSL_PARAM params[]) { #else int default_provider_HKDF_derive(QAT_HKDF_CTX *qat_hkdf_ctx, unsigned char *out, size_t olen) { #endif int rv = 0; EVP_KDF *kdf = NULL; EVP_KDF_CTX *kctx = NULL; #ifndef QAT_OPENSSL_PROVIDER OSSL_PARAM params[6], *p = params; char *mode = NULL; const char *mdname; /* Fetch the key derivation function implementation */ kdf = EVP_KDF_fetch(NULL, "HKDF", "provider=default"); #else kdf = EVP_KDF_fetch(NULL, "TLS13-KDF", "provider=default"); #endif if (kdf == NULL) { fprintf(stderr, "EVP_KDF_fetch() returned NULL\n"); goto end; } /* Create a context for the key derivation operation */ kctx = EVP_KDF_CTX_new(kdf); if (kctx == NULL) { fprintf(stderr, "EVP_KDF_CTX_new() returned NULL\n"); goto end; } #ifndef QAT_OPENSSL_PROVIDER switch (qat_hkdf_ctx->mode) { case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: mode = "EXTRACT_ONLY"; break; case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: mode = "EXPAND_ONLY"; break; case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: mode = "EXTRACT_AND_EXPAND"; break; default: WARN("Unknown HKDF mode \n"); return 0; } mdname = EVP_MD_get0_name(qat_hkdf_ctx->qat_md); /* Set the underlying hash function used to derive the key */ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); /* Set input keying material */ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, qat_hkdf_ctx->sw_ikm, qat_hkdf_ctx->sw_ikm_size); /* Set application specific information */ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, qat_hkdf_ctx->sw_info, qat_hkdf_ctx->sw_info_size); /* Set mode */ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, mode, 0); /* Set salt */ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, qat_hkdf_ctx->sw_salt, qat_hkdf_ctx->sw_salt_size); *p = OSSL_PARAM_construct_end(); #endif /* Derive the key */ if (EVP_KDF_derive(kctx, out, olen, params) != 1) { fprintf(stderr, "EVP_KDF_derive() failed\n"); goto end; } rv = 1; end: EVP_KDF_CTX_free(kctx); EVP_KDF_free(kdf); return rv; } #endif /****************************************************************************** * function: * qat_hkdf_derive(QAT_HKDF_CTX *qat_hkdf_ctx, * unsigned char *key, * size_t *olen) * * @param qat_hkdf_ctx [IN] - HKDF context * @param key [OUT] - Ptr to the key that will be generated * @param olen [IN] - Length of the key * * description: * HKDF derive function for TLS case ******************************************************************************/ #ifndef QAT_OPENSSL_PROVIDER int qat_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *olen) #else int qat_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *olen, const OSSL_PARAM params[]) #endif { int ret = 0, job_ret = 0; CpaFlatBuffer *generated_key = NULL; CpaStatus status = CPA_STATUS_FAIL; QAT_HKDF_CTX *qat_hkdf_ctx = NULL; int key_length = 0; int offset = 0; int md_size = 0; op_done_t op_done; int qatPerformOpRetries = 0; int iMsgRetry = getQatMsgRetryCount(); unsigned long int ulPollInterval = getQatPollInterval(); int inst_num = QAT_INVALID_INSTANCE; thread_local_variables_t *tlv = NULL; #ifdef QAT_OPENSSL_PROVIDER size_t hkdflabellen; unsigned char hkdflabel[2048]; qat_WPACKET pkt; const unsigned char *tls13_data; size_t tls13_datalen; unsigned char tls13_kdf_hash[EVP_MAX_MD_SIZE]; #endif #ifndef QAT_OPENSSL_3 int (*sw_derive_fn_ptr)(EVP_PKEY_CTX *, unsigned char *, size_t *) = NULL; #endif if (unlikely(NULL == ctx || NULL == key || NULL == olen)) { WARN("Either ctx %p, key %p or olen %p is NULL\n", ctx, key, olen); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_PASSED_NULL_PARAMETER); return ret; } #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif qat_hkdf_ctx = (QAT_HKDF_CTX *)EVP_PKEY_CTX_get_data(ctx); if (qat_hkdf_ctx == NULL) { WARN("qat_hkdf_ctx is NULL\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); return ret; } #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (qat_openssl3_hkdf_fallback == 1) { DEBUG("- Switched to software mode\n"); qat_hkdf_ctx->fallback = 1; goto err; } #endif DEBUG("QAT HW HKDF Started\n"); if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); qat_hkdf_ctx->fallback = 1; goto err; } if (!qat_get_cipher_suite(qat_hkdf_ctx)) { DEBUG("Failed to get cipher suite, fallback to SW\n"); qat_hkdf_ctx->fallback = 1; goto err; } if ((inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); qat_hkdf_ctx->fallback = 1; goto err; } else { QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); return 0; } } qat_hkdf_ctx->qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (!qat_set_hkdf_mode(qat_hkdf_ctx)) { WARN("Error setting mode into HKDFOpdata\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } generated_key = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (NULL == generated_key) { WARN("Failed to allocate memory for generated_key\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_MALLOC_FAILURE); goto err; } key_length = *olen; md_size = EVP_MD_size(qat_hkdf_ctx->qat_md); #ifdef QAT_OPENSSL_PROVIDER /*hkdf label creation and intialization for TLS13-KDF*/ if((qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp == CPA_CY_HKDF_KEY_EXPAND_LABEL)) { if (qat_hkdf_ctx->hkdf_op_data->seedLen != 0) { EVP_MD_CTX *mctx = EVP_MD_CTX_new(); /* The pre-extract derive step uses a hash of no messages */ if (mctx == NULL || EVP_DigestInit_ex(mctx, qat_hkdf_ctx->qat_md, NULL) <= 0 || EVP_DigestFinal_ex(mctx, tls13_kdf_hash, NULL) <= 0) { EVP_MD_CTX_free(mctx); return 0; } EVP_MD_CTX_free(mctx); memcpy(qat_hkdf_ctx->hkdf_op_data->secret, qat_hkdf_ctx->hkdf_op_data->seed, qat_hkdf_ctx->hkdf_op_data->seedLen); qat_hkdf_ctx->hkdf_op_data->secretLen = qat_hkdf_ctx->hkdf_op_data->seedLen; OPENSSL_cleanse(qat_hkdf_ctx->hkdf_op_data->seed, qat_hkdf_ctx->hkdf_op_data->seedLen); qat_hkdf_ctx->hkdf_op_data->seedLen = 0; tls13_data = tls13_kdf_hash; tls13_datalen = md_size; } else { tls13_data = qat_hkdf_ctx->data; tls13_datalen = qat_hkdf_ctx->data_len; } if (!QAT_WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0) || !QAT_WPACKET_put_bytes_u16(&pkt, key_length) || !QAT_WPACKET_start_sub_packet_u8(&pkt) || !QAT_WPACKET_memcpy(&pkt, qat_hkdf_ctx->prefix, qat_hkdf_ctx->prefix_len) || !QAT_WPACKET_memcpy(&pkt, qat_hkdf_ctx->label, qat_hkdf_ctx->label_len) || !QAT_WPACKET_close(&pkt) || !QAT_WPACKET_sub_memcpy_u8(&pkt, tls13_data, (tls13_data == NULL) ? 0 : tls13_datalen) || !QAT_WPACKET_get_total_written(&pkt, &hkdflabellen) || !QAT_WPACKET_finish(&pkt)) { QAT_WPACKET_cleanup(&pkt);} memcpy(qat_hkdf_ctx->hkdf_op_data->label[0].label, hkdflabel, hkdflabellen); qat_hkdf_ctx->hkdf_op_data->label[0].labelLen = hkdflabellen; qat_hkdf_ctx->hkdf_op_data->label[0].sublabelFlag = 0x00; } #endif /* For Extract and Expand, PRK and OKM is sent back so datalen is modified here to accommodate it */ if (qat_hkdf_ctx->hkdf_op_data->hkdfKeyOp == CPA_CY_HKDF_KEY_EXTRACT_EXPAND) { offset = md_size; key_length = 2 * offset; } /* API Expects Key Length equal to md_size */ if (key_length < md_size) key_length = md_size; generated_key->pData = (Cpa8U *) qat_mem_alloc(key_length, qat_hkdf_ctx->qat_svm, __FILE__, __LINE__); if (NULL == generated_key->pData) { WARN("Failed to allocate memory for generated_key data\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_MALLOC_FAILURE); goto err; } generated_key->dataLenInBytes = key_length; /* ---- Perform the operation ---- */ DUMP_HKDF_OP_DATA(qat_hkdf_ctx->hkdf_op_data); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } do { DUMP_KEYGEN_TLS(qat_instance_handles[inst_num], generated_key); DEBUG("Calling cpaCyKeyGenTls3 \n"); status = cpaCyKeyGenTls3(qat_instance_handles[inst_num], qat_hkdf_cb, &op_done, qat_hkdf_ctx->hkdf_op_data, qat_hkdf_ctx->cipher_suite, generated_key); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (CPA_STATUS_SUCCESS != status) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); qat_hkdf_ctx->fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); qat_hkdf_ctx->fallback = 1; } else { QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_kdf_requests_in_flight); } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_KEYGEN_TLS_OUTPUT(generated_key); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); qat_hkdf_ctx->fallback = 1; } else { QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); DUMPL("Generated key", generated_key->pData, key_length); if (unlikely(generated_key->pData == NULL)) { WARN("generated_key->pData is NULL\n"); QATerr(QAT_F_QAT_HKDF_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } memcpy(key, generated_key->pData + offset, *olen); ret = 1; err: /* Clean the memory */ if (NULL != qat_hkdf_ctx->hkdf_op_data) { if (NULL != generated_key) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(*generated_key, qat_hkdf_ctx->qat_svm); OPENSSL_free(generated_key); } } if (qat_hkdf_ctx->fallback == 1) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifndef QAT_OPENSSL_3 EVP_PKEY_meth_get_derive((EVP_PKEY_METHOD *)sw_hkdf_pmeth, NULL, &sw_derive_fn_ptr); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx->sw_hkdf_ctx_data); ret = (*sw_derive_fn_ptr)(ctx, key, olen); EVP_PKEY_CTX_set_data(ctx, qat_hkdf_ctx); #else # ifdef QAT_OPENSSL_PROVIDER ret = default_provider_HKDF_derive(qat_hkdf_ctx, key, *olen, params); # else ret = default_provider_HKDF_derive(qat_hkdf_ctx, key, *olen); # endif #endif } return ret; } #endif /* ENABLE_QAT_HW_HKDF */ qatengine-1.9.0/qat_hw_hkdf.h000066400000000000000000000056031500416242000161220ustar00rootroot00000000000000#ifndef QAT_HW_HKDF_H # define QAT_HW_HKDF_H #endif #ifdef ENABLE_QAT_HW_HKDF # ifdef QAT_OPENSSL_3 # include # include # include # include # include "qat_prov_hkdf_packet.h" # endif # include "openssl/ossl_typ.h" # include "openssl/kdf.h" # include "openssl/evp.h" # include "openssl/ssl.h" # include "qat_evp.h" # include "qat_utils.h" # include "e_qat.h" # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_key.h" /* These limits are based on QuickAssist limits. * OpenSSL is more generous but better to restrict and fail * early on here if they are exceeded rather than later on * down in the driver. */ # define QAT_HKDF_INFO_MAXBUF 1024 #ifdef QAT_OPENSSL_3 # define QAT_KDF_MAX_INFO_SZ 80 # define QAT_KDF_MAX_SEED_SZ 48 # define QAT_KDF_MAX_KEY_SZ 80 #endif # define EVP_KDF_HKDF_MODE_EXPAND_LABEL 2 #define EVP_PKEY_ALG_CTRL 0x1000 #define EVP_PKEY_CTRL_HKDF_PREFIX (EVP_PKEY_ALG_CTRL + 14) #define EVP_PKEY_CTRL_HKDF_LABEL (EVP_PKEY_ALG_CTRL + 15) #define EVP_PKEY_CTRL_HKDF_DATA (EVP_PKEY_ALG_CTRL + 16) extern char *kdf_name; /* QAT TLS pkey context structure */ typedef struct { /* Mode: Extract, Expand or both */ int mode; /* Digest to use for HKDF */ const EVP_MD *qat_md; void *sw_hkdf_ctx_data; /* Struct that contains salt, key and info */ CpaCyKeyGenHKDFOpData *hkdf_op_data; /* HKDF cipherSuite */ CpaCyKeyHKDFCipherSuite cipher_suite; /* fallback: SW offload */ unsigned int fallback; int qat_svm; /* Below are used for SW fallback when compiled * with openssl 3.0 engine API. It uses the openssl * default provider. */ #ifdef QAT_OPENSSL_3 /* input keying material */ unsigned char sw_ikm[QAT_KDF_MAX_KEY_SZ]; size_t sw_ikm_size; /* application specific information */ unsigned char sw_info[QAT_KDF_MAX_INFO_SZ]; size_t sw_info_size; /* salt */ unsigned char sw_salt[QAT_KDF_MAX_SEED_SZ]; size_t sw_salt_size; #endif #ifdef QAT_OPENSSL_PROVIDER unsigned char *prefix; size_t prefix_len; unsigned char *label; size_t label_len; unsigned char *data; size_t data_len; #endif } QAT_HKDF_CTX; typedef struct { int mode; const EVP_MD *md; unsigned char *salt; size_t salt_len; unsigned char *key; size_t key_len; unsigned char info[QAT_HKDF_INFO_MAXBUF]; size_t info_len; } QAT_HKDF_PKEY_CTX; /* Function Declarations */ int qat_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); int qat_hkdf_init(EVP_PKEY_CTX *ctx); void qat_hkdf_cleanup(EVP_PKEY_CTX *ctx); #ifndef QAT_OPENSSL_PROVIDER int qat_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *olen); #else int qat_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *olen, const OSSL_PARAM params[]); #endif #endif /* ENABLE_QAT_HW_HKDF */ qatengine-1.9.0/qat_hw_init.c000066400000000000000000001011721500416242000161420ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_init.c * * This file provides QAT Engine qat_hw initialization functions. * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif #define NANOSECONDS_TO_MICROSECONDS 1000 /* Standard Includes */ #include #include #include #include #include #include #include #ifndef __FreeBSD__ # include # include # include #endif #include #include #include /* Local Includes */ #include "e_qat.h" #include "qat_fork.h" #include "qat_events.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_utils.h" /* OpenSSL Includes */ #include #include #include /* QAT includes */ #include "cpa.h" #include "cpa_cy_im.h" #include "cpa_cy_common.h" #include "cpa_types.h" #include "icp_sal_user.h" #include "icp_sal_poll.h" /* 1. QAT HW mode, Check if QAT Engine Offload disabled. If yes, fallback to OpenSSL. 2. Co-Existence mode, if QAT HW initialization fail, fallback to QAT SW. 3. Sw fallback on, if instance not available, fallback to OpenSSL. */ int qat_get_qat_offload_disabled(void) { if (disable_qat_offload || fallback_to_qat_sw || (qat_get_sw_fallback_enabled() && !is_any_device_available())) return 1; else return 0; } int qat_get_sw_fallback_enabled(void) { #ifdef ENABLE_QAT_FIPS return 0; #else return enable_sw_fallback; #endif } static inline int qat_use_signals_no_engine_start(void) { return (int) (intptr_t) qat_timer_poll_func_thread; } int qat_use_signals(void) { /* We check engine_inited outside of a mutex here because it is more efficient and we are only interested in the state if it hasn't been initialised. The usual case is that the engine will have been initialised and we can carry on without locking. If the engine hasn't been initialised then there will be a further check within qat_engine_init inside a mutex to prevent a race condition. */ #ifndef QAT_OPENSSL_PROVIDER if (unlikely(!engine_inited)) { ENGINE* e = ENGINE_by_id(engine_qat_id); if (e == NULL) { WARN("Function ENGINE_by_id returned NULL\n"); return 0; } if (!qat_engine_init(e)) { WARN("Failure in qat_engine_init function\n"); ENGINE_free(e); ENGINE_QAT_PTR_RESET(); return 0; } ENGINE_free(e); ENGINE_QAT_PTR_RESET(); } #endif return qat_use_signals_no_engine_start(); } int validate_configuration_section_name(const char *name) { int len = 0; if (name == NULL) { return 0; } len = strlen(name); if (len == 0 || len >= QAT_CONFIG_SECTION_NAME_SIZE) { WARN("Invalid section name length %d\n", len); return 0; } return 1; } int is_instance_available(int inst_num) { if (inst_num > qat_num_instances) return 0; if (!qat_instance_details[inst_num].qat_instance_started) return 0; #ifdef ENABLE_QAT_HW_KPT thread_local_variables_t * tlv = NULL; tlv = qat_check_create_local_variables(); if (unlikely(NULL == tlv)) { WARN("No local variables are available\n"); return 0; } /* Return 0 if the KPT isn't initialized or provisioned * while using the WPK in the current request. */ if (tlv->kpt_wpk_in_use > -1 && (!is_kpt_mode() || !kpt_instance_available(inst_num, tlv->kpt_wpk_in_use))) return 0; #endif return !qat_accel_details[qat_instance_details[inst_num]. qat_instance_info.physInstId.packageId].qat_accel_reset_status; } int is_any_device_available(void) { int device_num = 0; if (qat_num_devices == 0) return 0; for (device_num = 0; device_num < qat_num_devices; device_num++) { if (qat_accel_details[device_num].qat_accel_reset_status == 0) return 1; } return 0; } int is_instance_svm(int inst_num) { return !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; } int get_instance(int inst_type, int mem_type) { int inst_num = QAT_INVALID_INSTANCE; int apl_inst_count; /* Applicable Instance Count */ int *inst_idx; unsigned int *inst_map; unsigned int inst_count = 0; thread_local_variables_t * tlv = NULL; #ifndef QAT_OPENSSL_PROVIDER /* See qat_use_signals() above for more info on why it is safe to check engine_inited outside of a mutex in this case. */ if (unlikely(!engine_inited)) { ENGINE* e = ENGINE_by_id(engine_qat_id); if (e == NULL) { WARN("Function ENGINE_by_id returned NULL\n"); return inst_num; } if (!qat_engine_init(e)) { WARN("Failure in qat_engine_init function\n"); ENGINE_free(e); return inst_num; } ENGINE_free(e); ENGINE_QAT_PTR_RESET(); } #endif tlv = qat_check_create_local_variables(); if (unlikely(NULL == tlv)) { WARN("No local variables are available\n"); return inst_num; } if (0 == enable_instance_for_thread) { if (inst_type == QAT_INSTANCE_ASYM) { /* Asym Instance */ apl_inst_count = qat_asym_num_instance; inst_idx = &tlv->qatAsymInstanceNumForThread; inst_map = qat_map_asym_inst; } else { /* Sym Instance */ apl_inst_count = qat_sym_num_instance; inst_idx = &tlv->qatSymInstanceNumForThread; inst_map = qat_map_sym_inst; } if (likely(qat_instance_handles && apl_inst_count)) { switch (mem_type) { case QAT_INSTANCE_SVM: do { inst_count++; *inst_idx = (*inst_idx + 1) % apl_inst_count; } while (!is_instance_available(inst_map[*inst_idx]) && !is_instance_svm(inst_map[*inst_idx]) && inst_count <= apl_inst_count); break; case QAT_INSTANCE_CONTIGUOUS: do { inst_count++; *inst_idx = (*inst_idx + 1) % apl_inst_count; } while (!is_instance_available(inst_map[*inst_idx]) && is_instance_svm(inst_map[*inst_idx]) && inst_count <= apl_inst_count); break; default: do { inst_count++; *inst_idx = (*inst_idx + 1) % apl_inst_count; } while (!is_instance_available(inst_map[*inst_idx]) && inst_count <= apl_inst_count); break; } if (likely(inst_count <= apl_inst_count)) inst_num = inst_map[*inst_idx]; } } else { if (inst_type == QAT_INSTANCE_ASYM) { /* Asym Instance */ if (tlv->qatAsymInstanceNumForThread != QAT_INVALID_INSTANCE) { if (is_instance_available(tlv->qatAsymInstanceNumForThread)) inst_num = tlv->qatAsymInstanceNumForThread; } } else { /* Sym Instance */ if (tlv->qatSymInstanceNumForThread != QAT_INVALID_INSTANCE) { if (is_instance_available(tlv->qatSymInstanceNumForThread)) inst_num = tlv->qatSymInstanceNumForThread; } } } /* If no working instance could be found then flag a warning */ if (unlikely(inst_num == QAT_INVALID_INSTANCE)) { WARN("No working instance is available\n"); } DEBUG("inst type: %s, inst_num = %d\n", inst_type == QAT_INSTANCE_ASYM ? "ASYM" : "SYM", inst_num); return inst_num; } /****************************************************************************** * function: * virtualToPhysical(void *virtualAddr) * * @param virtualAddr [IN] - Virtual address. * * description: * Translates virtual address to hardware physical address. See the qae_mem * module for more details. The virtual to physical translator is required * by the QAT hardware to map from virtual addresses to physical locations * in pinned memory. * * This function is designed to work with the allocator defined in * qae_mem_utils.c and qat_contig_mem/qat_contig_mem.c * ******************************************************************************/ static CpaPhysicalAddr virtualToPhysical(void *virtualAddr) { return qaeCryptoMemV2P(virtualAddr); } thread_local_variables_t * qat_check_create_local_variables(void) { thread_local_variables_t * tlv = (thread_local_variables_t *)qat_getspecific_thread(thread_local_variables); if (tlv != NULL) return tlv; tlv = OPENSSL_zalloc(sizeof(thread_local_variables_t)); if (tlv != NULL) { #ifdef ENABLE_QAT_HW_KPT tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; #endif tlv->qatAsymInstanceNumForThread = QAT_INVALID_INSTANCE; tlv->qatSymInstanceNumForThread = QAT_INVALID_INSTANCE; qat_setspecific_thread(thread_local_variables, (void *)tlv); } return tlv; } /****************************************************************************** * function: * qat_local_variable_destructor(void *tlv) * * description: * This is a cleanup callback function registered when pthread_key_create() * is called. It will get called when the thread is destroyed and will * cleanup the thread local variables. * *****************************************************************************/ static void qat_local_variable_destructor(void *tlv) { if (tlv) OPENSSL_free(tlv); qat_setspecific_thread(thread_local_variables, NULL); } void qat_instance_notification_callbackFn(const CpaInstanceHandle ih, void *callbackTag, const CpaInstanceEvent inst_ev) { Cpa32U packageId; struct timespec ts = { 0 }; switch (inst_ev) { case CPA_INSTANCE_EVENT_FATAL_ERROR: WARN("Received Callback that instance %ld is unavailable\n", (intptr_t)callbackTag); packageId = qat_instance_details[(intptr_t)callbackTag].qat_instance_info.physInstId.packageId; qat_accel_details[packageId].qat_accel_reset_status = 1; clock_gettime(clock_id, &ts); CRYPTO_QAT_LOG("[%lld.%06ld] Instance: %ld Handle %p Device %d RESTARTING \n", (long long)ts.tv_sec, ts.tv_nsec / NANOSECONDS_TO_MICROSECONDS, (intptr_t)callbackTag, ih, packageId); break; case CPA_INSTANCE_EVENT_RESTARTING: WARN("Received Callback that instance %ld is restarting\n", (intptr_t)callbackTag); break; case CPA_INSTANCE_EVENT_RESTARTED: WARN("Received Callback that instance %ld is available\n", (intptr_t)callbackTag); packageId = qat_instance_details[(intptr_t)callbackTag].qat_instance_info.physInstId.packageId; qat_accel_details[packageId].qat_accel_reset_status = 0; clock_gettime(clock_id, &ts); CRYPTO_QAT_LOG("[%lld.%06ld] Instance: %ld Handle %p Device %d RESTARTED \n", (long long)ts.tv_sec, ts.tv_nsec / NANOSECONDS_TO_MICROSECONDS, (intptr_t)callbackTag, ih, packageId); break; default: WARN("Fatal Error detected for instance: %ld\n", (intptr_t)callbackTag); break; } } static int qat_instance_sym_supported(CpaCyCapabilitiesInfo *pCapInfo) { return pCapInfo->symSupported; } static int qat_instance_asym_supported(CpaCyCapabilitiesInfo *pCapInfo) { /* For more detailed information about these flags go to check cpa_cy_im.h */ if (pCapInfo->dhSupported || pCapInfo->dsaSupported || pCapInfo->rsaSupported || pCapInfo->ecSupported || pCapInfo->ecdhSupported || pCapInfo->ecdsaSupported || pCapInfo->keySupported || pCapInfo->lnSupported || pCapInfo->primeSupported) { return 1; } else { return 0; } } /****************************************************************************** * function: * qat_remap_instances() * * description: * A instances classify function * - put symmetric instance index into qat_map_sym_inst * - put asymmetric instance index into qat_map_asym_inst * - put both-support instance index into * both qat_map_sym_inst and qat_map_asym_inst * *****************************************************************************/ static int qat_remap_instances() { CpaCyCapabilitiesInfo instance_cap = {0}; CpaCyCapabilitiesInfo *pCapInfo = &instance_cap; CpaStatus status; int instNum = 0, asym_idx = 0, sym_idx = 0; /* For each instance, get its capability. */ for (instNum = 0; instNum < qat_num_instances; instNum++) { status = cpaCyQueryCapabilities(qat_instance_handles[instNum], pCapInfo); if (CPA_STATUS_SUCCESS != status ) { WARN("cpaCyQueryCapabilities failed. status = %d\n", status); QATerr(QAT_F_QAT_REMAP_INSTANCES, QAT_R_CAPABILITY_FAILURE); return 0; } /* If Asym supported */ if (qat_instance_asym_supported(pCapInfo)) { qat_map_asym_inst[asym_idx] = instNum; asym_idx++; } /* If Sym supported */ if (qat_instance_sym_supported(pCapInfo)) { qat_map_sym_inst[sym_idx] = instNum; sym_idx++; } } /* Set the global vars */ qat_asym_num_instance = asym_idx; qat_sym_num_instance = sym_idx; DUMP_INSTANCE_MAPPING("Asymmetric instances sequence", qat_map_asym_inst, qat_asym_num_instance); DUMP_INSTANCE_MAPPING("Symmetric instances sequence", qat_map_sym_inst, qat_sym_num_instance); return 1; } int qat_hw_init(ENGINE *e) { int instNum, err; CpaStatus status = CPA_STATUS_SUCCESS; int ret_pthread_sigmask; Cpa32U package_id = 0; DEBUG("QAT_HW initialization:\n"); DEBUG("- External polling: %s\n", enable_external_polling ? "ON": "OFF"); DEBUG("- Heuristic polling: %s\n", enable_heuristic_polling ? "ON": "OFF"); DEBUG("- SW Fallback: %s\n", enable_sw_fallback ? "ON": "OFF"); DEBUG("- Inline polling: %s\n", enable_inline_polling ? "ON": "OFF"); DEBUG("- Internal poll interval: %dns\n", qat_poll_interval); DEBUG("- Epoll timeout: %dms\n", qat_epoll_timeout); DEBUG("- Event driven polling mode: %s\n", enable_event_driven_polling ? "ON": "OFF"); DEBUG("- Instance for thread: %s\n", enable_instance_for_thread ? "ON": "OFF"); DEBUG("- Max retry count: %d\n", qat_max_retry_count); qat_polling_thread = pthread_self(); if ((err = pthread_key_create(&thread_local_variables, qat_local_variable_destructor)) != 0) { WARN("pthread_key_create failed: %s\n", strerror(err)); QATerr(QAT_F_QAT_HW_INIT, QAT_R_PTHREAD_CREATE_FAILURE); return 0; } /* Initialise the QAT hardware */ if (CPA_STATUS_SUCCESS != icp_sal_userStart(ICPConfigSectionName_libcrypto)) { WARN("icp_sal_userStart failed\n"); # ifndef QAT_SW /* Co-Existence mode: Don't print error message. */ QATerr(QAT_F_QAT_HW_INIT, QAT_R_ICP_SAL_USERSTART_FAIL); # endif pthread_key_delete(thread_local_variables); return 0; } status = cpaCyGetNumInstances(&qat_num_instances); if (CPA_STATUS_SUCCESS != status) { WARN("cpaCyGetNumInstances failed, status=%d\n", status); QATerr(QAT_F_QAT_HW_INIT, QAT_R_GET_NUM_INSTANCE_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } if (!qat_num_instances) { WARN("No crypto instances found\n"); # ifndef QAT_SW /* Co-Existence mode: Don't print error message. */ QATerr(QAT_F_QAT_HW_INIT, QAT_R_INSTANCE_UNAVAILABLE); # endif qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } DEBUG("Found %d Cy instances\n", qat_num_instances); /* Allocate memory for the instance handle array */ qat_instance_handles = (CpaInstanceHandle *) OPENSSL_zalloc(((int)qat_num_instances) * sizeof(CpaInstanceHandle)); if (NULL == qat_instance_handles) { WARN("OPENSSL_zalloc() failed for instance handles.\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_INSTANCE_HANDLE_MALLOC_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } /* Get the Cy instances */ status = cpaCyGetInstances(qat_num_instances, qat_instance_handles); if (CPA_STATUS_SUCCESS != status) { WARN("cpaCyGetInstances failed, status=%d\n", status); QATerr(QAT_F_QAT_HW_INIT, QAT_R_GET_INSTANCE_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } if (!enable_external_polling && !enable_inline_polling) { #ifndef __FreeBSD__ if (qat_is_event_driven()) { CpaStatus status; int flags; int engine_fd; /* Add the file descriptor to an epoll event list */ internal_efd = epoll_create1(0); if (-1 == internal_efd) { WARN("Error creating epoll fd\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_EPOLL_CREATE_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } for (instNum = 0; instNum < qat_num_instances; instNum++) { /* Get the file descriptor for the instance */ status = icp_sal_CyGetFileDescriptor(qat_instance_handles[instNum], &engine_fd); if (CPA_STATUS_FAIL == status) { WARN("Error getting file descriptor for instance\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_GET_FILE_DESCRIPTOR_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } /* Make the file descriptor non-blocking */ eng_poll_st[instNum].eng_fd = engine_fd; eng_poll_st[instNum].inst_index = instNum; flags = qat_fcntl(engine_fd, F_GETFL, 0); if (qat_fcntl(engine_fd, F_SETFL, flags | O_NONBLOCK) == -1) { WARN("Failed to set engine_fd as NON BLOCKING\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_SET_FILE_DESCRIPTOR_NONBLOCKING_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } eng_epoll_events[instNum].data.ptr = &eng_poll_st[instNum]; eng_epoll_events[instNum].events = EPOLLIN | EPOLLET; if (-1 == epoll_ctl(internal_efd, EPOLL_CTL_ADD, engine_fd, &eng_epoll_events[instNum])) { WARN("Error adding fd to epoll\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_EPOLL_CTL_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } } } #endif } /* Set translation function and start each instance */ for (instNum = 0; instNum < qat_num_instances; instNum++) { /* Retrieve CpaInstanceInfo2 structure for that instance */ status = cpaCyInstanceGetInfo2(qat_instance_handles[instNum], &qat_instance_details[instNum].qat_instance_info); if (CPA_STATUS_SUCCESS != status ) { WARN("cpaCyInstanceGetInfo2 failed. status = %d\n", status); QATerr(QAT_F_QAT_HW_INIT, QAT_R_GET_INSTANCE_INFO_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } package_id = qat_instance_details[instNum].qat_instance_info.physInstId.packageId; qat_accel_details[package_id].qat_accel_present = 1; if (package_id >= qat_num_devices) qat_num_devices = package_id + 1; if (!qat_instance_details[instNum].qat_instance_info.requiresPhysicallyContiguousMemory) { qat_map_svm_inst[qat_svm_num_instance] = instNum; ++qat_svm_num_instance; } /* Set the address translation function */ status = cpaCySetAddressTranslation(qat_instance_handles[instNum], virtualToPhysical); if (CPA_STATUS_SUCCESS != status) { WARN("cpaCySetAddressTranslation failed, status=%d\n", status); QATerr(QAT_F_QAT_HW_INIT, QAT_R_SET_ADDRESS_TRANSLATION_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } /* Start the instances */ status = cpaCyStartInstance(qat_instance_handles[instNum]); if (CPA_STATUS_SUCCESS != status) { WARN("cpaCyStartInstance failed, status=%d\n", status); QATerr(QAT_F_QAT_HW_INIT, QAT_R_START_INSTANCE_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } qat_instance_details[instNum].qat_instance_started = 1; DEBUG("Started Instance No: %d Located on Device: %d\n", instNum, package_id); if (enable_sw_fallback) { DEBUG("cpaCyInstanceSetNotificationCb instNum = %d\n", instNum); status = cpaCyInstanceSetNotificationCb(qat_instance_handles[instNum], qat_instance_notification_callbackFn, (void *)(intptr_t)instNum); if (CPA_STATUS_SUCCESS != status) { WARN("cpaCyInstanceSetNotificationCb failed, status=%d\n", status); QATerr(QAT_F_QAT_HW_INIT, QAT_R_SET_NOTIFICATION_CALLBACK_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } } } if (!qat_remap_instances()) { qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } qat_contig_num_instance = qat_num_instances - qat_svm_num_instance; DEBUG("Instances %d, SVM instances %d, contig instances %d\n", qat_num_instances, qat_svm_num_instance, qat_contig_num_instance); DUMP_INSTANCE_MAPPING("Asym sequence for thread mapping", qat_map_asym_inst, qat_asym_num_instance); DUMP_INSTANCE_MAPPING("Sym sequence for thread mapping", qat_map_sym_inst, qat_sym_num_instance); #ifdef QAT_CPU_CYCLES_COUNT rdtsc_prof_init(&qat_hw_rsa_dec_req_prepare, 0); rdtsc_prof_init(&qat_hw_rsa_dec_req_submit, 0); rdtsc_prof_init(&qat_hw_rsa_dec_req_retry, 0); rdtsc_prof_init(&qat_hw_rsa_dec_req_cleanup, 0); rdtsc_prof_init(&qat_hw_ecdsa_sign_req_prepare, 0); rdtsc_prof_init(&qat_hw_ecdsa_sign_req_submit, 0); rdtsc_prof_init(&qat_hw_ecdsa_sign_req_retry, 0); rdtsc_prof_init(&qat_hw_ecdsa_sign_req_cleanup, 0); rdtsc_prof_init(&qat_hw_ecdh_derive_req_prepare, 0); rdtsc_prof_init(&qat_hw_ecdh_derive_req_submit, 0); rdtsc_prof_init(&qat_hw_ecdh_derive_req_retry, 0); rdtsc_prof_init(&qat_hw_ecdh_derive_req_cleanup, 0); rdtsc_prof_init(&qat_hw_ecx_derive_req_prepare, 0); rdtsc_prof_init(&qat_hw_ecx_derive_req_submit, 0); rdtsc_prof_init(&qat_hw_ecx_derive_req_retry, 0); rdtsc_prof_init(&qat_hw_ecx_derive_req_cleanup, 0); #endif if (!enable_external_polling && !enable_inline_polling) { if (!qat_is_event_driven()) { sigemptyset(&set); sigaddset(&set, SIGUSR1); ret_pthread_sigmask = pthread_sigmask(SIG_BLOCK, &set, NULL); if (ret_pthread_sigmask != 0) { WARN("pthread_sigmask error\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_POLLING_THREAD_SIGMASK_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } } if (sem_init(&hw_polling_thread_sem, 0, 0) != 0) { WARN("hw sem_init failed!\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_POLLING_THREAD_SEM_INIT_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } #ifndef __FreeBSD__ if (qat_create_thread(&qat_polling_thread, NULL, qat_is_event_driven() ? event_poll_func : qat_timer_poll_func, NULL)) { #else if (qat_create_thread(&qat_polling_thread, NULL, qat_timer_poll_func, NULL)) { #endif WARN("Creation of polling thread failed\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_POLLING_THREAD_CREATE_FAILURE); qat_polling_thread = pthread_self(); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } if (qat_adjust_thread_affinity(qat_polling_thread) == 0) { WARN("Setting polling thread affinity failed\n"); QATerr(QAT_F_QAT_HW_INIT, QAT_R_SET_POLLING_THREAD_AFFINITY_FAILURE); qat_hw_finish_int(e, QAT_RESET_GLOBALS); return 0; } if (!qat_is_event_driven()) { if (pthread_mutex_lock(&qat_poll_mutex) == 0) { while (!cleared_to_start){ if (pthread_cond_wait(&qat_poll_condition, &qat_poll_mutex) != 0) { WARN("Failed to get conditional wait\n"); } qat_cond_wait_started = 1; } if (pthread_mutex_unlock(&qat_poll_mutex) != 0) { WARN("Failed to unlock conditional wait mutex \n"); } } else { WARN("Failed to lock conditional wait mutex \n"); } } } #ifdef ENABLE_QAT_HW_KPT /* Init KPT if KPT is enabled and hasn't be inited */ if (kpt_enabled && !kpt_inited) { if (!qat_hw_kpt_init()) { WARN("KPT init failed, please check\n"); qat_pthread_mutex_unlock(); qat_engine_finish(e); return 0; } kpt_inited = 1; } #endif return 1; } int qat_hw_finish_int(ENGINE *e, int reset_globals) { int i; int ret = 1; CpaStatus status = CPA_STATUS_SUCCESS; #ifndef __FreeBSD__ ENGINE_EPOLL_ST *epollst = NULL; #endif DEBUG("---- QAT Finishing...\n\n"); #ifdef ENABLE_QAT_HW_KPT if (kpt_enabled) { /* Finish KPT before engine finish if KPT is inited */ if (kpt_inited) { DEBUG("Start KPT Finishing.\n"); qat_hw_kpt_finish(); /* kpt_enabled can't be zeroed, otherwise child processes won't * do qat_hw_kpt_init while forking. * kpt_inited should be zeroed as the process is terminated. */ kpt_inited = 0; } DEBUG("Reset the loaded WPK file number.\n"); if (kpt_reset_wpk_num()) { WARN("Failure in kpt_reset_wpk_num.\n"); } } #endif qat_hw_keep_polling = 0; if (qat_use_signals_no_engine_start()) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_HW_FINISH_INT, QAT_R_SEM_POST_FAILURE); ret = 0; } } if (qat_instance_handles) { for (i = 0; i < qat_num_instances; i++) { if (qat_instance_details[i].qat_instance_started) { status = cpaCyStopInstance(qat_instance_handles[i]); if (CPA_STATUS_SUCCESS != status) { WARN("cpaCyStopInstance failed, status=%d\n", status); QATerr(QAT_F_QAT_HW_FINISH_INT, QAT_R_STOP_INSTANCE_FAILURE); ret = 0; } qat_instance_details[i].qat_instance_started = 0; } } } /* If polling thread is different from the main thread, wait for polling * thread to finish. pthread_equal returns 0 when threads are different. */ if (!enable_external_polling && !enable_inline_polling && pthread_equal(qat_polling_thread, pthread_self()) == 0) { if (qat_join_thread(qat_polling_thread, NULL) != 0) { WARN("Polling thread join failed with status: %d\n", ret); QATerr(QAT_F_QAT_HW_FINISH_INT, QAT_R_PTHREAD_JOIN_FAILURE); ret = 0; } } qat_polling_thread = pthread_self(); if (qat_instance_handles) { OPENSSL_free(qat_instance_handles); qat_instance_handles = NULL; } if (!enable_external_polling && !enable_inline_polling) { #ifndef __FreeBSD__ if (qat_is_event_driven()) { for (i = 0; i < qat_num_instances; i++) { epollst = (ENGINE_EPOLL_ST*)eng_epoll_events[i].data.ptr; if (epollst) { if (-1 == epoll_ctl(internal_efd, EPOLL_CTL_DEL, epollst->eng_fd, &eng_epoll_events[i])) { WARN("Error removing fd from epoll\n"); QATerr(QAT_F_QAT_HW_FINISH_INT, QAT_R_EPOLL_CTL_FAILURE); ret = 0; } close(epollst->eng_fd); } } } #endif } CRYPTO_QAT_LOG("Number of remaining in-flight requests = %d - %s\n", num_requests_in_flight, __func__); /* Reset global variables */ qat_num_instances = 0; qat_num_devices = 0; qat_asym_num_instance = 0; qat_sym_num_instance = 0; icp_sal_userStop(); internal_efd = 0; qat_instance_handles = NULL; qat_hw_keep_polling = 1; #ifndef QAT_BORINGSSL qatPerformOpRetries = 0; #endif DEBUG("Calling pthread_key_delete()\n"); pthread_key_delete(thread_local_variables); sem_destroy(&hw_polling_thread_sem); /* destroy qat hw semaphore: hw_polling_thread_sem. */ if (!enable_external_polling && !enable_inline_polling) { if (!qat_is_event_driven()) { int res =0; if ((qat_cond_wait_started && (res = pthread_cond_destroy(&qat_poll_condition))) != 0) { WARN("Destroying of qat_poll_condition failed. %d\n", res); } } } /* Reset the configuration global variables (to their default values) only * if requested, i.e. when we are not re-initializing the engine after * forking */ if (reset_globals == 1) { #ifdef ENABLE_QAT_HW_KPT DEBUG("KPT reset globally\n"); kpt_inited = 0; kpt_enabled = 0; #endif enable_inline_polling = 0; enable_event_driven_polling = 0; enable_instance_for_thread = 0; enable_sw_fallback = 0; disable_qat_offload = 0; qat_poll_interval = QAT_POLL_PERIOD_IN_NS; qat_max_retry_count = QAT_CRYPTO_NUM_POLLING_RETRIES; qat_cond_wait_started = 0; } return ret; } qatengine-1.9.0/qat_hw_kpt.c000066400000000000000000000612541500416242000160030ustar00rootroot00000000000000/* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif #ifdef ENABLE_QAT_HW_KPT /* Standard Includes */ # include # include # include # include # include # include # include # include # include /* Local Includes */ # include "qat_hw_kpt.h" # include "qat_hw_callback.h" # include "qat_hw_polling.h" # include "qat_events.h" # include "qat_hw_asym_common.h" # define NO_PADDING 0 # define PADDING 1 pthread_t kpt_polling_thread; int kpt_keep_polling = 0; int kpt_enabled = 0; int kpt_inited = 0; int is_kpt_mode(void) { /* * kpt_enabled = 1 means WPK files are used and loaded successfully. * kpt_inited = 1 means KPT is provisioned successfully. * KPT mode needs to satisfy both of above conditions. */ if (kpt_enabled) { if (kpt_inited) { return 1; } else { /* Init KPT for single-process app, e.g. OpenSSL. */ if (!qat_hw_kpt_init()) { kpt_inited = 0; WARN("KPT initialization in KPT mode check failed.\n"); return 0; } kpt_inited = 1; return 1; } } return 0; } EVP_PKEY *qat_hw_kpt_load_privkey(ENGINE *e, const char *wpk) { return kpt_load_priv_key(e, wpk); } static void *kpt_poll_func(void *ih) { CpaStatus status; int inst_idx; struct timespec req_time = { 0 }; req_time.tv_nsec = qat_poll_interval; while (kpt_keep_polling) { for (inst_idx = 0; inst_idx < qat_num_instances; inst_idx++) { status = icp_sal_CyPollInstance(qat_instance_handles[inst_idx], 0); if (unlikely(status == CPA_STATUS_FAIL)) WARN("Error in icp_sal_CyPollInstance\n"); } nanosleep(&req_time, NULL); } return NULL; } int qat_hw_kpt_init() { int inst_idx = 0; int pass = 0; /* create kpt polling thread */ kpt_keep_polling = 1; if (qat_create_thread(&kpt_polling_thread, NULL, kpt_poll_func, NULL)) { WARN("Creation of kpt polling thread failed\n"); return 0; } for (inst_idx = 0; inst_idx < qat_num_instances; inst_idx++) { if (kpt_init(inst_idx, qat_instance_handles[inst_idx])) { DEBUG("Instance %d Loads SWK Successfully\n", inst_idx); pass = 1; } } /* stop kpt polling thread */ kpt_keep_polling = 0; if (qat_join_thread(kpt_polling_thread, NULL) != 0) { WARN("Error in kpt polling thread join\n"); return 0; } if (!pass) { WARN("No Instance is provisioned successful\n"); return 0; } return 1; } void qat_hw_kpt_finish() { int inst_idx = 0; /* create kpt polling thread */ kpt_keep_polling = 1; if (qat_create_thread(&kpt_polling_thread, NULL, kpt_poll_func, NULL)) { WARN("Creation of kpt polling thread failed\n"); return; } for (inst_idx = 0; inst_idx < qat_num_instances; inst_idx++) { kpt_finish(inst_idx, qat_instance_handles[inst_idx]); } /* stop kpt polling thread */ kpt_keep_polling = 0; if (qat_join_thread(kpt_polling_thread, NULL) != 0) { WARN("Error in kpt polling thread join\n"); return; } } /** ***************************************************************************** * * KPT RSA Decryption and Sign implementation. * *****************************************************************************/ /****************************************************************************** * function: * kpt_rsaCallbackFn(void *pCallbackTag, CpaStatus status, * void *pOpData, CpaFlatBuffer * pOut) * * @param pCallbackTag [IN] - Opaque User Data for this specific call. Will * be returned unchanged in the callback. * @param status [IN] - Status result of the RSA operation. * @param pOpData [IN] - Structure containing all the data needed to * perform the RSA encryption operation. * @param pOut [IN] - Pointer to buffer into which the result of * the RSA encryption is written. * description: * Callback function used by RSA operations to indicate completion. * Calls back to qat_crypto_callbackFn() as functionally it does the same. * ******************************************************************************/ int qat_check_rsa_wpk(RSA *rsa) { return kpt_check_rsa_wpk(rsa); } static void kpt_rsaCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer *pOut) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } static void kpt_sync_rsaCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer *pOut) { op_done_t *opDone = (op_done_t *) pCallbackTag; if (unlikely(opDone == NULL)) { WARN("opDone is NULL\n"); return; } DEBUG("kpt_sync_rsaCallbackFn status %d\n", status); opDone->verifyResult = CPA_TRUE; opDone->status = status; opDone->flag = 0; opDone->job = NULL; return; } static int qat_hw_kpt_rsa_decrypt(CpaCyKptRsaDecryptOpData *dec_op_data, int rsa_len, CpaFlatBuffer *output_buf, int *fallback, int kpt_wpk_idx) { /* Used for RSA Decrypt and RSA Sign */ op_done_t op_done; CpaStatus sts = CPA_STATUS_FAIL; int inst_num = QAT_INVALID_INSTANCE; int job_ret = 0; thread_local_variables_t *tlv = NULL; DEBUG("- Started\n"); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); return 0; } tlv->kpt_wpk_in_use = kpt_wpk_idx; if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; return 0; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (qat_kill_thread(qat_timer_poll_func_thread, SIGUSR1) != 0) { WARN("qat_kill_thread error\n"); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; return 0; } } } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notifications\n"); qat_cleanup_op_done(&op_done); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; return 0; } } else { /* Sync mode */ CRYPTO_QAT_LOG("- RSA\n"); DEBUG("RSA Decryption in Sync Mode\n"); /* Inline polling mode, need to quickly return then polling the ring */ if (getEnableInlinePolling()) { sts = kpt_rsa_decrypt(inst_num, kpt_sync_rsaCallbackFn, &op_done, dec_op_data, output_buf, kpt_wpk_idx); } else { /* Internal/External polling mode, block here until it returns */ sts = kpt_rsa_decrypt(inst_num, NULL, NULL, dec_op_data, output_buf, kpt_wpk_idx); } if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", sts); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; return 0; } /* wait for replies */ do { if (getEnableInlinePolling()) sts = icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); else sched_yield(); } while (sts == CPA_STATUS_RETRY); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to poll the response - status = %d\n", sts); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; return 0; } DUMP_RSA_DECRYPT_OUTPUT(output_buf); qat_cleanup_op_done(&op_done); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; DEBUG("- Finished\n"); return 1; } CRYPTO_QAT_LOG("- RSA\n"); do { sts = kpt_rsa_decrypt(inst_num, kpt_rsaCallbackFn, &op_done, dec_op_data, output_buf, kpt_wpk_idx); if (sts == CPA_STATUS_RETRY) { tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } tlv->kpt_wpk_in_use = kpt_wpk_idx; } } while (sts == CPA_STATUS_RETRY); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", sts); qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; return 0; } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); tlv->kpt_wpk_in_use = kpt_wpk_idx; } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_RSA_DECRYPT_OUTPUT(output_buf); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); qat_cleanup_op_done(&op_done); return 0; } qat_cleanup_op_done(&op_done); DEBUG("- Finished\n"); return 1; } int qat_hw_kpt_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int rsa_len = 0; int sts = 1, fallback = 0; CpaFlatBuffer *output_buffer = NULL; # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION unsigned char *ver_msg = NULL; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; int lenstra_ret = 0; # endif CpaCyKptRsaDecryptOpData *kpt_dec_op_data = NULL; int kpt_wpk_idx = KPT_INVALID_WPK_IDX; DEBUG("- Started.\n"); if (qat_get_qat_offload_disabled()) { DEBUG("qat_get_qat_offload_disabled\n"); return 0; } rsa_len = RSA_size(rsa); if (!kpt_rsa_prepare(flen, from, to, rsa, padding, &output_buffer, &kpt_dec_op_data, PADDING, &kpt_wpk_idx)) { WARN("Failure in kpt_rsa_prepare\n"); return 0; } if (1 != qat_hw_kpt_rsa_decrypt(kpt_dec_op_data, rsa_len, output_buffer, &fallback, kpt_wpk_idx)) { WARN("Failure in qat_hw_kpt_rsa_decrypt\n"); sts = 0; goto exit; } memcpy(to, output_buffer->pData, rsa_len); # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION /* Lenstra vulnerability protection: Now call the s/w impl'n of public decrypt in order to verify the encrypt operation just carried out. */ RSA_get0_key((const RSA *)rsa, &n, &e, &d); /* Note: not checking 'd' as it is not used */ if (e != NULL) { /* then a public key exists and we can effect Lenstra attack protection */ ver_msg = OPENSSL_zalloc(flen); if (ver_msg == NULL) { WARN("ver_msg zalloc failed.\n"); sts = 0; goto exit; } # ifdef ENABLE_QAT_HW_LENSTRA_VERIFY_HW lenstra_ret = qat_rsa_pub_dec(rsa_len, (const unsigned char *)to, ver_msg, rsa, padding); # else lenstra_ret = RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL()) (rsa_len, (const unsigned char *)to, ver_msg, rsa, padding); # endif if ((lenstra_ret <= 0) || (CRYPTO_memcmp(from, ver_msg, flen) != 0)) { WARN("- KPT RSA Sign failed - LENSTRA_PROTECTION\n"); OPENSSL_free(ver_msg); return 0; } OPENSSL_free(ver_msg); } # endif DEBUG("- Finished\n"); return rsa_len; exit: /* Free all the memory allocated in this function */ kpt_rsa_finish(kpt_dec_op_data, output_buffer, &kpt_wpk_idx); if (!sts) OPENSSL_cleanse(to, rsa_len); /* Return an error */ return 0; } int qat_hw_kpt_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int rsa_len = 0; int output_len = -1; int sts = 1, fallback = 0; CpaFlatBuffer *output_buffer = NULL; # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION unsigned char *ver_msg = NULL; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; int lenstra_ret = 0; # endif CpaCyKptRsaDecryptOpData *kpt_dec_op_data = NULL; int kpt_wpk_idx = KPT_INVALID_WPK_IDX; DEBUG("- Started.\n"); if (qat_get_qat_offload_disabled()) { DEBUG("qat_get_qat_offload_disabled\n"); return 0; } rsa_len = RSA_size(rsa); if (!kpt_rsa_prepare(flen, from, to, rsa, padding, &output_buffer, &kpt_dec_op_data, NO_PADDING, &kpt_wpk_idx)) { WARN("Failure in kpt_rsa_prepare\n"); return 0; } if (1 != qat_hw_kpt_rsa_decrypt(kpt_dec_op_data, rsa_len, output_buffer, &fallback, kpt_wpk_idx)) { WARN("Failure in qat_hw_kpt_rsa_decrypt\n"); sts = 0; goto exit; } # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION /* Lenstra vulnerability protection: Now call the s/w impl'n of public encrypt in order to verify the decrypt operation just carried out. */ RSA_get0_key((const RSA *)rsa, &n, &e, &d); /* Note: not checking 'd' as it is not used */ if (e != NULL) { /* then a public key exists and we can effect Lenstra attack protection */ ver_msg = OPENSSL_zalloc(flen); if (ver_msg == NULL) { WARN("ver_msg zalloc failed.\n"); sts = 0; goto exit; } # ifdef ENABLE_QAT_HW_LENSTRA_VERIFY_HW lenstra_ret = qat_rsa_pub_enc(rsa_len, (const unsigned char *)output_buffer-> pData, ver_msg, rsa, RSA_NO_PADDING); # else lenstra_ret = RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL()) (rsa_len, (const unsigned char *)output_buffer->pData, ver_msg, rsa, RSA_NO_PADDING); # endif if ((lenstra_ret <= 0) || (CRYPTO_memcmp(from, ver_msg, flen) != 0)) { WARN("- KPT RSA decryption failed - LENSTRA_PROTECTION\n"); OPENSSL_free(ver_msg); kpt_rsa_finish(kpt_dec_op_data, output_buffer, &kpt_wpk_idx); return 0; } OPENSSL_free(ver_msg); } # endif switch (padding) { case RSA_PKCS1_PADDING: output_len = RSA_padding_check_PKCS1_type_2(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; case RSA_PKCS1_OAEP_PADDING: output_len = RSA_padding_check_PKCS1_OAEP(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len, NULL, 0); break; #ifndef QAT_OPENSSL_3 /* RSA SSLv23 padding mode is remove in OpenSSL 3.0 * https://github.com/openssl/openssl/issues/14283 */ case RSA_SSLV23_PADDING: output_len = RSA_padding_check_SSLv23(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; #endif case RSA_NO_PADDING: output_len = RSA_padding_check_none(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; default: break; /* Do nothing as the error will be caught below. */ } if (output_len < 0) { WARN("Failure in removing padding\n"); sts = 0; goto exit; } kpt_rsa_finish(kpt_dec_op_data, output_buffer, &kpt_wpk_idx); DEBUG("- Finished\n"); return output_len; exit: /* Free all the memory allocated in this function */ kpt_rsa_finish(kpt_dec_op_data, output_buffer, &kpt_wpk_idx); if (!sts) OPENSSL_cleanse(to, rsa_len); /* Return an error */ return 0; } /** ***************************************************************************** * * KPT ECDSA Sign implementation. * *****************************************************************************/ int qat_check_ec_wpk(EC_KEY *eckey) { return kpt_check_ec_wpk(eckey); } /* Callback to indicate KPT completion of ECDSA Sign */ static void kpt_ecdsaSignCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean bEcdsaSignStatus, CpaFlatBuffer *pResultR, CpaFlatBuffer *pResultS) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, bEcdsaSignStatus); } ECDSA_SIG *qat_hw_kpt_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { int ok = 0, job_ret = 0; BN_CTX *ctx = NULL; ECDSA_SIG *ret = NULL; BIGNUM *ecdsa_sig_r = NULL, *ecdsa_sig_s = NULL; CpaFlatBuffer *pResultR = NULL; CpaFlatBuffer *pResultS = NULL; int inst_num = QAT_INVALID_INSTANCE; CpaCyKptEcdsaSignRSOpData *opData = NULL; CpaBoolean bEcdsaSignStatus; CpaStatus status; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); thread_local_variables_t *tlv = NULL; int kpt_wpk_idx = KPT_INVALID_WPK_IDX; DEBUG("- Started\n"); if (qat_get_qat_offload_disabled()) { DEBUG("- QAT offload is disabled\n"); return NULL; } if (!kpt_ecdsa_prepare(dgst, dgst_len, in_kinv, in_r, eckey, &ctx, &ret, &pResultR, &pResultS, &ecdsa_sig_r, &ecdsa_sig_s, &opData, &kpt_wpk_idx)) { WARN("Failure in kpt_ecdsa_prepare\n"); return NULL; } /* perform ECDSA sign */ tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); goto err; } tlv->kpt_wpk_in_use = kpt_wpk_idx; QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (qat_kill_thread(qat_timer_poll_func_thread, SIGUSR1) != 0) { WARN("qat_kill_thread error\n"); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; goto err; } } } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); qat_cleanup_op_done(&op_done); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; goto err; } } CRYPTO_QAT_LOG("AU - %s\n", __func__); do { if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; goto err; } status = kpt_ecdsa_do_sign(inst_num, kpt_ecdsaSignCallbackFn, &op_done, opData, &bEcdsaSignStatus, pResultR, pResultS, kpt_wpk_idx); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } tlv->kpt_wpk_in_use = kpt_wpk_idx; } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; goto err; } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if (op_done.job != NULL) { tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); tlv->kpt_wpk_in_use = kpt_wpk_idx; } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_ECDSA_SIGN_OUTPUT(bEcdsaSignStatus, pResultR, pResultS); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); tlv->kpt_wpk_in_use = KPT_INVALID_WPK_IDX; if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); /* Convert the flatbuffer results back to a BN */ BN_bin2bn(pResultR->pData, pResultR->dataLenInBytes, ecdsa_sig_r); BN_bin2bn(pResultS->pData, pResultS->dataLenInBytes, ecdsa_sig_s); ok = 1; err: if (!ok) { ECDSA_SIG_free(ret); ret = NULL; } kpt_ecdsa_finish(pResultR, pResultS, opData, ctx, &kpt_wpk_idx); DEBUG("- Finished\n"); return ret; } #endif qatengine-1.9.0/qat_hw_kpt.h000066400000000000000000000130721500416242000160030ustar00rootroot00000000000000#ifndef __QAT_HW_KPT_H__ # define __QAT_HW_KPT_H__ /* Openssl */ # include # include # include # include # include # include # include /* QAT includes */ # include "cpa.h" # include "cpa_cy_im.h" # include "cpa_cy_kpt.h" # include "qae_mem.h" # include "qae_mem_utils.h" # include "icp_sal_versions.h" # include "icp_sal_poll.h" /* Local Includes */ # include "qat_utils.h" /* KPT2 Library Includes */ # include "kpt.h" /****************************************************************************** * function: * EVP_PKEY *qat_hw_kpt_load_privkey(ENGINE *e, const char *wpk) * * @param e [IN] - OpenSSL engine pointer * @param wpk [IN] - Path of WPK file * * @return - Openssl EVP_PKEY key struct * * description: * WPK file loading and parsing function. It will retrieve key information from * ASN1 encoded stream and save the data into EVP_PKEY->ex_data for later usage. * ******************************************************************************/ EVP_PKEY *qat_hw_kpt_load_privkey(ENGINE *e, const char *wpk); /****************************************************************************** * function: * qat_hw_kpt_init() * * @return - 1 represent successful, 0 represent failed * * description: * KPT init functions. Provision the ESWK to QAT HW devices. * ******************************************************************************/ int qat_hw_kpt_init(); /****************************************************************************** * function: * void qat_hw_kpt_finish(); * * description: * KPT finish functions. Delete the provisioned SWK. * ******************************************************************************/ void qat_hw_kpt_finish(); /****************************************************************************** * function: * int is_kpt_mode(void); * * @return - 1 represent KPT mode, 0 represent Non-KPT mode. * * description: * KPT mode availability check. * ******************************************************************************/ int is_kpt_mode(void); /****************************************************************************** * function: * qat_check_rsa_wpk(RSA *rsa); * * @return - 1 represent the RSA WPK is used, 0 represent the opposition. * * description: * Check whether the RSA Wrapped Private Key is used. * ******************************************************************************/ int qat_check_rsa_wpk(RSA *rsa); /****************************************************************************** * function: * qat_hw_kpt_rsa_priv_enc (int flen, * const unsigned char *from, * unsigned char *to, * RSA *rsa, * int padding) * * @param flen [IN] - length in bytes of input file * @param from [IN] - pointer to the input file * @param to [OUT] - pointer to output signature * @param rsa [IN] - pointer to private key structure * @param padding [IN] - Padding scheme * * description: Perform a KPT RSA private encrypt (RSA Sign) * We use the decrypt implementation to achieve this. ******************************************************************************/ int qat_hw_kpt_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); /****************************************************************************** * function: * qat_hw_kpt_rsa_priv_dec(int flen, * const unsigned char *from, * unsigned char *to, * RSA * rsa, * int padding) * * @param flen [IN] - length in bytes of input * @param from [IN] - pointer to the input * @param to [OUT] - pointer to output * @param rsa [IN] - pointer to the private key structure * @param padding [IN] - Padding scheme * * description: * description: Perform a KPT RSA private decrypt. (RSA Decrypt) ******************************************************************************/ int qat_hw_kpt_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); /****************************************************************************** * function: * qat_check_ec_wpk(EC_KEY *eckey); * * @return - 1 represent the EC WPK is used, 0 represent the opposition. * * description: * Check whether the EC Wrapped Private Key is used. * ******************************************************************************/ int qat_check_ec_wpk(EC_KEY *eckey); /****************************************************************************** * function: * qat_hw_kpt_ecdsa_do_sign (const unsigned char *dgst, * int dgst_len, * const BIGNUM *in_kinv, * const BIGNUM *in_r, * EC_KEY *eckey) * * @param dgst [IN] - digest to be signed * @param dgst_len [IN] - length in bytes of digest * @param in_kinv [IN] - pointer to k_inv * @param in_r [IN] - pointer to r * @param eckey [IN] - pointer to the private key structure * @return * * description: Perform a KPT ECDSA operation. ******************************************************************************/ ECDSA_SIG *qat_hw_kpt_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); #endif qatengine-1.9.0/qat_hw_polling.c000066400000000000000000000277261500416242000166570ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_polling.c * * This file provides an implementation for polling in QAT engine * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Standard Includes */ #include #include #include #include #include #include #include /* Local Includes */ #include "qat_hw_polling.h" #include "qat_utils.h" # include "e_qat.h" /* OpenSSL Includes */ #include /* QAT includes */ #ifdef QAT_HW # include "cpa.h" # include "cpa_cy_im.h" # include "cpa_types.h" # include "icp_sal_user.h" # include "icp_sal_poll.h" #endif #ifndef __FreeBSD__ struct epoll_event eng_epoll_events[QAT_MAX_CRYPTO_INSTANCES] = {{ 0 }}; ENGINE_EPOLL_ST eng_poll_st[QAT_MAX_CRYPTO_INSTANCES] = {{ -1 }}; #endif int internal_efd = 0; int getQatMsgRetryCount() { return qat_max_retry_count; } useconds_t getQatPollInterval() { return qat_poll_interval; } int getEnableInlinePolling() { return enable_inline_polling; } static void qat_poll_heartbeat_timer_expiry(struct timespec *previous_time) { struct timespec current_time = { 0 }; struct timespec diff_time = { 0 }; clock_gettime(clock_id, ¤t_time); /* Calculate time difference and poll every one second */ if ((current_time.tv_nsec - previous_time->tv_nsec) < 0) { diff_time.tv_sec = current_time.tv_sec - previous_time->tv_sec - 1; } else { diff_time.tv_sec = current_time.tv_sec - previous_time->tv_sec; } if (diff_time.tv_sec > 0) { poll_heartbeat(); previous_time->tv_sec = current_time.tv_sec; previous_time->tv_nsec = current_time.tv_nsec; } } void *qat_timer_poll_func(void *ih) { CpaStatus status = 0; Cpa16U inst_num = 0; struct timespec req_time = { 0 }; struct timespec rem_time = { 0 }; struct timespec timeout_time = { 0 }; unsigned int retry_count = 0; /* to prevent too much time drift */ int sig = 0; unsigned int eintr_count = 0; struct timespec previous_time = { 0 }; struct timespec hw_polling_abs_timeout; DEBUG("timer_poll_func started\n"); qat_timer_poll_func_thread = pthread_self(); cleared_to_start = 1; if (pthread_mutex_lock(&qat_poll_mutex) == 0) { pthread_cond_signal(&qat_poll_condition); if (pthread_mutex_unlock(&qat_poll_mutex) != 0) WARN("Failed to unlock conditional wait mutex \n"); } else { WARN("Failed to lock conditional wait mutex \n"); } DEBUG("qat_timer_poll_func_thread = 0x%lx\n", (unsigned long)qat_timer_poll_func_thread); if (qat_get_sw_fallback_enabled()) { clock_gettime(clock_id, &previous_time); } while (qat_hw_keep_polling) { if (num_requests_in_flight == 0) { if (qat_get_sw_fallback_enabled()) { qat_poll_heartbeat_timer_expiry(&previous_time); } timeout_time.tv_sec = QAT_EVENT_TIMEOUT_IN_SEC; timeout_time.tv_nsec = 0; get_sem_wait_abs_time(&hw_polling_abs_timeout, timeout_time); while ((sig = sem_timedwait(&hw_polling_thread_sem, &hw_polling_abs_timeout)) == -1 && errno == EINTR && eintr_count < QAT_CRYPTO_NUM_EVENT_RETRIES) { eintr_count++; } eintr_count = 0; if (unlikely(sig == -1)) { if ((qat_get_sw_fallback_enabled()) && (errno == ETIMEDOUT || errno == EINTR)) { clock_gettime(clock_id, &previous_time); poll_heartbeat(); } continue; } } else { if (qat_get_sw_fallback_enabled()) { qat_poll_heartbeat_timer_expiry(&previous_time); } } req_time.tv_nsec = qat_poll_interval; for (inst_num = 0; inst_num < qat_num_instances; ++inst_num) { if (num_requests_in_flight == 0) break; /* Poll for 0 means process all packets on the instance */ status = icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); if (unlikely(CPA_STATUS_SUCCESS != status && CPA_STATUS_RESTARTING != status && CPA_STATUS_RETRY != status)) { WARN("icp_sal_CyPollInstance returned status %d\n", status); } if (unlikely(!qat_hw_keep_polling)) break; } retry_count = 0; do { retry_count++; nanosleep(&req_time, &rem_time); req_time.tv_sec = rem_time.tv_sec; req_time.tv_nsec = rem_time.tv_nsec; if (unlikely((errno < 0) && (EINTR != errno))) { WARN("nanosleep system call failed: errno %i\n", errno); break; } } while ((retry_count <= QAT_CRYPTO_NUM_POLLING_RETRIES) && (EINTR == errno)); } DEBUG("timer_poll_func finishing - pid = %d\n", getpid()); qat_timer_poll_func_thread = 0; cleared_to_start = 0; pthread_cond_signal(&qat_poll_condition); return NULL; } #ifndef __FreeBSD__ void *event_poll_func(void *ih) { CpaStatus status = 0; struct epoll_event *events = NULL; ENGINE_EPOLL_ST* epollst = NULL; struct timespec previous_time = { 0 }; /* Buffer where events are returned */ events = OPENSSL_zalloc(sizeof(struct epoll_event) * MAX_EVENTS); if (NULL == events) { WARN("Error allocating events list\n"); QATerr(QAT_F_EVENT_POLL_FUNC, QAT_R_EVENTS_MALLOC_FAILURE); goto end; } if (qat_get_sw_fallback_enabled()) { clock_gettime(clock_id, &previous_time); } while (qat_hw_keep_polling) { int n = 0; int i = 0; n = epoll_wait(internal_efd, events, MAX_EVENTS, qat_epoll_timeout); for (i = 0; i < n; ++i) { if (events[i].events & EPOLLIN) { /* poll for 0 means process all packets on the ET ring */ epollst = (ENGINE_EPOLL_ST*)events[i].data.ptr; status = icp_sal_CyPollInstance(qat_instance_handles[epollst->inst_index], 0); if (CPA_STATUS_SUCCESS != status) { WARN("icp_sal_CyPollInstance returned status %d\n", status); } } } if (qat_get_sw_fallback_enabled()) { qat_poll_heartbeat_timer_expiry(&previous_time); } } OPENSSL_free(events); events = NULL; end: return NULL; } #endif CpaStatus poll_instances(void) { unsigned int poll_loop; int inst_asym; int inst_sym; int instance_polled = 0; CpaStatus internal_status = CPA_STATUS_SUCCESS, ret_status = CPA_STATUS_SUCCESS; if (enable_instance_for_thread) { thread_local_variables_t *tlv = NULL; tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); return CPA_STATUS_FAIL; } inst_asym = qat_map_asym_inst[tlv->qatAsymInstanceNumForThread]; inst_sym = qat_map_sym_inst[tlv->qatSymInstanceNumForThread]; if (qat_instance_handles) { /* Asymmetric instance */ if (QAT_INVALID_INSTANCE != inst_asym) { internal_status = icp_sal_CyPollInstance(qat_instance_handles[inst_asym], 0); if (CPA_STATUS_SUCCESS != internal_status) { WARN("Fail to poll Asymmetric instance\n"); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); ret_status = CPA_STATUS_FAIL; } instance_polled = 1; } /* Symmetric instance */ if (QAT_INVALID_INSTANCE != inst_sym && inst_asym != inst_sym) { internal_status = icp_sal_CyPollInstance(qat_instance_handles[inst_sym], 0); if (CPA_STATUS_SUCCESS != internal_status) { WARN("Fail to poll Symmetric instance\n"); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); ret_status = CPA_STATUS_FAIL; } instance_polled = 1; } if (instance_polled) { return ret_status; } else { WARN("neither asym nor sym instance is valid\n"); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); return CPA_STATUS_FAIL; } } else { WARN("could not get a valid instance to poll\n"); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); return CPA_STATUS_FAIL; } } if (NULL == qat_instance_handles) { WARN("qat_instance_handles is NULL\n"); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); return CPA_STATUS_FAIL; } for (poll_loop = 0; poll_loop < qat_num_instances; poll_loop++) { if (qat_instance_handles[poll_loop] != NULL) { internal_status = icp_sal_CyPollInstance(qat_instance_handles[poll_loop], 0); if (CPA_STATUS_SUCCESS == internal_status) { /* Do nothing */ } else if (CPA_STATUS_RETRY == internal_status) { ret_status = internal_status; } else { WARN("icp_sal_CyPollInstance failed - status %d\n", internal_status); QATerr(QAT_F_POLL_INSTANCES, QAT_R_POLL_INSTANCE_FAILURE); ret_status = internal_status; break; } } } return ret_status; } CpaStatus poll_heartbeat(void) { CpaStatus ret_status = CPA_STATUS_SUCCESS; ret_status = icp_sal_poll_device_events(); if (unlikely(CPA_STATUS_SUCCESS != ret_status)) { WARN("The call to icp_sal_poll_device_events failed\n"); } return ret_status; } qatengine-1.9.0/qat_hw_polling.h000066400000000000000000000066641500416242000166620ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_polling.h * * This file provides an interface for polling in QAT engine * *****************************************************************************/ #ifndef QAT_HW_POLLING_H # define QAT_HW_POLLING_H # include "cpa.h" # include "cpa_types.h" # include "e_qat.h" # include "qat_fork.h" # ifndef __FreeBSD__ # include # endif # define MAX_EVENTS 32 /* Globals */ typedef struct { int eng_fd; int inst_index; } ENGINE_EPOLL_ST; # ifndef __FreeBSD__ extern struct epoll_event eng_epoll_events[QAT_MAX_CRYPTO_INSTANCES]; extern ENGINE_EPOLL_ST eng_poll_st[QAT_MAX_CRYPTO_INSTANCES]; # endif extern int internal_efd; int getQatMsgRetryCount(); useconds_t getQatPollInterval(); int getEnableInlinePolling(); /****************************************************************************** * function: * void *qat_timer_poll_func(void *ih) * * @param ih [IN] - NULL * * description: * Poll the QAT instances (nanosleep version) * NB: Delay in this function is set by default at runtime by an engine * specific message. If not set then the default is QAT_POLL_PERIOD_IN_NS. * This function uses pthread signals to wait for a signal * that there is traffic to process and therefore that QAT engine polling * needs to be started/resumed. * ******************************************************************************/ void *qat_timer_poll_func(void *ih); # ifndef __FreeBSD__ void *event_poll_func(void *ih); # endif CpaStatus poll_instances(void); CpaStatus poll_heartbeat(void); #endif /* QAT_HW_POLLING_H */ qatengine-1.9.0/qat_hw_prf.c000066400000000000000000001045651500416242000157770ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prf.c * * This file provides an implementation of the PRF operations for an * OpenSSL engine * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifdef QAT_OPENSSL_3 # include # include # include # include #endif #include #include #include #include #include "qat_hw_prf.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_key.h" #ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; #endif static EVP_PKEY_METHOD *_hidden_prf_pmeth = NULL; #ifndef QAT_OPENSSL_3 /* Have a store of the s/w EVP_PKEY_METHOD for software fallback purposes. * This is only used for OpenSSL 1.1.1. For OpenSSL 3, we will use the * default provider for SW fallback purposes. */ static const EVP_PKEY_METHOD *sw_prf_pmeth = NULL; #endif #ifdef ENABLE_QAT_HW_PRF void qat_prf_pkey_methods(void) { EVP_PKEY_meth_set_init(_hidden_prf_pmeth, qat_tls1_prf_init); EVP_PKEY_meth_set_cleanup(_hidden_prf_pmeth, qat_prf_cleanup); EVP_PKEY_meth_set_derive(_hidden_prf_pmeth, NULL, qat_prf_tls_derive); EVP_PKEY_meth_set_ctrl(_hidden_prf_pmeth, qat_tls1_prf_ctrl, NULL); } #endif EVP_PKEY_METHOD *qat_prf_pmeth(void) { if (_hidden_prf_pmeth) { if (!qat_reload_algo) return _hidden_prf_pmeth; EVP_PKEY_meth_free(_hidden_prf_pmeth); } if ((_hidden_prf_pmeth = EVP_PKEY_meth_new(EVP_PKEY_TLS1_PRF, 0)) == NULL) { QATerr(QAT_F_QAT_PRF_PMETH, ERR_R_INTERNAL_ERROR); return NULL; } /* Now save the current (non-offloaded) prf pmeth to sw_prf_pmeth */ /* for software fallback purposes */ #ifndef QAT_OPENSSL_3 if ((sw_prf_pmeth = EVP_PKEY_meth_find(EVP_PKEY_TLS1_PRF)) == NULL) { QATerr(QAT_F_QAT_PRF_PMETH, ERR_R_INTERNAL_ERROR); return NULL; } #endif #ifdef ENABLE_QAT_HW_PRF if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_PRF)) { qat_prf_pkey_methods(); qat_hw_prf_offload = 1; DEBUG("QAT HW PRF Registration succeeded\n"); } else { qat_hw_prf_offload = 0; } #endif if (!qat_hw_prf_offload) { #ifndef QAT_OPENSSL_PROVIDER DEBUG("QAT HW PRF is disabled, using OpenSSL SW\n"); #endif #ifndef QAT_OPENSSL_3 EVP_PKEY_meth_copy(_hidden_prf_pmeth, sw_prf_pmeth); #else /* Although QATEngine supports software fallback to the default provider when * using the OpenSSL 3 legacy engine API, if it fails during the registration * phase, the pkey method cannot be set correctly because the OpenSSL3 legacy * engine framework no longer provides a standard method for HKDF, PRF and SM2. * https://github.com/openssl/openssl/issues/19047 */ # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) # ifdef ENABLE_QAT_HW_PRF qat_openssl3_prf_fallback = 1; qat_prf_pkey_methods(); return _hidden_prf_pmeth; # endif # else EVP_PKEY_meth_free(_hidden_prf_pmeth); return NULL; # endif #endif } return _hidden_prf_pmeth; } #ifdef ENABLE_QAT_HW_PRF /****************************************************************************** * function: * qat_tls1_prf_init(EVP_PKEY_CTX *ctx) * * @param ctx [IN] - PKEY Context structure pointer * * @param [OUT] - Status * * description: * Qat PRF init function ******************************************************************************/ int qat_tls1_prf_init(EVP_PKEY_CTX *ctx) { QAT_TLS1_PRF_CTX *qat_prf_ctx = NULL; int inst_num = QAT_INVALID_INSTANCE; #ifndef QAT_OPENSSL_3 int (*sw_init_fn_ptr)(EVP_PKEY_CTX *) = NULL; int ret = 0; #endif if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return 0; } #ifndef QAT_OPENSSL_3 if (qat_get_qat_offload_disabled() || qat_get_sw_fallback_enabled()) { DEBUG("- Switched to software mode or fallback mode enabled.\n"); EVP_PKEY_meth_get_init((EVP_PKEY_METHOD *)sw_prf_pmeth, &sw_init_fn_ptr); ret = (*sw_init_fn_ptr)(ctx); if (ret != 1) { WARN("s/w tls1_prf_init fn failed.\n"); return 0; } } #endif qat_prf_ctx = OPENSSL_zalloc(sizeof(*qat_prf_ctx)); if (qat_prf_ctx == NULL) { WARN("Cannot allocate qat_prf_ctx\n"); return 0; } if ((inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY)) != QAT_INVALID_INSTANCE) { qat_prf_ctx->qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; } else { WARN("Failed to get an instance\n"); } if (qat_get_qat_offload_disabled() || qat_get_sw_fallback_enabled()) qat_prf_ctx->sw_prf_ctx_data = EVP_PKEY_CTX_get_data(ctx); EVP_PKEY_CTX_set_data(ctx, qat_prf_ctx); return 1; } /****************************************************************************** * function: * qat_prf_cleanup(EVP_PKEY_CTX *ctx) * * @param ctx [IN] - PKEY Context structure pointer * * description: * Clear the QAT specific data stored in qat_prf_ctx ******************************************************************************/ void qat_prf_cleanup(EVP_PKEY_CTX *ctx) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif QAT_TLS1_PRF_CTX *qat_prf_ctx = NULL; #ifndef QAT_OPENSSL_3 void (*sw_cleanup_fn_ptr)(EVP_PKEY_CTX *) = NULL; #endif if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return; } qat_prf_ctx = (QAT_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); if (qat_prf_ctx == NULL) { WARN("qat_prf_ctx is NULL\n"); return; } #ifndef QAT_OPENSSL_3 if (qat_get_qat_offload_disabled() || qat_get_sw_fallback_enabled()) { DEBUG("- Switched to software mode or fallback mode enabled.\n"); /* Clean up the sw_prf_ctx_data created by the init function */ EVP_PKEY_meth_get_cleanup((EVP_PKEY_METHOD *)sw_prf_pmeth, &sw_cleanup_fn_ptr); EVP_PKEY_CTX_set_data(ctx, qat_prf_ctx->sw_prf_ctx_data); (*sw_cleanup_fn_ptr)(ctx); } #endif if (!qat_prf_ctx->qat_svm) { if (qat_prf_ctx->qat_sec != NULL) { OPENSSL_cleanse(qat_prf_ctx->qat_sec, qat_prf_ctx->qat_seclen); qaeCryptoMemFreeNonZero(qat_prf_ctx->qat_sec); } if (qat_prf_ctx->qat_seedlen) OPENSSL_cleanse(qat_prf_ctx->qat_seed, qat_prf_ctx->qat_seedlen); if (qat_prf_ctx->qat_userLabel != NULL) qaeCryptoMemFreeNonZero(qat_prf_ctx->qat_userLabel); } else { if (qat_prf_ctx->qat_sec != NULL) { OPENSSL_cleanse(qat_prf_ctx->qat_sec, qat_prf_ctx->qat_seclen); OPENSSL_free(qat_prf_ctx->qat_sec); } if (qat_prf_ctx->qat_seedlen) OPENSSL_cleanse(qat_prf_ctx->qat_seed, qat_prf_ctx->qat_seedlen); if (qat_prf_ctx->qat_userLabel != NULL) OPENSSL_free(qat_prf_ctx->qat_userLabel); } OPENSSL_free(qat_prf_ctx); EVP_PKEY_CTX_set_data(ctx, NULL); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } /****************************************************************************** * function: * qat_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, * int type, * int p1, * void *p2) * * @param ctx [IN] - PKEY Context structure pointer * @param type [IN] - Type * @param p1 [IN] - Length/Size * @param *p2 [IN] - Data * * @param [OUT] - Status * * description: * Qat PRF control function ******************************************************************************/ int qat_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (unlikely(ctx == NULL)) { WARN("Invalid input param.\n"); return 0; } QAT_TLS1_PRF_CTX *qat_prf_ctx = (QAT_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); #ifndef QAT_OPENSSL_3 int (*sw_ctrl_fn_ptr)(EVP_PKEY_CTX *, int, int, void *) = NULL; int ret = 0; #endif if (unlikely(qat_prf_ctx == NULL)) { WARN("qat_prf_ctx cannot be NULL\n"); return 0; } #ifndef QAT_OPENSSL_3 if (qat_get_qat_offload_disabled() || qat_get_sw_fallback_enabled()) { DEBUG("- Switched to software mode or fallback mode enabled.\n"); EVP_PKEY_meth_get_ctrl((EVP_PKEY_METHOD *)sw_prf_pmeth, &sw_ctrl_fn_ptr, NULL); EVP_PKEY_CTX_set_data(ctx, qat_prf_ctx->sw_prf_ctx_data); ret = (*sw_ctrl_fn_ptr)(ctx, type, p1, p2); EVP_PKEY_CTX_set_data(ctx, qat_prf_ctx); if (ret != 1) { WARN("S/W tls1_prf_ctrl fn failed\n"); return 0; } } #endif switch (type) { case EVP_PKEY_CTRL_TLS_MD: if (unlikely(p2 == NULL)) { WARN("Invalid input param.\n"); return 0; } qat_prf_ctx->qat_md = p2; return 1; case EVP_PKEY_CTRL_TLS_SECRET: if (p1 < 0 || p1 > QAT_TLS1_PRF_SECRET_MAXBUF || p2 == NULL) { WARN("Either p1 is invalid or p2 is NULL\n"); return 0; } if (qat_prf_ctx->qat_sec != NULL) { OPENSSL_cleanse(qat_prf_ctx->qat_sec, qat_prf_ctx->qat_seclen); QAT_MEM_FREE_NONZERO_BUFF(qat_prf_ctx->qat_sec, qat_prf_ctx->qat_svm); qat_prf_ctx->qat_seclen = 0; } OPENSSL_cleanse(qat_prf_ctx->qat_seed, qat_prf_ctx->qat_seedlen); qat_prf_ctx->qat_seedlen = 0; qat_prf_ctx->qat_userLabel_len = 0; /*- * Allocate and copy the secret data * In case of zero length secret key (for example EXP cipher), * allocate minimum byte aligned size buffer when common memory * driver is used. */ if (!qat_prf_ctx->qat_svm) qat_prf_ctx->qat_sec = copyAllocPinnedMemory(p2, p1 ? p1 : 1, __FILE__, __LINE__); else qat_prf_ctx->qat_sec = OPENSSL_memdup(p2, p1 ? p1 : 1); if (qat_prf_ctx->qat_sec == NULL) { WARN("secret data malloc failed\n"); return 0; } qat_prf_ctx->qat_seclen = p1; return 1; case EVP_PKEY_CTRL_TLS_SEED: if (p1 == 0 || p2 == NULL) return 1; if (qat_prf_ctx->qat_userLabel_len == 0) { if (p1 < 0 || p1 > QAT_TLS1_PRF_LABEL_MAXBUF) { WARN("userLabel p1 %d is out of range\n", p1); return 0; } else { if (!qat_prf_ctx->qat_svm) { if (qat_prf_ctx->qat_userLabel != NULL) qaeCryptoMemFreeNonZero(qat_prf_ctx->qat_userLabel); qat_prf_ctx->qat_userLabel = copyAllocPinnedMemory(p2, p1, __FILE__, __LINE__); } else { if (qat_prf_ctx->qat_userLabel != NULL) OPENSSL_free(qat_prf_ctx->qat_userLabel); qat_prf_ctx->qat_userLabel = OPENSSL_memdup(p2, p1); } if (qat_prf_ctx->qat_userLabel == NULL) { WARN("userLabel malloc failed\n"); return 0; } qat_prf_ctx->qat_userLabel_len = p1; } } else { if (p1 < 0 || p1 > (QAT_TLS1_PRF_SEED_MAXBUF - qat_prf_ctx->qat_seedlen)) { WARN("p1 %d is out of range\n", p1); return 0; } else { memcpy(qat_prf_ctx->qat_seed + qat_prf_ctx->qat_seedlen, p2, p1); qat_prf_ctx->qat_seedlen += p1; } } return 1; default: WARN("Invalid type %d\n", type); return -2; } /* switch */ } /****************************************************************************** * function: * void qat_prf_cb( * void *pCallbackTag, * CpaStatus status, * void *pOpdata, * CpaFlatBuffer *pOut) * * @param pCallbackTag [IN] - Pointer to user data * @param status [IN] - Status of the operation * @param pOpData [IN] - Pointer to operation data of the request * @param out [IN] - Pointer to the output buffer * * description: * Callback to indicate the completion of PRF ******************************************************************************/ static void qat_prf_cb(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer * pOut) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_kdf_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } /****************************************************************************** * function: * qat_get_hash_algorithm( * PRF *qat_prf_ctx * CpaCySymHashAlgorithm *hash_algorithm) * * @param qat_prf_ctx [IN] - PRF context * @param hash_algorithm [OUT] - Ptr to hash algorithm in CPA format * * description: * Retrieve the hash algorithm from the prf context and convert it to * the CPA format ******************************************************************************/ static int qat_get_hash_algorithm(QAT_TLS1_PRF_CTX * qat_prf_ctx, CpaCySymHashAlgorithm * hash_algorithm) { const EVP_MD *md = NULL; if (qat_prf_ctx == NULL || hash_algorithm == NULL) { WARN("Either qat_prf_ctx %p or hash_algorithm %p is NULL\n", qat_prf_ctx, hash_algorithm); return 0; } md = qat_prf_ctx->qat_md; if (md == NULL) { WARN("md is NULL.\n"); return 0; } switch (EVP_MD_type(md)) { case NID_sha224: *hash_algorithm = CPA_CY_SYM_HASH_SHA224; break; case NID_sha256: *hash_algorithm = CPA_CY_SYM_HASH_SHA256; break; case NID_sha384: *hash_algorithm = CPA_CY_SYM_HASH_SHA384; break; case NID_sha512: *hash_algorithm = CPA_CY_SYM_HASH_SHA512; break; case NID_md5: *hash_algorithm = CPA_CY_SYM_HASH_MD5; break; #if defined(QAT20_OOT) case NID_sm3: *hash_algorithm = CPA_CY_SYM_HASH_SM3; break; #endif default: WARN("unsupported PRF hash type\n"); return 0; } return 1; } /****************************************************************************** * function: * build_tls_prf_op_data( * PRF *qat_prf_ctx, * CpaCyKeyGenTlsOpData *prf_op_data) * * @param qat_prf_ctx [IN] - PRF context * @param prf_op_data [OUT] - Ptr to TlsOpData used as destination * * description: * Build the TlsOpData based on the values stored in the PRF context * Note: prf_op_data must be allocated outside this function ******************************************************************************/ static int build_tls_prf_op_data(QAT_TLS1_PRF_CTX * qat_prf_ctx, CpaCyKeyGenTlsOpData * prf_op_data) { const void *label = NULL; if (qat_prf_ctx == NULL || prf_op_data == NULL) { WARN("Either qat_prf_ctx %p or prf_op_data %p is NULL\n", qat_prf_ctx, prf_op_data); return 0; } prf_op_data->secret.pData = (Cpa8U *) qat_prf_ctx->qat_sec; prf_op_data->secret.dataLenInBytes = qat_prf_ctx->qat_seclen; /*- * The label is stored in userLabel as a string Conversion from string to CPA * constant */ label = qat_prf_ctx->qat_userLabel; DEBUG("Value of label = %s\n", (char *)label); prf_op_data->userLabel.pData = NULL; prf_op_data->userLabel.dataLenInBytes = 0; prf_op_data->seed.pData = NULL; if (0 == strncmp(label, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE)) { prf_op_data->tlsOp = (CpaCyKeyTlsOp) CPA_CY_KEY_SSL_OP_MASTER_SECRET_DERIVE; } else if (0 == strncmp(label, TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE)) { prf_op_data->tlsOp = (CpaCyKeyTlsOp) CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE; } else if (0 == strncmp(label, TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE)) { prf_op_data->tlsOp = (CpaCyKeyTlsOp) CPA_CY_KEY_TLS_OP_CLIENT_FINISHED_DERIVE; } else if (0 == strncmp(label, TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE)) { prf_op_data->tlsOp = (CpaCyKeyTlsOp) CPA_CY_KEY_TLS_OP_SERVER_FINISHED_DERIVE; } else { /* Allocate and copy the user label contained in userLabel */ /* TODO we must test this case to see if it works OK */ DEBUG("Using USER_DEFINED label = %s\n", (char*)label); prf_op_data->tlsOp = (CpaCyKeyTlsOp) CPA_CY_KEY_TLS_OP_USER_DEFINED; prf_op_data->userLabel.pData = (Cpa8U *) qat_prf_ctx->qat_userLabel; if (qat_prf_ctx->qat_seedlen == 0) { qat_prf_ctx->qat_seedlen = qat_prf_ctx->qat_userLabel_len; memcpy(qat_prf_ctx->qat_seed, qat_prf_ctx->qat_userLabel, qat_prf_ctx->qat_seedlen); } else prf_op_data->userLabel.dataLenInBytes = qat_prf_ctx->qat_userLabel_len; } /*- * The seed for prf_op_data is obtained by concatenating seed2...5 in the * context. * The client and server randoms are reversed on the QAT API for Key * Derive. This is not be a problem because OpenSSL calls the function * with the variables in the correct order */ if (qat_prf_ctx->qat_seedlen) { if (!qat_prf_ctx->qat_svm) { prf_op_data->seed.pData = copyAllocPinnedMemory(qat_prf_ctx->qat_seed, qat_prf_ctx->qat_seedlen, __FILE__, __LINE__); } else { prf_op_data->seed.pData = OPENSSL_memdup(qat_prf_ctx->qat_seed, qat_prf_ctx->qat_seedlen); } if (prf_op_data->seed.pData == NULL) { /* On failure WARN and Error are flagged at the next level up.*/ return 0; } prf_op_data->seed.dataLenInBytes = qat_prf_ctx->qat_seedlen; } return 1; } #ifdef QAT_OPENSSL_3 /****************************************************************************** * function: * default_provider_PRF_derive(QAT_TLS1_PRF_CTX *qat_prf_ctx, * unsigned char *out, * size_t olen) * * @param qat_prf_ctx [IN] - PRF context * @param out [OUT] - Ptr to the key that will be generated * @param olen [IN] - Length of the key * * description: * PRF SW fallback function. Using default provider of OpenSSL 3 ******************************************************************************/ int default_provider_PRF_derive(QAT_TLS1_PRF_CTX *qat_prf_ctx, unsigned char *out, size_t olen) { int rv = 0; EVP_KDF *kdf = NULL; EVP_KDF_CTX *kctx = NULL; OSSL_PARAM params[5], *p = params; const char *mdname; /* Fetch the key derivation function implementation */ kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", "provider=default"); if (kdf == NULL) { fprintf(stderr, "EVP_KDF_fetch() returned NULL\n"); goto end; } /* Create a context for the key derivation operation */ kctx = EVP_KDF_CTX_new(kdf); if (kctx == NULL) { fprintf(stderr, "EVP_KDF_CTX_new() returned NULL\n"); goto end; } mdname = EVP_MD_get0_name(qat_prf_ctx->qat_md); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, qat_prf_ctx->qat_sec, qat_prf_ctx->qat_seclen); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, qat_prf_ctx->qat_userLabel, qat_prf_ctx->qat_userLabel_len); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, qat_prf_ctx->qat_seed, qat_prf_ctx->qat_seedlen); *p = OSSL_PARAM_construct_end(); /* Derive the key */ if (EVP_KDF_derive(kctx, out, olen, params) != 1) { fprintf(stderr, "EVP_KDF_derive() failed\n"); goto end; } rv = 1; end: EVP_KDF_CTX_free(kctx); EVP_KDF_free(kdf); return rv; } #endif /****************************************************************************** * function: * qat_prf_tls_derive( * QAT_TLS1_PRF_CTX *qat_prf_ctx, * unsigned char *key, * size_t *olen) * * * @param qat_prf_ctx [IN] - PRF context * @param key [OUT] - Ptr to the key that will be generated * @param olen [IN] - Length of the key * * description: * PRF derive function for TLS case ******************************************************************************/ int qat_prf_tls_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *olen) { int ret = 0, job_ret = 0; CpaCyKeyGenTlsOpData prf_op_data; CpaFlatBuffer *generated_key = NULL; CpaStatus status = CPA_STATUS_FAIL; QAT_TLS1_PRF_CTX *qat_prf_ctx = NULL; CpaCySymHashAlgorithm hash_algo = CPA_CY_SYM_HASH_NONE; int key_length = 0; int md_nid = 0; op_done_t op_done; int qatPerformOpRetries = 0; int iMsgRetry = getQatMsgRetryCount(); unsigned long int ulPollInterval = getQatPollInterval(); int inst_num = QAT_INVALID_INSTANCE; thread_local_variables_t *tlv = NULL; int fallback = 0; #ifndef QAT_OPENSSL_3 int (*sw_derive_fn_ptr)(EVP_PKEY_CTX *, unsigned char *, size_t *) = NULL; #endif if (unlikely(NULL == ctx || NULL == key || NULL == olen)) { WARN("Either ctx %p, key %p or olen %p is NULL\n", ctx, key, olen); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_PASSED_NULL_PARAMETER); return ret; } #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif qat_prf_ctx = (QAT_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); if (qat_prf_ctx == NULL) { WARN("qat_prf_ctx is NULL\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); return ret; } if ((qat_prf_ctx->qat_md == NULL) || (qat_prf_ctx->qat_sec == NULL) || ((qat_prf_ctx->qat_seedlen == 0) && qat_prf_ctx->qat_userLabel_len == 0)) { WARN("Either md %p, secret %p, or seedlen %zu userLabel_len %zu is ZERO\n", qat_prf_ctx->qat_md, qat_prf_ctx->qat_sec, qat_prf_ctx->qat_seedlen, qat_prf_ctx->qat_userLabel_len); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_PASSED_NULL_PARAMETER); return ret; } memset(&prf_op_data, 0, sizeof(CpaCyKeyGenTlsOpData)); key_length = *olen; md_nid = EVP_MD_type(qat_prf_ctx->qat_md); #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (qat_openssl3_prf_fallback == 1) { DEBUG("- Switched to software mode\n"); fallback = 1; goto err; } #endif DEBUG("QAT HW PRF Started\n"); if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); fallback = 1; goto err; } #ifdef QAT_DRIVER_INTREE if (md_nid == NID_md5_sha1) { if (qat_get_sw_fallback_enabled()){ DEBUG("TLS < 1.2 not supported. Fallback to software\n"); fallback = 1; goto err; } WARN("TLS < 1.2 not supported in the in-tree driver\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } #endif /* * Only required for TLS1.2 as previous versions always use MD5 and SHA-1 */ if (md_nid != NID_md5_sha1) { if (!qat_get_hash_algorithm(qat_prf_ctx, &hash_algo)) { WARN("Failed to get hash algorithm\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); return ret; } } if ((inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; goto err; } else { QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); return 0; } } qat_prf_ctx->qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; /* ---- Tls Op Data ---- */ if (!build_tls_prf_op_data(qat_prf_ctx, &prf_op_data)) { WARN("Error building TlsOpdata\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } /* ---- Generated Key ---- */ prf_op_data.generatedKeyLenInBytes = key_length; generated_key = (CpaFlatBuffer *) qat_mem_alloc(sizeof(CpaFlatBuffer), qat_prf_ctx->qat_svm, __FILE__, __LINE__); if (NULL == generated_key) { WARN("Failed to allocate memory for generated_key\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_MALLOC_FAILURE); goto err; } generated_key->pData = (Cpa8U *) qat_mem_alloc(key_length, qat_prf_ctx->qat_svm, __FILE__, __LINE__); if (NULL == generated_key->pData) { WARN("Failed to allocate memory for generated_key data\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_MALLOC_FAILURE); goto err; } generated_key->dataLenInBytes = key_length; /* ---- Perform the operation ---- */ DUMP_PRF_OP_DATA(prf_op_data); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } do { DUMP_KEYGEN_TLS(qat_instance_handles[inst_num], generated_key); /* Call the function of CPA according the to the version of TLS */ if (md_nid != NID_md5_sha1) { DEBUG("Calling cpaCyKeyGenTls2 \n"); status = cpaCyKeyGenTls2(qat_instance_handles[inst_num], qat_prf_cb, &op_done, &prf_op_data, hash_algo, generated_key); } else { DEBUG("Calling cpaCyKeyGenTls \n"); status = cpaCyKeyGenTls(qat_instance_handles[inst_num], qat_prf_cb, &op_done, &prf_op_data, generated_key); } if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (CPA_STATUS_SUCCESS != status) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); fallback = 1; } else { QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_kdf_requests_in_flight); } do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_KEYGEN_TLS_OUTPUT(generated_key); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); DUMPL("Generated key", generated_key->pData, key_length); if (unlikely(generated_key->pData == NULL)) { WARN("generated_key->pData is NULL\n"); QATerr(QAT_F_QAT_PRF_TLS_DERIVE, ERR_R_INTERNAL_ERROR); goto err; } memcpy(key, generated_key->pData, key_length); ret = 1; err: /* Free the memory */ if (prf_op_data.seed.pData) { OPENSSL_cleanse(prf_op_data.seed.pData, prf_op_data.seed.dataLenInBytes); QAT_MEM_FREE_BUFF(prf_op_data.seed.pData, qat_prf_ctx->qat_svm); } if (NULL != generated_key) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(*generated_key, qat_prf_ctx->qat_svm); QAT_MEM_FREE_BUFF(generated_key, qat_prf_ctx->qat_svm); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifndef QAT_OPENSSL_3 EVP_PKEY_meth_get_derive((EVP_PKEY_METHOD *)sw_prf_pmeth, NULL, &sw_derive_fn_ptr); EVP_PKEY_CTX_set_data(ctx, qat_prf_ctx->sw_prf_ctx_data); ret = (*sw_derive_fn_ptr)(ctx, key, olen); EVP_PKEY_CTX_set_data(ctx, qat_prf_ctx); #else ret = default_provider_PRF_derive(qat_prf_ctx, key, *olen); #endif } return ret; } #endif /* ENABLE_QAT_HW_PRF */ qatengine-1.9.0/qat_hw_prf.h000066400000000000000000000071171500416242000157770ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prf.h * * This file provides an interface of the PRF operations for an * OpenSSL engine * *****************************************************************************/ #ifndef QAT_HW_PRF_H #define QAT_HW_PRF_H #include #include #include #include #include "openssl/ossl_typ.h" #include "openssl/kdf.h" #include "openssl/evp.h" #include "openssl/ssl.h" #include "qat_evp.h" #include "qat_utils.h" #include "qat_hw_asym_common.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" /* These limits are based on QuickAssist limits. * OpenSSL is more generous but better to restrict and fail * early on here if they are exceeded rather than later on * down in the driver. */ # ifdef ENABLE_QAT_HW_PRF # define QAT_TLS1_PRF_SECRET_MAXBUF 1024 # define QAT_TLS1_PRF_SEED_MAXBUF 64 # define QAT_TLS1_PRF_LABEL_MAXBUF 136 /* QAT TLS pkey context structure */ typedef struct { /* Buffer of concatenated seeds from seed2 to seed5 data */ unsigned char qat_seed[QAT_TLS1_PRF_SEED_MAXBUF]; size_t qat_seedlen; unsigned char *qat_userLabel; size_t qat_userLabel_len; /* Digest to use for PRF */ const EVP_MD *qat_md; /* Secret value to use for PRF */ unsigned char *qat_sec; size_t qat_seclen; void *sw_prf_ctx_data; int qat_svm; } QAT_TLS1_PRF_CTX; /* Function Declarations */ int qat_tls1_prf_init(EVP_PKEY_CTX *ctx); void qat_prf_cleanup(EVP_PKEY_CTX *ctx); int qat_prf_tls_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *olen); int qat_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); # endif /* ENABLE_QAT_HW_PRF */ #endif /* QAT_HW_PRF_H */ qatengine-1.9.0/qat_hw_rsa.c000066400000000000000000001765411500416242000160000ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_rsa.c * * This file contains the engine implementations for RSA operations * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include #include "qat_utils.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_rsa.h" #include "cpa_cy_ln.h" #include "qat_hw_rsa.h" #include "qat_hw_asym_common.h" #include "icp_sal_poll.h" #include "qat_evp.h" #include "qat_constant_time.h" #ifdef ENABLE_QAT_SW_RSA # include "qat_sw_rsa.h" #endif /* To specify the RSA op sizes supported by QAT engine */ #ifdef QAT_INSECURE_ALGO # define RSA_QAT_RANGE_MIN 512 #else # define RSA_QAT_RANGE_MIN 2048 #endif #if defined(QAT20_OOT) || defined(QAT_HW_INTREE) || defined(QAT_HW_FBSD_OOT) || defined(QAT_HW_FBSD_INTREE) # define RSA_QAT_RANGE_MAX 8192 #else # define RSA_QAT_RANGE_MAX 4096 #endif #define NO_PADDING 0 #define PADDING 1 #ifdef ENABLE_QAT_HW_RSA /* * The RSA range check is performed so that if the op sizes are not in the * range supported by QAT engine then fall back to software */ static inline int qat_rsa_range_check(int plen) { return ((plen >= RSA_QAT_RANGE_MIN) && (plen <= RSA_QAT_RANGE_MAX)); } static RSA *copy_rsa_public_to_private_exponent(RSA *rsa) { RSA *rsa_copy = NULL; const BIGNUM *lenstra_n = NULL; const BIGNUM *lenstra_e = NULL; RSA_get0_key((const RSA *)rsa, &lenstra_n, &lenstra_e, NULL); rsa_copy = RSA_new(); if (rsa_copy == NULL) return NULL; RSA_set0_key(rsa_copy, (BIGNUM *)lenstra_n, NULL, (BIGNUM *)lenstra_e); return rsa_copy; } /****************************************************************************** * function: * qat_rsaCallbackFn(void *pCallbackTag, CpaStatus status, * void *pOpData, CpaFlatBuffer * pOut) * * @param pCallbackTag [IN] - Opaque User Data for this specific call. Will * be returned unchanged in the callback. * @param status [IN] - Status result of the RSA operation. * @param pOpData [IN] - Structure containing all the data needed to * perform the RSA encryption operation. * @param pOut [IN] - Pointer to buffer into which the result of * the RSA encryption is written. * description: * Callback function used by RSA operations to indicate completion. * Calls back to qat_crypto_callbackFn() as functionally it does the same. * ******************************************************************************/ static void qat_rsaCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaFlatBuffer * pOut) { # ifdef QAT_BORINGSSL CpaBufferList pBuffer; pBuffer.pBuffers = pOut; qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, &pBuffer, CPA_TRUE); # else if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); # endif /* QAT_BORINGSSL */ } static void rsa_decrypt_op_buf_free(CpaCyRsaDecryptOpData * dec_op_data, CpaFlatBuffer * out_buf, int qat_svm) { CpaCyRsaPrivateKeyRep2 *key = NULL; DEBUG("- Started\n"); if (dec_op_data) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(dec_op_data->inputData, qat_svm); if (dec_op_data->pRecipientPrivateKey) { key = &dec_op_data->pRecipientPrivateKey->privateKeyRep2; QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(key->prime1P, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(key->prime2Q, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(key->exponent1Dp, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(key->exponent2Dq, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(key->coefficientQInv, qat_svm); OPENSSL_free(dec_op_data->pRecipientPrivateKey); } OPENSSL_free(dec_op_data); } if (out_buf) { if (out_buf->pData && !qat_svm) qaeCryptoMemFreeNonZero(out_buf->pData); OPENSSL_free(out_buf); } DEBUG("- Finished\n"); } static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, CpaFlatBuffer * output_buf, int * fallback, int inst_num, int qat_svm) { /* Used for RSA Decrypt and RSA Sign */ op_done_t op_done; CpaStatus sts = CPA_STATUS_FAIL; thread_local_variables_t *tlv = NULL; # ifdef QAT_BORINGSSL op_done_t *op_done_bssl = NULL; # endif int job_ret = 0; int iMsgRetry = getQatMsgRetryCount(); useconds_t ulPollInterval = getQatPollInterval(); int qatPerformOpRetries = 0; DEBUG("- Started\n"); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); return 0; } #if defined(QAT_BORINGSSL) qat_init_op_done(&op_done, qat_svm); #else qat_init_op_done(&op_done); #endif if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notifications\n"); QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); return 0; } } # ifdef QAT_BORINGSSL if (op_done.job != NULL) { op_done_bssl = (op_done_t*)op_done.job->copy_op_done(&op_done, sizeof(op_done), (void (*)(void *, void *, int))rsa_decrypt_op_buf_free); } # endif STOP_RDTSC(&qat_hw_rsa_dec_req_prepare, 1, "[QAT HW RSA: prepare]"); /* * cpaCyRsaDecrypt() is the function called for RSA Sign in the API. * For that particular case the dec_op_data [IN] contains both the * private key value and the message (hash) value. The output_buf [OUT] * stores the signature as the output once the request is fully completed. * The sts return value contains 0 (CPA_STATUS_SUCCESS) if the request * was successfully submitted. */ CRYPTO_QAT_LOG("- RSA\n"); do { START_RDTSC(&qat_hw_rsa_dec_req_submit); if (sts == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); } # ifdef QAT_BORINGSSL if (op_done.job != NULL) op_done.job->free_op_done(op_done_bssl); # endif if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); return 0; } DUMP_RSA_DECRYPT(qat_instance_handles[inst_num], &op_done, dec_op_data, output_buf); # ifndef QAT_BORINGSSL sts = cpaCyRsaDecrypt(qat_instance_handles[inst_num], qat_rsaCallbackFn, &op_done, dec_op_data, output_buf); # else if (op_done.job != NULL) { sts = cpaCyRsaDecrypt(qat_instance_handles[inst_num], qat_rsaCallbackFn, op_done_bssl, dec_op_data, output_buf); } /* No need for wake up job or pause job here */ else { sts = cpaCyRsaDecrypt(qat_instance_handles[inst_num], qat_rsaCallbackFn, &op_done, dec_op_data, output_buf); } # endif STOP_RDTSC(&qat_hw_rsa_dec_req_submit, 1, "[QAT HW RSA: submit]"); if (sts == CPA_STATUS_RETRY) { DEBUG("cpaCyRsaDecrypt Retry \n"); if (qat_rsa_coexist) { START_RDTSC(&qat_hw_rsa_dec_req_retry); ++num_rsa_priv_retry; qat_sw_rsa_priv_req += QAT_SW_SWITCH_MB8; *fallback = 1; qat_cleanup_op_done(&op_done); STOP_RDTSC(&qat_hw_rsa_dec_req_retry, 1, "[QAT HW RSA: retry]"); return 0; } else { if (op_done.job == NULL) { usleep(ulPollInterval + qatPerformOpRetries); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { # ifndef QAT_BORINGSSL if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } # endif } } } } while (sts == CPA_STATUS_RETRY); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", sts); if (qat_get_sw_fallback_enabled() && (sts == CPA_STATUS_RESTARTING || sts == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); *fallback = 1; } else { QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { # ifdef QAT_BORINGSSL op_done.job->free_op_done(op_done_bssl); # endif qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); return 0; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); # ifdef QAT_BORINGSSL if (op_done.job != NULL) op_done.job->free_op_done(op_done_bssl); # endif return 0; } } } # ifdef QAT_BORINGSSL if (op_done.job != NULL) { qat_cleanup_op_done(&op_done); return -1; /* Async mode for BoringSSL */ } # endif if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } if (qat_rsa_coexist) ++num_rsa_hw_priv_reqs; do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { # ifdef QAT_BORINGSSL /* Support inline polling in current scenario */ if(getEnableInlinePolling()) { sts = icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); if (sts == CPA_STATUS_FAIL) { WARN("icp_sal_CyPollInstance failed - status %d\n", sts); QATerr(QAT_F_QAT_RSA_DECRYPT, QAT_R_POLL_INSTANCE_FAILURE); qat_cleanup_op_done(&op_done); return 0; } RSA_INLINE_POLLING_USLEEP(); } else { sched_yield(); } # else sched_yield(); # endif /* QAT_BORINGSSL */ } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_RSA_DECRYPT_OUTPUT(output_buf); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); return 0; } qat_cleanup_op_done(&op_done); DEBUG("- Finished\n"); return 1; } static int build_decrypt_op_buf(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaCyRsaDecryptOpData ** dec_op_data, CpaFlatBuffer ** output_buffer, int alloc_pad, int inst_num, int qat_svm) { int rsa_len = 0; int padding_result = 0; CpaCyRsaPrivateKey *cpa_prv_key = NULL; const BIGNUM *p = NULL; const BIGNUM *q = NULL; const BIGNUM *dmp1 = NULL; const BIGNUM *dmq1 = NULL; const BIGNUM *iqmp = NULL; DEBUG("- Started\n"); RSA_get0_factors((const RSA*)rsa, &p, &q); RSA_get0_crt_params((const RSA*)rsa, &dmp1, &dmq1, &iqmp); if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL) { WARN("Either p %p, q %p, dmp1 %p, dmq1 %p, iqmp %p are NULL\n", p, q, dmp1, dmq1, iqmp); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_IQMP_NULL); return 0; } DEBUG("flen = %d, padding = %d \n", flen, padding); /* output signature should have same length as the RSA size */ rsa_len = RSA_size(rsa); /* Padding check */ if ((padding != RSA_NO_PADDING) && (padding != RSA_PKCS1_PADDING) && (padding != RSA_PKCS1_OAEP_PADDING) && # ifndef QAT_OPENSSL_3 (padding != RSA_SSLV23_PADDING) && # endif (padding != RSA_X931_PADDING)) { WARN("Unknown Padding %d\n", padding); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PADDING_UNKNOWN); return 0; } cpa_prv_key = (CpaCyRsaPrivateKey *) OPENSSL_zalloc(sizeof(CpaCyRsaPrivateKey)); if (NULL == cpa_prv_key) { WARN("Failed to allocate cpa_prv_key\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PRIV_KEY_MALLOC_FAILURE); return 0; } /* output and input data MUST allocate memory for sign process */ /* memory allocation for DecOpdata[IN] */ *dec_op_data = OPENSSL_zalloc(sizeof(CpaCyRsaDecryptOpData)); if (NULL == *dec_op_data) { WARN("Failed to allocate dec_op_data\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_DEC_OP_DATA_MALLOC_FAILURE); OPENSSL_free(cpa_prv_key); return 0; } /* Setup the DecOpData structure */ (*dec_op_data)->pRecipientPrivateKey = cpa_prv_key; cpa_prv_key->version = CPA_CY_RSA_VERSION_TWO_PRIME; /* Setup the private key rep type 2 structure */ cpa_prv_key->privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2; if (qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime1P, p, qat_svm) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime2Q, q, qat_svm) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent1Dp, dmp1, qat_svm) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent2Dq, dmq1, qat_svm) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.coefficientQInv, iqmp, qat_svm) != 1) { WARN("Failed to convert privateKeyRep2 elements to flatbuffer\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE); return 0; } (*dec_op_data)->inputData.pData = (Cpa8U *) qat_mem_alloc( ((padding != RSA_NO_PADDING) && alloc_pad) ? rsa_len : flen, qat_svm, __FILE__,__LINE__); if (NULL == (*dec_op_data)->inputData.pData) { WARN("Failed to allocate (*dec_op_data)->inputData.pData\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_INPUT_DATA_MALLOC_FAILURE); return 0; } (*dec_op_data)->inputData.dataLenInBytes = (padding != RSA_NO_PADDING) && alloc_pad ? rsa_len : flen; if (alloc_pad) { switch (padding) { case RSA_PKCS1_PADDING: padding_result = RSA_padding_add_PKCS1_type_1((*dec_op_data)->inputData.pData, rsa_len, from, flen); break; case RSA_X931_PADDING: padding_result = RSA_padding_add_X931((*dec_op_data)->inputData.pData, rsa_len, from, flen); break; case RSA_NO_PADDING: padding_result = RSA_padding_add_none((*dec_op_data)->inputData.pData, rsa_len, from, flen); break; default: QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, RSA_R_UNKNOWN_PADDING_TYPE); break; } } else { padding_result = RSA_padding_add_none((*dec_op_data)->inputData.pData, rsa_len, from, flen); } if (padding_result <= 0) { WARN("Failed to add padding\n"); /* Error is raised within the padding function. */ return 0; } *output_buffer = OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (NULL == *output_buffer) { WARN("Failed to allocate output_buffer\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_OUTPUT_BUF_MALLOC_FAILURE); return 0; } /* * Memory allocation for DecOpdata[IN] the size of outputBuffer * should big enough to contain RSA_size */ if (qat_svm) (*output_buffer)->pData = (Cpa8U *) to; else (*output_buffer)->pData = (Cpa8U *) qaeCryptoMemAlloc(rsa_len, __FILE__, __LINE__); if (NULL == (*output_buffer)->pData) { WARN("Failed to allocate output_buffer->pData\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE); return 0; } (*output_buffer)->dataLenInBytes = rsa_len; DEBUG("- Finished\n"); return 1; } static void rsa_encrypt_op_buf_free(CpaCyRsaEncryptOpData * enc_op_data, CpaFlatBuffer * out_buf, int qat_svm) { DEBUG("- Started\n"); if (enc_op_data) { if (enc_op_data->pPublicKey) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(enc_op_data->pPublicKey->modulusN, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(enc_op_data->pPublicKey->publicExponentE, qat_svm); OPENSSL_free(enc_op_data->pPublicKey); } if (enc_op_data->inputData.pData) { OPENSSL_cleanse(enc_op_data->inputData.pData, enc_op_data->inputData.dataLenInBytes); QAT_MEM_FREE_NONZERO_BUFF(enc_op_data->inputData.pData,qat_svm); } OPENSSL_free(enc_op_data); } if (out_buf) { if (out_buf->pData && !qat_svm) { qaeCryptoMemFreeNonZero(out_buf->pData); } OPENSSL_free(out_buf); } DEBUG("- Finished\n"); } static int qat_rsa_encrypt(CpaCyRsaEncryptOpData * enc_op_data, CpaFlatBuffer * output_buf, int * fallback, int inst_num, int qat_svm) { /* Used for RSA Encrypt and RSA Verify */ op_done_t op_done; CpaStatus sts = CPA_STATUS_FAIL; int qatPerformOpRetries = 0; int job_ret = 0; thread_local_variables_t *tlv = NULL; int iMsgRetry = getQatMsgRetryCount(); useconds_t ulPollInterval = getQatPollInterval(); DEBUG("- Started\n"); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR); return 0; } #if defined(QAT_BORINGSSL) && defined(ENABLE_QAT_HW_RSA) qat_init_op_done(&op_done, qat_svm); #else qat_init_op_done(&op_done); #endif if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); return 0; } } /* * cpaCyRsaEncrypt() is the function called for RSA verify in the API. * For that particular case the enc_op_data [IN] contains both the * public key value and the signature value. The output_buf [OUT] * stores the message as the output once the request is fully completed. * The sts return value contains 0 (CPA_STATUS_SUCCESS) if the request * was successfully submitted. */ CRYPTO_QAT_LOG("RSA - %s\n", __func__); do { if (sts == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); return 0; } DUMP_RSA_ENCRYPT(qat_instance_handles[inst_num], &op_done, enc_op_data, output_buf); sts = cpaCyRsaEncrypt(qat_instance_handles[inst_num], qat_rsaCallbackFn, &op_done, enc_op_data, output_buf); if (sts == CPA_STATUS_RETRY) { DEBUG("cpaCyRsaDecrypt Retry \n"); if (op_done.job == NULL) { usleep(ulPollInterval + qatPerformOpRetries); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if (qat_rsa_coexist) { ++num_rsa_pub_retry; qat_sw_rsa_pub_req += QAT_SW_SWITCH_MB8; *fallback = 1; qat_cleanup_op_done(&op_done); return 0; } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } } while (sts == CPA_STATUS_RETRY); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", sts); if (qat_get_sw_fallback_enabled() && (sts == CPA_STATUS_RESTARTING || sts == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else if (sts == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm Unsupported in QAT_HW! Using OpenSSL SW\n"); *fallback = 1; } else { QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); return 0; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); return 0; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } if (qat_rsa_coexist) ++num_rsa_hw_pub_reqs; do { if(op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { if(getEnableInlinePolling()) { sts = icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); if (sts == CPA_STATUS_FAIL) { WARN("icp_sal_CyPollInstance failed - status %d\n", sts); op_done.flag = 1; } } else sched_yield(); } } while (!op_done.flag || (sts == CPA_STATUS_RETRY) || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_RSA_ENCRYPT_OUTPUT(output_buf); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info.physInstId.packageId, __func__); *fallback = 1; } else { QATerr(QAT_F_QAT_RSA_ENCRYPT, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); return 0; } qat_cleanup_op_done(&op_done); return 1; } static int build_encrypt_op_buf(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaCyRsaEncryptOpData ** enc_op_data, CpaFlatBuffer ** output_buffer, int alloc_pad, int qat_svm) { CpaCyRsaPublicKey *cpa_pub_key = NULL; int rsa_len = 0; int padding_result = 0; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; DEBUG("- Started\n"); RSA_get0_key((const RSA*)rsa, &n, &e, &d); /* Note: not checking 'd' as it is not used */ if (n == NULL || e == NULL) { WARN("RSA key values n = %p or e = %p are NULL\n", n, e); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_N_E_NULL); return 0; } DEBUG("flen =%d, padding = %d \n", flen, padding); rsa_len = RSA_size(rsa); if ((padding != RSA_NO_PADDING) && (padding != RSA_PKCS1_PADDING) && (padding != RSA_PKCS1_OAEP_PADDING) && # ifndef QAT_OPENSSL_3 (padding != RSA_SSLV23_PADDING) && # endif (padding != RSA_X931_PADDING)) { WARN("Unknown Padding %d\n", padding); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_UNKNOWN_PADDING); return 0; } cpa_pub_key = OPENSSL_zalloc(sizeof(CpaCyRsaPublicKey)); if (NULL == cpa_pub_key) { WARN("Public Key zalloc failed\n"); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_PUB_KEY_MALLOC_FAILURE); return 0; } /* Output and input data MUST allocate memory for RSA verify process */ /* Memory allocation for EncOpData[IN] */ *enc_op_data = OPENSSL_zalloc(sizeof(CpaCyRsaEncryptOpData)); if (NULL == *enc_op_data) { WARN("Failed to allocate enc_op_data\n"); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_ENC_OP_DATA_MALLOC_FAILURE); OPENSSL_free(cpa_pub_key); return 0; } /* Setup the Encrypt operation Data structure */ (*enc_op_data)->pPublicKey = cpa_pub_key; /* Passing Public key from big number format to big endian order binary */ if (qat_BN_to_FB(&cpa_pub_key->modulusN, n, qat_svm) != 1 || qat_BN_to_FB(&cpa_pub_key->publicExponentE, e, qat_svm) != 1) { WARN("Failed to convert cpa_pub_key elements to flatbuffer\n"); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_N_E_CONVERT_TO_FB_FAILURE); return 0; } (*enc_op_data)->inputData.pData = (Cpa8U *) qat_mem_alloc( ((padding != RSA_NO_PADDING) && alloc_pad) ? rsa_len : flen, qat_svm, __FILE__,__LINE__); if (NULL == (*enc_op_data)->inputData.pData) { WARN("Failed to allocate (*enc_op_data)->inputData.pData\n"); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_INPUT_DATA_MALLOC_FAILURE); return 0; } (*enc_op_data)->inputData.dataLenInBytes = ((padding != RSA_NO_PADDING) && alloc_pad) ? rsa_len : flen; if (alloc_pad) { switch (padding) { case RSA_PKCS1_PADDING: padding_result = RSA_padding_add_PKCS1_type_2((*enc_op_data)->inputData.pData, rsa_len, from, flen); break; case RSA_PKCS1_OAEP_PADDING: padding_result = RSA_padding_add_PKCS1_OAEP((*enc_op_data)->inputData.pData, rsa_len, from, flen, NULL, 0); break; # ifndef QAT_OPENSSL_3 case RSA_SSLV23_PADDING: padding_result = RSA_padding_add_SSLv23((*enc_op_data)->inputData.pData, rsa_len, from, flen); break; # endif case RSA_NO_PADDING: padding_result = RSA_padding_add_none((*enc_op_data)->inputData.pData, rsa_len, from, flen); break; default: QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, RSA_R_UNKNOWN_PADDING_TYPE); break; } } else { padding_result = RSA_padding_add_none((*enc_op_data)->inputData.pData, rsa_len, from, flen); } if (padding_result <= 0) { WARN("Failed to add padding\n"); /* Error is raised within the padding function. */ return 0; } /* * Memory allocation for outputBuffer[OUT] OutputBuffer size initialize * as the size of rsa size */ (*output_buffer) = (CpaFlatBuffer *) OPENSSL_zalloc(sizeof(CpaFlatBuffer)); if (NULL == (*output_buffer)) { WARN("Failed to allocate output_buffer\n"); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_OUTPUT_BUF_MALLOC_FAILURE); return 0; } /* * outputBuffer size should large enough to hold the Hash value but * smaller than (RSA_size(rsa)-11) */ (*output_buffer)->dataLenInBytes = rsa_len; if (!qat_svm) (*output_buffer)->pData = qaeCryptoMemAlloc(rsa_len, __FILE__, __LINE__); else (*output_buffer)->pData = (Cpa8U *) to; if (NULL == (*output_buffer)->pData) { WARN("Failed to allocate (*output_buffer)->pData\n"); QATerr(QAT_F_BUILD_ENCRYPT_OP_BUF, QAT_R_OUTPUT_BUF_PDATA_MALLOC_FAILURE); return 0;; } DEBUG("- Finished\n"); return 1; } /****************************************************************************** * function: * qat_rsa_priv_enc (int flen, * const unsigned char *from, * unsigned char *to, * RSA *rsa, * int padding) * * @param flen [IN] - length in bytes of input file * @param from [IN] - pointer to the input file * @param to [OUT] - pointer to output signature * @param rsa [IN] - pointer to private key structure * @param padding [IN] - Padding scheme * * description: Perform an RSA private encrypt (RSA Sign) * We use the decrypt implementation to achieve this. ******************************************************************************/ int qat_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int rsa_len = 0; CpaCyRsaDecryptOpData *dec_op_data = NULL; CpaFlatBuffer *output_buffer = NULL; int sts = 1, fallback = 0, dec_ret = 0; int inst_num = QAT_INVALID_INSTANCE; int qat_svm = QAT_INSTANCE_ANY; # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION unsigned char *ver_msg = NULL; const BIGNUM *d = NULL; RSA *lenstra_rsa = NULL; int lenstra_ret = -1; int memcmp_ret = -1; # endif #ifdef ENABLE_QAT_HW_KPT if (rsa && qat_check_rsa_wpk(rsa) > 0) { if (is_kpt_mode()) { DEBUG("Run the qat_rsa_priv_enc in KPT mode.\n"); return qat_hw_kpt_rsa_priv_enc(flen, from, to, rsa, padding); } else { WARN("Use the WPK in Non-KPT mode, return failed.\n"); return 0; } } #endif DEBUG("QAT HW RSA Started.\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if ((qat_sw_rsa_priv_req > 0) || qat_get_qat_offload_disabled()) { fallback = 1; goto exit; } START_RDTSC(&qat_hw_rsa_dec_req_prepare); /* Parameter Checking */ /* * The input message length should be less than or equal to RSA size and also have * minimum space of at least 11 bytes of padding if using PKCS1 padding. */ if (unlikely(rsa == NULL || from == NULL || to == NULL || flen <= 0)) { WARN("RSA key, input or output is NULL or invalid length, \ flen = %d\n", flen); QATerr(QAT_F_QAT_RSA_PRIV_ENC, QAT_R_RSA_FROM_TO_NULL); return 0; } rsa_len = RSA_size(rsa); /* * If the op sizes are not in the range supported by QAT engine then fall * back to software */ if (!qat_rsa_range_check(RSA_bits((const RSA*)rsa))) return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { WARN("Failed to get an instance - fallback to SW - %s\n", __func__); sts = 0; goto exit; } else { QATerr(QAT_F_QAT_RSA_PRIV_ENC, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (1 != build_decrypt_op_buf(flen, from, to, rsa, padding, &dec_op_data, &output_buffer, PADDING, inst_num, qat_svm)) { WARN("Failure in build_decrypt_op_buf\n"); /* Errors are already raised within build_decrypt_op_buf. */ sts = 0; goto exit; } dec_ret = qat_rsa_decrypt(dec_op_data, rsa_len, output_buffer, &fallback, inst_num, qat_svm); if (1 != dec_ret) { # ifdef QAT_BORINGSSL if (-1 == dec_ret) { DEBUG("Async job pause, waiting for wake up.\n"); /* For the Async mode when BoringSSL enabled, rsa_decrypt_op_buf_free is * called at the end of callback function. */ return 1; } else # endif /* QAT_BORINGSSL */ WARN("Failure in qat_rsa_decrypt fallback = %d\n", fallback); /* Errors are already raised within qat_rsa_decrypt. */ sts = 0; goto exit; } if (unlikely(output_buffer->pData == NULL)) { WARN("output_buffer->pData is NULL\n"); QATerr(QAT_F_QAT_RSA_PRIV_ENC, ERR_R_INTERNAL_ERROR); sts = 0; goto exit; } if (!qat_svm) memcpy(to, output_buffer->pData, rsa_len); rsa_decrypt_op_buf_free(dec_op_data, output_buffer, qat_svm); dec_op_data = NULL; output_buffer = NULL; # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION lenstra_rsa = copy_rsa_public_to_private_exponent(rsa); if (lenstra_rsa != NULL) d = RSA_get0_d((const RSA*)lenstra_rsa); if (d != NULL) { ver_msg = OPENSSL_zalloc(flen); if (ver_msg == NULL) { WARN("ver_msg zalloc failed.\n"); QATerr(QAT_F_QAT_RSA_PRIV_ENC, ERR_R_MALLOC_FAILURE); sts = 0; goto exit; } # ifdef ENABLE_QAT_HW_LENSTRA_VERIFY_HW lenstra_ret = qat_rsa_pub_dec(rsa_len, (const unsigned char *)to, ver_msg, rsa, padding); # else lenstra_ret = RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL()) (rsa_len, (const unsigned char *)to, ver_msg, lenstra_rsa, padding); # endif memcmp_ret = CRYPTO_memcmp(from, ver_msg, flen); if ((qat_constant_time_le_int(lenstra_ret, 0)) | (memcmp_ret != 0)) { WARN("QAT RSA Verify failed - redoing sign operation in s/w\n"); OPENSSL_free(ver_msg); return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); } OPENSSL_free(ver_msg); } if (lenstra_rsa != NULL) RSA_free(lenstra_rsa); # endif DEBUG("- Finished\n"); return rsa_len; exit: START_RDTSC(&qat_hw_rsa_dec_req_cleanup); /* Free all the memory allocated in this function */ rsa_decrypt_op_buf_free(dec_op_data, output_buffer, qat_svm); STOP_RDTSC(&qat_hw_rsa_dec_req_cleanup, 1, "[QAT HW RSA: cleanup]"); if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef ENABLE_QAT_SW_RSA if (qat_rsa_coexist) { DEBUG("- Switch to QAT SW mode.\n"); if (qat_sw_rsa_priv_req > 0) --qat_sw_rsa_priv_req; return multibuff_rsa_priv_enc(flen, from, to, rsa, padding); } #endif WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); } if (!sts) OPENSSL_cleanse(to, rsa_len); /* Return an error */ return 0; } /****************************************************************************** * function: * qat_rsa_priv_dec(int flen, * const unsigned char *from, * unsigned char *to, * RSA * rsa, * int padding) * * @param flen [IN] - length in bytes of input * @param from [IN] - pointer to the input * @param to [OUT] - pointer to output * @param rsa [IN] - pointer to the private key structure * @param padding [IN] - Padding scheme * * description: * description: Perform an RSA private decrypt. (RSA Decrypt) ******************************************************************************/ int qat_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int rsa_len = 0; int output_len = -1; int sts = 1, fallback = 0, dec_ret = 0; CpaCyRsaDecryptOpData *dec_op_data = NULL; CpaFlatBuffer *output_buffer = NULL; int inst_num = QAT_INVALID_INSTANCE; int qat_svm = QAT_INSTANCE_ANY; # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION unsigned char *ver_msg = NULL; const BIGNUM *d = NULL; RSA *lenstra_rsa = NULL; int lenstra_ret = -1; int memcmp_ret = -1; # endif unsigned char temp_buf[RSA_QAT_RANGE_MAX]; unsigned char *select_ptr = NULL; int rsa_priv_dec_sts = -1; #ifdef ENABLE_QAT_HW_KPT if (rsa && qat_check_rsa_wpk(rsa) > 0) { if (is_kpt_mode()) { DEBUG("Run the qat_rsa_priv_dec in KPT mode.\n"); return qat_hw_kpt_rsa_priv_dec(flen, from, to, rsa, padding); } else { WARN("Use the WPK in Non-KPT mode, return failed.\n"); return 0; } } #endif DEBUG("QAT HW RSA Started.\n"); if ((qat_sw_rsa_priv_req > 0) || qat_get_qat_offload_disabled()) { fallback = 1; goto exit; } START_RDTSC(&qat_hw_rsa_dec_req_prepare); /* parameter checks */ if (unlikely(rsa == NULL || from == NULL || to == NULL || (flen != (rsa_len = RSA_size(rsa))))) { WARN("RSA key, input or output is NULL or invalid length, \ flen = %d, rsa_len = %d\n", flen, rsa_len); QATerr(QAT_F_QAT_RSA_PRIV_DEC, QAT_R_RSA_FROM_TO_NULL); return 0; } /* * If the op sizes are not in the range supported by QAT engine then fall * back to software */ if (!qat_rsa_range_check(RSA_bits((const RSA*)rsa))) return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { WARN("Failed to get an instance - fallback to SW - %s\n", __func__); sts = 0; goto exit; } else { QATerr(QAT_F_QAT_RSA_PRIV_DEC, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (1 != build_decrypt_op_buf(flen, from, to, rsa, padding, &dec_op_data, &output_buffer, NO_PADDING, inst_num, qat_svm)) { WARN("Failure in build_decrypt_op_buf\n"); /* Errors are already raised within build_decrypt_op_buf. */ sts = 0; goto exit; } dec_ret = qat_rsa_decrypt(dec_op_data, rsa_len, output_buffer, &fallback, inst_num, qat_svm); if (1 != dec_ret) { # ifdef QAT_BORINGSSL if (-1 == dec_ret) { DEBUG("Async job pause, waiting for wake up.\n"); /* For the Async mode when BoringSSL enabled, rsa_decrypt_op_buf_free is * called at the end of callback function. * For private key decryption in BoringSSL, not add padding before return * since RSA_NO_PADDING is passed to RSA_decrypt in ssl_private_key_decrypt. */ return 1; } else # endif /* QAT_BORINGSSL */ WARN("Failure in qat_rsa_decrypt fallback = %d\n", fallback); if (fallback == 0) { /* Most but not all error cases are also raised within qat_rsa_decrypt. */ QATerr(QAT_F_QAT_RSA_PRIV_DEC, ERR_R_INTERNAL_ERROR); } sts = 0; goto exit; } # ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION lenstra_rsa = copy_rsa_public_to_private_exponent(rsa); if (lenstra_rsa != NULL) d = RSA_get0_d((const RSA*)lenstra_rsa); if (d != NULL) { ver_msg = OPENSSL_zalloc(flen); if (ver_msg == NULL) { WARN("ver_msg zalloc failed.\n"); QATerr(QAT_F_QAT_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE); sts = 0; goto exit; } # ifdef ENABLE_QAT_HW_LENSTRA_VERIFY_HW lenstra_ret = qat_rsa_pub_enc(rsa_len, (const unsigned char *)output_buffer->pData, ver_msg, rsa, RSA_NO_PADDING); # else lenstra_ret = RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL()) (rsa_len, (const unsigned char *)output_buffer->pData, ver_msg, lenstra_rsa, RSA_NO_PADDING); # endif memcmp_ret = CRYPTO_memcmp(from, ver_msg, flen); if ((qat_constant_time_le_int(lenstra_ret, 0)) | (memcmp_ret != 0)) { WARN("- QAT RSA sign failed - redoing decrypt operation in s/w\n"); OPENSSL_free(ver_msg); rsa_decrypt_op_buf_free(dec_op_data, output_buffer, qat_svm); return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); } OPENSSL_free(ver_msg); } if(lenstra_rsa != NULL) RSA_free(lenstra_rsa); # endif switch (padding) { case RSA_PKCS1_PADDING: output_len = RSA_padding_check_PKCS1_type_2(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; case RSA_PKCS1_OAEP_PADDING: output_len = RSA_padding_check_PKCS1_OAEP(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len, NULL, 0); break; # ifndef QAT_OPENSSL_3 case RSA_SSLV23_PADDING: output_len = RSA_padding_check_SSLv23(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; # endif case RSA_NO_PADDING: output_len = RSA_padding_check_none(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; default: break; } rsa_priv_dec_sts = qat_constant_time_select_int((output_len < 0), 0, output_len); rsa_decrypt_op_buf_free(dec_op_data, output_buffer, qat_svm); dec_op_data = NULL; output_buffer = NULL; select_ptr = qat_constant_time_select_ptr((rsa_priv_dec_sts == 0), to, temp_buf); OPENSSL_cleanse(select_ptr, rsa_len); return rsa_priv_dec_sts; exit: START_RDTSC(&qat_hw_rsa_dec_req_cleanup); /* Free all the memory allocated in this function */ rsa_decrypt_op_buf_free(dec_op_data, output_buffer, qat_svm); STOP_RDTSC(&qat_hw_rsa_dec_req_cleanup, 1, "[QAT HW RSA: cleanup]"); if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef ENABLE_QAT_SW_RSA if (qat_rsa_coexist) { DEBUG("- Switch to QAT_SW mode.\n"); if (qat_sw_rsa_priv_req > 0) --qat_sw_rsa_priv_req; return multibuff_rsa_priv_dec(flen, from, to, rsa, padding); } #endif WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); } if (!sts) OPENSSL_cleanse(to, rsa_len); /* Return an error */ return 0; } /****************************************************************************** * function: * qat_rsa_pub_enc(int flen, * const unsigned char *from, * unsigned char *to, * RSA *rsa, * int padding) * * @param flen [IN] - size in bytes of input * @param from [IN] - pointer to the input * @param to [OUT] - pointer to output data * @param rsa [IN] - pointer to public key structure * @param padding [IN] - Padding scheme * * * description: * This function is rewrite of OpenSSL RSA_pub_enc() function. (RSA Encrypt) * All the inputs are pass form the above OpenSSL layer to the corresponding * API RSA sign function cpaCyRsaEncrypt(). ******************************************************************************/ int qat_rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int rsa_len = 0; CpaCyRsaEncryptOpData *enc_op_data = NULL; CpaFlatBuffer *output_buffer = NULL; int sts = 1, fallback = 0; int inst_num = QAT_INVALID_INSTANCE; int qat_svm = QAT_INSTANCE_ANY; DEBUG("QAT HW RSA Started.\n"); if ((qat_sw_rsa_pub_req > 0) || qat_get_qat_offload_disabled()) { fallback = 1; goto exit; } /* parameter checks */ if (unlikely(rsa == NULL || from == NULL || to == NULL || flen < 0)) { WARN("RSA key %p, input %p or output %p are NULL, or flen invalid length.\n", rsa, from, to); QATerr(QAT_F_QAT_RSA_PUB_ENC, QAT_R_RSA_FROM_TO_NULL); return 0; } rsa_len = RSA_size(rsa); /* * If the op sizes are not in the range supported by QAT engine then fall * back to software */ if (!qat_rsa_range_check(RSA_bits((const RSA*)rsa))) return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { WARN("Failed to get an instance - fallback to SW - %s\n", __func__); sts = 0; goto exit; } else { QATerr(QAT_F_QAT_RSA_PUB_ENC, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (1 != build_encrypt_op_buf(flen, from, to, rsa, padding, &enc_op_data, &output_buffer, PADDING, qat_svm)) { WARN("Failure in build_encrypt_op_buf\n"); /* Errors are already raised within build_encrypt_op_buf. */ sts = 0; goto exit; } if (1 != qat_rsa_encrypt(enc_op_data, output_buffer, &fallback, inst_num, qat_svm)) { WARN("Failure in qat_rsa_encrypt\n"); /* Errors are already raised within qat_rsa_encrypt. */ sts = 0; goto exit; } else { if (unlikely(output_buffer->pData == NULL)) { WARN("output_buffer->pData is NULL\n"); QATerr(QAT_F_QAT_RSA_PUB_ENC, ERR_R_INTERNAL_ERROR); sts = 0; goto exit; } if (!qat_svm) memcpy(to, output_buffer->pData, output_buffer->dataLenInBytes); } rsa_encrypt_op_buf_free(enc_op_data, output_buffer, qat_svm); enc_op_data = NULL; output_buffer = NULL; DEBUG("- Finished\n"); return rsa_len; exit: /* Free all the memory allocated in this function */ rsa_encrypt_op_buf_free(enc_op_data, output_buffer, qat_svm); if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef ENABLE_QAT_SW_RSA if (qat_rsa_coexist) { DEBUG("- Switch to QAT_SW mode.\n"); if (qat_sw_rsa_pub_req > 0) --qat_sw_rsa_pub_req; return multibuff_rsa_pub_enc(flen, from, to, rsa, padding); } #endif WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); } if (!sts) OPENSSL_cleanse(to, rsa_len); return 0; } /****************************************************************************** * function: * qat_rsa_pub_dec(int flen, * const unsigned char *from, * unsigned char *to, * RSA *rsa, * int padding) * * @param flen [IN] - size in bytes of input * @param from [IN] - pointer to the input * @param to [OUT] - pointer to output data * @param rsa [IN] - pointer to public key structure * @param padding [IN] - Padding scheme * * description: * This function is rewrite of OpenSSL RSA_pub_dec() function (RSA Verify) * All the inputs are pass form the above OpenSSL layer to the corresponding * API RSA verify function cpaCyRsaEncrypt(). * The function returns the RSA recovered message output. * We use the encrypt implementation to achieve this. ******************************************************************************/ int qat_rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int rsa_len = 0; int output_len = -1; CpaCyRsaEncryptOpData *enc_op_data = NULL; CpaFlatBuffer *output_buffer = NULL; int sts = 1, fallback = 0; int inst_num = QAT_INVALID_INSTANCE; int qat_svm = QAT_INSTANCE_ANY; unsigned char temp_buf[RSA_QAT_RANGE_MAX]; unsigned char *select_ptr = NULL; int rsa_pub_dec_sts = -1; DEBUG("QAT HW RSA Started.\n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if ((qat_sw_rsa_pub_req > 0) || qat_get_qat_offload_disabled()) { fallback = 1; goto exit; } /* parameter checking */ if (rsa == NULL || from == NULL || to == NULL || (flen != (rsa_len = RSA_size(rsa)))) { WARN("RSA key %p, input %p or output %p are NULL or invalid length, \ flen = %d, rsa_len = %d\n", rsa, from, to, flen, rsa_len); QATerr(QAT_F_QAT_RSA_PUB_DEC, QAT_R_RSA_FROM_TO_NULL); return 0; } /* * If the op sizes are not in the range supported by QAT engine then fall * back to software */ if (!qat_rsa_range_check(RSA_bits((const RSA*)rsa))) return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failed to get an instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; sts = 0; goto exit; } else { QATerr(QAT_F_QAT_RSA_PUB_DEC, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; if (1 != build_encrypt_op_buf(flen, from, to, rsa, padding, &enc_op_data, &output_buffer, NO_PADDING, qat_svm)) { WARN("Failure in build_encrypt_op_buf\n"); /* Errors are already raised within build_encrypt_op_buf. */ sts = 0; goto exit; } if (1 != qat_rsa_encrypt(enc_op_data, output_buffer, &fallback, inst_num, qat_svm)) { WARN("Failure in qat_rsa_encrypt\n"); /* Errors are already raised within qat_rsa_encrypt. */ sts = 0; goto exit; } switch (padding) { case RSA_PKCS1_PADDING: output_len = RSA_padding_check_PKCS1_type_1(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; case RSA_X931_PADDING: output_len = RSA_padding_check_X931(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; case RSA_NO_PADDING: output_len = RSA_padding_check_none(to, rsa_len, output_buffer->pData, output_buffer->dataLenInBytes, rsa_len); break; default: break; } rsa_pub_dec_sts = qat_constant_time_select_int((output_len < 0), 0, output_len); rsa_encrypt_op_buf_free(enc_op_data, output_buffer, qat_svm); enc_op_data = NULL; output_buffer = NULL; select_ptr = qat_constant_time_select_ptr((rsa_pub_dec_sts == 0), to, temp_buf); OPENSSL_cleanse(select_ptr, rsa_len); return rsa_pub_dec_sts; exit: /* Free all the memory allocated in this function */ rsa_encrypt_op_buf_free(enc_op_data, output_buffer, qat_svm); if (fallback) { CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); #ifdef ENABLE_QAT_SW_RSA if (qat_rsa_coexist) { DEBUG("- Switch to QAT_SW mode.\n"); if (qat_sw_rsa_pub_req > 0) --qat_sw_rsa_pub_req; return multibuff_rsa_pub_dec(flen, from, to, rsa, padding); } #endif WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL()) (flen, from, to, rsa, padding); } if (!sts) OPENSSL_cleanse(to, rsa_len); return 0; } # ifndef QAT_BORINGSSL /****************************************************************************** * function: * qat_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) * * @param r0 [IN] - Result bignum of mod_exp * @param I [IN] - Base used for mod_exp * @param rsa [IN] - Exponent used for mod_exp * @param ctx [IN] - EVP context. * * description: * Returns sw implementation of rsa_mod_exp * *******************************************************************************/ int qat_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { DEBUG("- Started\n"); return RSA_meth_get_mod_exp(RSA_PKCS1_OpenSSL()) (r0, I, rsa, ctx); } /****************************************************************************** * function: * qat_rsa_init(RSA *rsa) * * @param rsa [IN] - The RSA data structure * * description: * Returns sw implementation of rsa_init. * Needed to ensure correct caching occurs. * *******************************************************************************/ int qat_rsa_init(RSA *rsa) { return RSA_meth_get_init(RSA_PKCS1_OpenSSL())(rsa); } /****************************************************************************** * function: * qat_rsa_finish(RSA *rsa) * * @param rsa [IN] - The RSA data structure * * description: * Returns sw implementation of rsa_finish. * Needed to ensure correct cleanup of cached data. * *******************************************************************************/ int qat_rsa_finish(RSA *rsa) { return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa); } #else /* Referred to boringssl/crypto/fipsmodule/rsa/rsa_impl.c*/ int qat_rsa_priv_sign(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { int len = 0; const unsigned rsa_size = RSA_size(rsa); int __attribute__((unused)) _ret; if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); _ret = ASYNC_current_job_last_check_and_get(); return 0; } len = qat_rsa_priv_enc(in_len, in, out, rsa, padding); if(0 >= len) { _ret = ASYNC_current_job_last_check_and_get(); return 0; } if (1 == len) { /* async mode */ _ret = ASYNC_current_job_last_check_and_get(); len = 0; } *out_len = len; return 1; } int qat_rsa_priv_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { int len = 0; const unsigned rsa_size = RSA_size(rsa); int __attribute__((unused)) _ret; if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); _ret = ASYNC_current_job_last_check_and_get(); return 0; } if (in_len != rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); _ret = ASYNC_current_job_last_check_and_get(); return 0; } len = qat_rsa_priv_dec(in_len, in, out, rsa, padding); if(0 >= len) { _ret = ASYNC_current_job_last_check_and_get(); return 0; } if (1 == len) { /* async mode */ _ret = ASYNC_current_job_last_check_and_get(); len = 0; } *out_len = len; return 1; } # endif /* QAT_BORINGSSL */ #endif /* ENABLE_QAT_HW_RSA */ qatengine-1.9.0/qat_hw_rsa.h000066400000000000000000000064171500416242000157770ustar00rootroot00000000000000 /* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_rsa.h * * This file provides an RSA interface for an OpenSSL engine * *****************************************************************************/ #ifndef QAT_HW_RSA_H # define QAT_HW_RSA_H # include #ifdef ENABLE_QAT_HW_RSA /* Qat engine RSA methods declaration */ int qat_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int qat_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int qat_rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int qat_rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); #ifndef QAT_BORINGSSL int qat_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); int qat_rsa_init(RSA *rsa); int qat_rsa_finish(RSA *rsa); #else /* QAT_BORINGSSL */ int qat_rsa_priv_sign(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); int qat_rsa_priv_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); #endif /* QAT_BORINGSSL */ #endif #endif /* QAT_HW_RSA_H */ qatengine-1.9.0/qat_hw_sha3.c000066400000000000000000001151161500416242000160400ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sha3.c * * This file contains the engine implementations for SHA3 Hash operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include "e_qat.h" #include "qat_utils.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_evp.h" #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_sym.h" #include "qat_hw_sha3.h" #include "qat_hw_ciphers.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #include #include #include #include #include #ifdef QAT_HW_INTREE # ifndef ENABLE_QAT_HW_SHA3 # define ENABLE_QAT_HW_SHA3 # endif #endif # define GET_SW_SHA3_DIGEST(ctx) \ qat_sha3_sw_impl(EVP_MD_CTX_type((ctx)) ) #ifdef ENABLE_QAT_HW_SHA3 # ifndef QAT_OPENSSL_PROVIDER static int qat_sha3_init(EVP_MD_CTX *ctx); static int qat_sha3_cleanup(EVP_MD_CTX *ctx); static int qat_sha3_update(EVP_MD_CTX *ctx, const void *in, size_t len); static int qat_sha3_final(EVP_MD_CTX *ctx, unsigned char *md); static int qat_sha3_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); static int qat_sha3_ctrl(EVP_MD_CTX *ctx, int type, int p1,void *p2); static int qat_get_sha3_block_size(int nid); static int qat_get_sha3_state_size(int nid); # endif #endif #ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; #endif static inline const EVP_MD *qat_sha3_sw_impl(int nid) { switch (nid) { case NID_sha3_224: return EVP_sha3_224(); case NID_sha3_256: return EVP_sha3_256(); case NID_sha3_384: return EVP_sha3_384(); case NID_sha3_512: return EVP_sha3_512(); default: WARN("Invalid nid %d\n", nid); return NULL; } } #if defined(ENABLE_QAT_HW_SHA3) && !defined(QAT_OPENSSL_PROVIDER) int qat_sha3_md_methods(EVP_MD *c, int blocksize, int statesize) { int res = 1; res &= EVP_MD_meth_set_result_size(c, statesize); res &= EVP_MD_meth_set_input_blocksize(c,blocksize); res &= EVP_MD_meth_set_app_datasize(c, sizeof(EVP_MD*) + sizeof(qat_sha3_ctx) + sizeof(SHA3_CTX)); res &= EVP_MD_meth_set_flags(c, EVP_MD_CTX_FLAG_REUSE); res &= EVP_MD_meth_set_init(c, qat_sha3_init); res &= EVP_MD_meth_set_update(c, qat_sha3_update); res &= EVP_MD_meth_set_final(c, qat_sha3_final); res &= EVP_MD_meth_set_copy(c, qat_sha3_copy); res &= EVP_MD_meth_set_ctrl(c, qat_sha3_ctrl); return res; } #endif const EVP_MD *qat_create_sha3_meth(int nid , int key_type) { #if defined(ENABLE_QAT_HW_SHA3) && !defined(QAT_OPENSSL_PROVIDER) EVP_MD *c = NULL; int res = 1; int blocksize,statesize = 0; if ((c = EVP_MD_meth_new(nid,key_type)) == NULL) { WARN("Failed to allocate digest methods for nid %d\n", nid); return NULL; } blocksize = qat_get_sha3_block_size(nid); if (!blocksize){ WARN("Failed to get block size for nid %d\n", nid); EVP_MD_meth_free(c); return NULL; } statesize = qat_get_sha3_state_size(nid); if (!statesize){ WARN("Failed to state size for nid %d\n", nid); EVP_MD_meth_free(c); return NULL; } if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_SHA3)) { res = qat_sha3_md_methods(c, blocksize, statesize); if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_MD_meth_free(c); return NULL; } qat_hw_sha_offload = 1; DEBUG("QAT HW SHA3 Registration succeeded\n"); return c; } else { qat_hw_sha_offload = 0; # ifdef QAT_OPENSSL_3 qat_openssl3_sha_fallback = 1; res = qat_sha3_md_methods(c, blocksize, statesize); if (0 == res) { WARN("Failed to set cipher methods for nid %d\n", nid); EVP_MD_meth_free(c); return NULL; } return c; # else DEBUG("QAT HW SHA3 is disabled, using OpenSSL SW\n"); EVP_MD_meth_free(c); return qat_sha3_sw_impl(nid); # endif } #else qat_hw_sha_offload = 0; DEBUG("QAT HW SHA3 is disabled, using OpenSSL SW\n"); return qat_sha3_sw_impl(nid); #endif } #ifdef ENABLE_QAT_HW_SHA3 static const CpaCySymOpData template_opData = { .sessionCtx = NULL, .packetType = CPA_CY_SYM_PACKET_TYPE_FULL, .pIv = NULL, .ivLenInBytes = 0, .cryptoStartSrcOffsetInBytes = 0, .messageLenToCipherInBytes = 0, .hashStartSrcOffsetInBytes = 0, .messageLenToHashInBytes = 0, .pDigestResult = NULL, .pAdditionalAuthData = NULL }; #ifndef QAT_OPENSSL_PROVIDER static int qat_get_sha3_block_size(int nid) { switch (nid) { case NID_sha3_224: return QAT_SHA3_224_BLOCK_SIZE; case NID_sha3_256: return QAT_SHA3_256_BLOCK_SIZE; case NID_sha3_384: return QAT_SHA3_384_BLOCK_SIZE; case NID_sha3_512: return QAT_SHA3_512_BLOCK_SIZE; default: WARN("Unsupported Hash Algorithm\n"); return 0; } } static int qat_get_sha3_state_size(int nid) { switch (nid) { case NID_sha3_224: return QAT_SHA3_224_STATE_SIZE; case NID_sha3_256: return QAT_SHA3_256_STATE_SIZE; case NID_sha3_384: return QAT_SHA3_384_STATE_SIZE; case NID_sha3_512: return QAT_SHA3_512_STATE_SIZE; default: WARN("Unsupported Hash Algorithm\n"); return 0; } } #endif static int qat_get_sha3_data_size(int nid) { switch (nid) { case NID_sha3_224: return QAT_SHA3_224_OFFLOAD_THRESHOLD; case NID_sha3_256: return QAT_SHA3_256_OFFLOAD_THRESHOLD; case NID_sha3_384: return QAT_SHA3_384_OFFLOAD_THRESHOLD; case NID_sha3_512: return QAT_SHA3_512_OFFLOAD_THRESHOLD; default: WARN("Unsupported Hash Algorithm\n"); return 0; } } static int qat_get_hash_alg_data(int nid) { switch (nid) { case NID_sha3_224: return CPA_CY_SYM_HASH_SHA3_224; case NID_sha3_256: return CPA_CY_SYM_HASH_SHA3_256; case NID_sha3_384: return CPA_CY_SYM_HASH_SHA3_384; case NID_sha3_512: return CPA_CY_SYM_HASH_SHA3_512; default: WARN("Unsupported Hash Algorithm\n"); return 0; } } /****************************************************************************** * function: * qat_sha3_session_data_init(EVP_MD_CTX *ctx,qat_sha3_ctx *sha3_ctx) * * @param ctx [IN] - pointer to the existing context * @param sha3_ctx [IN] - pointer to the sha3 context * * description: * This function is to create QAT specific session data. * * It will return 1 if successful and 0 on failure. ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER static int qat_sha3_session_data_init(QAT_KECCAK1600_CTX *ctx, qat_sha3_ctx *sha3_ctx) #else static int qat_sha3_session_data_init(EVP_MD_CTX *ctx, qat_sha3_ctx *sha3_ctx) #endif { CpaCySymSessionSetupData *session_data = NULL; CpaCySymOpData *pOpData = NULL; if (NULL == sha3_ctx || NULL == ctx){ WARN("sha3_ctx or ctx is NULL\n"); QATerr(QAT_F_QAT_SHA3_SESSION_DATA_INIT, QAT_R_SHA3_CTX_NULL); return 0; } session_data = OPENSSL_zalloc(sizeof(CpaCySymSessionSetupData)); if (NULL == session_data) { WARN("session setup data Malloc failure\n"); QATerr(QAT_F_QAT_SHA3_SESSION_DATA_INIT, QAT_R_SSD_MALLOC_FAILURE); return 0; } /* Set priority and operation of this session */ session_data->sessionPriority = CPA_CY_PRIORITY_HIGH; session_data->symOperation = CPA_CY_SYM_OP_HASH; /* Set the hash mode and the length of the digest */ #ifdef QAT_OPENSSL_PROVIDER session_data->hashSetupData.hashAlgorithm = qat_get_hash_alg_data(ctx->md_type); #else session_data->hashSetupData.hashAlgorithm = qat_get_hash_alg_data(EVP_MD_CTX_type(ctx)); #endif session_data->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN; session_data->hashSetupData.digestResultLenInBytes = sha3_ctx->md_size; session_data->hashSetupData.authModeSetupData.authKey = NULL; session_data->hashSetupData.nestedModeSetupData.pInnerPrefixData = NULL; session_data->hashSetupData.nestedModeSetupData.pOuterPrefixData = NULL; /* Tag follows immediately after the region to hash */ session_data->digestIsAppended = CPA_FALSE; /* digestVerify is not required to be set.*/ session_data->verifyDigest = CPA_FALSE; pOpData = OPENSSL_zalloc(sizeof(template_opData)); if (pOpData == NULL) { WARN("memory allocation failed for symopData struct.\n"); QATerr(QAT_F_QAT_SHA3_SESSION_DATA_INIT, ERR_R_MALLOC_FAILURE); OPENSSL_free(session_data); return 0; } sha3_ctx->session_data = session_data; sha3_ctx->opd = pOpData; sha3_ctx->context_params_set = 1; return 1; } /****************************************************************************** * function: * qat_sha3_init(EVP_MD_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the hash algorithm parameters for EVP context. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_sha3_init(QAT_KECCAK1600_CTX *ctx) #else static int qat_sha3_init(EVP_MD_CTX *ctx) #endif { qat_sha3_ctx* sha3_ctx = NULL; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int sts = 0; #endif if (NULL == ctx) { WARN("ctx is NULL\n"); return 0; } #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (qat_openssl3_sha_fallback == 1) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } #endif DEBUG("QAT HW SHA3 init Started ctx %p\n", ctx); /* Initialise a QAT session and set the hash*/ #ifdef QAT_OPENSSL_PROVIDER sha3_ctx = ctx->qctx; #else sha3_ctx = QAT_SHA3_GET_CTX(ctx); #endif if (NULL == sha3_ctx) { WARN("sha3_ctx is NULL\n"); return 0; } #ifdef QAT_OPENSSL_PROVIDER sha3_ctx->md_size = ctx->md_size; #else sha3_ctx->md_size = EVP_MD_CTX_size(ctx); #endif if (!sha3_ctx->md_size) { WARN("sha3_ctx md size is NULL\n"); return 0; } sha3_ctx->context_params_set = 0; sha3_ctx->session_init = 0; #ifndef QAT_OPENSSL_PROVIDER # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD /* Update the software init data */ KECCAK1600_CTX *k_ctx = EVP_MD_CTX_md_data(ctx); size_t bsz = EVP_MD_CTX_block_size(ctx); if (bsz <= sizeof(k_ctx->buf)) { memset(k_ctx->A, 0, sizeof(k_ctx->A)); k_ctx->num = 0; k_ctx->block_size = bsz; k_ctx->md_size = EVP_MD_CTX_size(ctx); k_ctx->pad = '\x06'; } # endif #endif return 1; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) use_sw_method: sts = EVP_MD_meth_get_init(GET_SW_SHA3_DIGEST(ctx))(ctx); DEBUG("SW Finished %p\n", ctx); return sts; #endif } /****************************************************************************** * function: * qat_sha3_ctrl(EVP_MD_CTX *ctx,int type, int p1, void *p2) * * @param ctx [IN] - pointer to existing context * @param type [IN] - type of request * @param p1 [IN] - size of the pointed to by ptr * @param p2 [IN] - input buffer contain the necessary parameters * * @retval 1 function succeeded * @retval -1 function failed * * description: * This function is a generic control interface provided by the EVP API. * ******************************************************************************/ #ifndef QAT_OPENSSL_PROVIDER static int qat_sha3_ctrl(EVP_MD_CTX *ctx, int type, int p1, void *p2) { qat_sha3_ctx *sha3_ctx = NULL; if (NULL == ctx) { WARN("ctx is NULL.\n"); QATerr(QAT_F_QAT_SHA3_CTRL, QAT_R_CTX_NULL); return 0; } sha3_ctx = QAT_SHA3_GET_CTX(ctx); if (NULL == sha3_ctx) { WARN("SHA3ctx is NULL\n"); QATerr(QAT_F_QAT_SHA3_CTRL, QAT_R_SHA3_CTX_NULL); return 0; } switch (type) { case EVP_MD_CTRL_XOF_LEN: sha3_ctx->md_size = p1; DEBUG("EVP_MD_CTRL_XOF_LEN, ctx = %p, type = %d, " "p1 = %d, p2 = %p\n", (void*)ctx, type, p1 ,(void*) p2); return 1; default: WARN("Invalid type %d\n", type); QATerr(QAT_F_QAT_SHA3_CTRL, QAT_R_INVALID_CTRL_TYPE); return -1; } } #endif /****************************************************************************** * function: * qat_sha3_cleanup(EVP_MD_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_sha3_cleanup(QAT_KECCAK1600_CTX *ctx) #else static int qat_sha3_cleanup(EVP_MD_CTX *ctx) #endif { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif qat_sha3_ctx* sha3_ctx = NULL; CpaStatus status = 0; int ret_val = 1; if (NULL == ctx) { WARN("ctx is NULL\n"); QATerr(QAT_F_QAT_SHA3_CLEANUP, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER sha3_ctx = ctx->qctx; #else sha3_ctx = QAT_SHA3_GET_CTX(ctx); #endif if (NULL == sha3_ctx) { WARN("digest cleanup without md_data\n"); return 1; } if (sha3_ctx->session_init) { QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->pSrcBufferList.pPrivateMetaData, sha3_ctx->qat_svm); sha3_ctx->pSrcBufferList.pPrivateMetaData = NULL; if (is_instance_available(sha3_ctx->inst_num)) { /* Wait for in-flight requests before removing session */ CpaBoolean sessionInUse = CPA_FALSE; if (sha3_ctx->session_ctx != NULL) { do { cpaCySymSessionInUse(sha3_ctx->session_ctx, &sessionInUse); } while (sessionInUse); } if ((status = cpaCySymRemoveSession(qat_instance_handles[sha3_ctx->inst_num], sha3_ctx->session_ctx)) != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, status= %d.!\n", status); ret_val = 0; /* Lets not return yet and instead make a best effort to * cleanup the rest to avoid memory leaks */ } QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->session_ctx, sha3_ctx->qat_svm); sha3_ctx->session_ctx = NULL; } sha3_ctx->session_init = 0; } if (sha3_ctx->context_params_set) { if (sha3_ctx->opd) { OPENSSL_free(sha3_ctx->opd); sha3_ctx->opd = NULL; } OPENSSL_clear_free(sha3_ctx->session_data, sizeof(CpaCySymSessionSetupData)); sha3_ctx->context_params_set = 0; } DEBUG("cleanup done\n"); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif DEBUG("cleanup done\n"); return ret_val; } /****************************************************************************** * function: * * static void qat_sha3_cb(void *pCallbackTag, CpaStatus status, * const CpaCySymOp operationType, * void *pOpData, CpaBufferList *pDstBuffer, * CpaBoolean verifyResult) * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. Cast to op_done_pipe_t. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: Callback to indicate the completion of crypto operation ******************************************************************************/ static void qat_sha3_cb(void *pCallbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList *pDstBuffer, CpaBoolean verifyResult) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_HASH, pOpData, NULL, CPA_TRUE); } /****************************************************************************** * function: * qat_sha3_setup_param(EVP_MD_CTX *ctx) * * @param ctx [IN] - pointer to context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function synchronises the initialisation of the QAT session and * pre-allocates the necessary buffers for the session. ******************************************************************************/ static int qat_sha3_setup_param(qat_sha3_ctx *sha3_ctx) { int numBuffers = 1; Cpa32U bufferMetaSize = 0; Cpa32U sctx_size = 0; CpaStatus status; if (sha3_ctx == NULL) { WARN("sha3 context data is NULL.\n"); QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, QAT_R_SHA3_CTX_NULL); return 0; } /* Allocate instance */ sha3_ctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (sha3_ctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); return 0; } sha3_ctx->qat_svm = !qat_instance_details[sha3_ctx->inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; DEBUG("inst_num = %d Size of session ctx = %d inst mem type = %d \n", sha3_ctx->inst_num, sctx_size, sha3_ctx->qat_svm); /* Determine size of session context to allocate */ status = cpaCySymSessionCtxGetSize(qat_instance_handles[sha3_ctx->inst_num], sha3_ctx->session_data, &sctx_size); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); return 0; } DEBUG("inst_num = %d, Size of session ctx = %d\n", sha3_ctx->inst_num, sctx_size); sha3_ctx->session_ctx = (CpaCySymSessionCtx)qat_mem_alloc(sctx_size, sha3_ctx->qat_svm, __FILE__, __LINE__); if (sha3_ctx->session_ctx == NULL) { WARN("Memory alloc failed for session ctx\n"); QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, ERR_R_MALLOC_FAILURE); return 0; } DUMP_SESSION_SETUP_DATA(sha3_ctx->session_data); /* Initialise Session data */ /* Remove session should be added if session init fail. */ status = cpaCySymInitSession(qat_instance_handles[sha3_ctx->inst_num], qat_sha3_cb, sha3_ctx->session_data, sha3_ctx->session_ctx); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCySymInitSession failed! Status = %d\n", status); if (((status == CPA_STATUS_RESTARTING) || (status == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d\n", sha3_ctx->inst_num, qat_instance_details[sha3_ctx->inst_num].qat_instance_info.physInstId.packageId); } QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->session_ctx, sha3_ctx->qat_svm); return 0; } /* Get buffer metasize */ status = cpaCyBufferListGetMetaSize(qat_instance_handles[sha3_ctx->inst_num], numBuffers, &bufferMetaSize); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetMetaSize failed for the instance id %d\n", sha3_ctx->inst_num); QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->session_ctx, sha3_ctx->qat_svm); return 0; } DEBUG("Buffer MetaSize : %d\n", bufferMetaSize); if (bufferMetaSize) { sha3_ctx->pSrcBufferList.pPrivateMetaData = qat_mem_alloc(bufferMetaSize, sha3_ctx->qat_svm, __FILE__, __LINE__); if (sha3_ctx->pSrcBufferList.pPrivateMetaData == NULL) { WARN("QMEM alloc failed for PrivateData\n"); QATerr(QAT_F_QAT_SHA3_SETUP_PARAM, ERR_R_MALLOC_FAILURE); QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->session_ctx, sha3_ctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->pSrcBufferList.pPrivateMetaData, sha3_ctx->qat_svm); return 0; } sha3_ctx->pSrcBufferList.numBuffers = numBuffers; } else { sha3_ctx->pSrcBufferList.pPrivateMetaData = NULL; sha3_ctx->pSrcBufferList.numBuffers = 0; } sha3_ctx->pSrcBufferList.pUserData = NULL; sha3_ctx->pSrcBufferList.pBuffers = &sha3_ctx->src_buffer; sha3_ctx->src_buffer.pData = NULL; /* Mark session init as set. */ sha3_ctx->session_init = 1; return 1; } #ifdef QAT_OPENSSL_PROVIDER static int qat_hw_sha3_offload(QAT_KECCAK1600_CTX *ctx, const void *in, size_t len, int packet_type) #else static int qat_hw_sha3_offload(EVP_MD_CTX *ctx, const void *in, size_t len, int packet_type) #endif { int job_ret = 0; CpaStatus status; op_done_t op_done; thread_local_variables_t *tlv = NULL; qat_sha3_ctx *sha3_ctx = NULL; Cpa8U *pDigestBuffer = NULL; int ret = 0; if (unlikely((ctx == NULL) || (in == NULL))) { WARN("Either ctx %p or in %p is NULL\n", ctx, in); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, QAT_R_INVALID_INPUT); return -1; } #ifdef QAT_OPENSSL_PROVIDER sha3_ctx = ctx->qctx; #else sha3_ctx = QAT_SHA3_GET_CTX(ctx); #endif if (sha3_ctx == NULL) { WARN("SHA3 context hash data is NULL.\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, QAT_R_SHA3_CTX_NULL); return -1; } #ifdef QAT_OPENSSL_PROVIDER sha3_ctx->md_size = ctx->md_size; #else sha3_ctx->md_size = EVP_MD_CTX_size(ctx); #endif /* Initialize QAT session */ if (!sha3_ctx->context_params_set) { if (0 == qat_sha3_session_data_init(ctx, sha3_ctx)) { WARN("qat_session_data_init failed.\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); return 0; } } if (sha3_ctx->context_params_set && !sha3_ctx->session_init) { /* Set SHA3 opdata params and initialise session. */ if (!qat_sha3_setup_param(sha3_ctx)) { WARN("SHA3 operational params setup failed.\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); return 0; } } /* The variables in and out remain separate */ sha3_ctx->src_buffer.pData = qat_mem_alloc(len + sha3_ctx->md_size, sha3_ctx->qat_svm, __FILE__, __LINE__); if ((sha3_ctx->src_buffer.pData) == NULL) { WARN("Unable to allocate memory for buffer for sha3 hash.\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_MALLOC_FAILURE); goto err; } sha3_ctx->src_buffer.dataLenInBytes = len + sha3_ctx->md_size; pDigestBuffer = sha3_ctx->src_buffer.pData + len; memcpy(sha3_ctx->src_buffer.pData, in, len); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } sha3_ctx->pSrcBufferList.pUserData = NULL; sha3_ctx->opd->sessionCtx = sha3_ctx->session_ctx; /* The type 'last partial cannot set without a partial set previous */ if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packet_type && sha3_ctx->qat_offloaded == 0) { DEBUG("SHA3 data packet type: FULL\n"); sha3_ctx->opd->packetType = CPA_CY_SYM_PACKET_TYPE_FULL; } else { DEBUG("SHA3 data packet type partial or last partial\n"); sha3_ctx->opd->packetType = packet_type; } /* The message length, in bytes, of the source buffer that the hash * will be computed on. */ sha3_ctx->opd->messageLenToHashInBytes = len; sha3_ctx->opd->pDigestResult = pDigestBuffer; if (!is_instance_available(sha3_ctx->inst_num)) { WARN("QAT instance %d not available.\n", sha3_ctx->inst_num); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } DUMP_SYM_PERFORM_OP_SHA3(qat_instance_handles[sha3_ctx->inst_num], sha3_ctx->opd, sha3_ctx->pSrcBufferList, sha3_ctx->pSrcBufferList); /* same src & dst for an in-place operation */ status = qat_sym_perform_op(sha3_ctx->inst_num, &op_done, sha3_ctx->opd, &(sha3_ctx->pSrcBufferList), &(sha3_ctx->pSrcBufferList), &(sha3_ctx->session_data->verifyDigest)); if (status != CPA_STATUS_SUCCESS) { if (((status == CPA_STATUS_RESTARTING) || (status == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - %s\n", sha3_ctx->inst_num, qat_instance_details[sha3_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } else if (status == CPA_STATUS_UNSUPPORTED) { WARN("Algorithm type unsupported in QAT_HW\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, QAT_R_ALGO_TYPE_UNSUPPORTED); } QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) { sched_yield(); } } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); QATerr(QAT_F_QAT_HW_SHA3_OFFLOAD, ERR_R_INTERNAL_ERROR); if (op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG("Verification of result failed for qat inst_num %d device_id %d - %s\n", sha3_ctx->inst_num, qat_instance_details[sha3_ctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qat_cleanup_op_done(&op_done); goto err; } } qat_cleanup_op_done(&op_done); /* final partial */ if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packet_type) memcpy(sha3_ctx->digest_data, sha3_ctx->opd->pDigestResult, sha3_ctx->md_size); else sha3_ctx->qat_offloaded = 1; ret = 1; err: QAT_MEM_FREE_NONZERO_BUFF(sha3_ctx->src_buffer.pData, sha3_ctx->qat_svm); sha3_ctx->src_buffer.pData = NULL; sha3_ctx->opd->pDigestResult = NULL; return ret; } #ifdef QAT_OPENSSL_PROVIDER int qat_sha3_copy(QAT_KECCAK1600_CTX *to, const QAT_KECCAK1600_CTX *from) #else static int qat_sha3_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) #endif { qat_sha3_ctx *qat_from, *qat_to; if (NULL == from || NULL == to) { WARN("Either from %p or to %p are NULL\n", from, to); return 0; } DEBUG("Copy to %p from %p \n", to, from); #ifdef QAT_OPENSSL_PROVIDER qat_from = from->qctx; if (qat_from == NULL) { WARN("digest copy without md_data\n"); return 1; } qat_to = to->qctx; #else qat_from = QAT_SHA3_GET_CTX(from); if (qat_from == NULL) { WARN("digest copy without md_data\n"); return 1; } qat_to = QAT_SHA3_GET_CTX(to); #endif if (NULL == qat_to) { WARN("qat_to %p is NULL\n", qat_to); return 0; } qat_to->pSrcBufferList.numBuffers = 1; if (qat_from->pSrcBufferList.pPrivateMetaData) { qat_to->pSrcBufferList.pPrivateMetaData = qat_from->pSrcBufferList.pPrivateMetaData; } else { qat_to->pSrcBufferList.pPrivateMetaData = NULL; } qat_to->pSrcBufferList.pUserData = NULL; qat_to->pSrcBufferList.pBuffers = &qat_to->src_buffer; return 1; } /****************************************************************************** * function: * qat_sha3_final(EVP_MD_CTX *ctx, unsigned char *md) * * @param ctx [IN] - pointer to existing context * @param md [OUT] - output buffer for digest result * * @retval -1 function failed * @retval 1 function succeeded * * description: * This function performs the copy operation of digest into md buffer. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_sha3_final(QAT_KECCAK1600_CTX *ctx, unsigned char *md) #else static int qat_sha3_final(EVP_MD_CTX *ctx, unsigned char *md) #endif { qat_sha3_ctx *sha3_ctx = NULL; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int sts = 0; #endif #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(ctx == NULL)) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_SHA3_FINAL, QAT_R_CTX_NULL); return -1; } #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (qat_openssl3_sha_fallback == 1) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } #endif #ifdef QAT_OPENSSL_PROVIDER sha3_ctx = ctx->qctx; #else sha3_ctx = QAT_SHA3_GET_CTX(ctx); #endif if (sha3_ctx == NULL) { WARN("SHA3 context hash data is NULL.\n"); QATerr(QAT_F_QAT_SHA3_FINAL, QAT_R_SHA3_CTX_NULL); return -1; } DEBUG("QAT HW SHA3 final, ctx %p, md %p len %d\n", ctx, md, sha3_ctx->num); #ifndef QAT_OPENSSL_PROVIDER # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (sha3_ctx->num <= CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT && sha3_ctx->sw_offload) { DEBUG("Packet size < 2048, Using OpenSSL SW\n"); return EVP_MD_meth_get_final(GET_SW_SHA3_DIGEST(ctx)) (ctx, md); } # endif #endif /* If num is 0, and a request has offloaded the * packet type previous should be LAST_PARTIAL or FULL */ qat_hw_sha3_offload(ctx, sha3_ctx->data, sha3_ctx->num, CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL); /* Copy digest result into "md" buffer. */ memcpy(md, sha3_ctx->digest_data, sha3_ctx->md_size); memset(sha3_ctx->digest_data, 0x00, sha3_ctx->md_size); #ifndef QAT_OPENSSL_PROVIDER if (!qat_sha3_cleanup(ctx)) { WARN("qat_sha3_cleanup failed\n"); QATerr(QAT_F_QAT_SHA3_FINAL, ERR_R_INTERNAL_ERROR); return 0; } #endif return 1; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) use_sw_method: sts = EVP_MD_meth_get_final(GET_SW_SHA3_DIGEST(ctx)) (ctx, md); DEBUG("SW Finished %p\n", ctx); return sts; #endif } /****************************************************************************** * function: * qat_sha3_update(EVP_MD_CTX *ctx, const void *in, size_t len) * * @param ctx [IN] - pointer to existing context * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval len function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_sha3_update(QAT_KECCAK1600_CTX *ctx, const void *in, size_t len) #else static int qat_sha3_update(EVP_MD_CTX *ctx, const void *in, size_t len) #endif { const unsigned char *data = in; qat_sha3_ctx *sha3_ctx = NULL; unsigned char *p; size_t n; unsigned int data_size = 0; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int sts = 0; #endif #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(ctx == NULL)) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_SHA3_UPDATE, QAT_R_CTX_NULL); return -1; } #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (qat_openssl3_sha_fallback == 1) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } #endif DEBUG("QAT HW SHA3 Update ctx %p, in %p, len %ld\n", ctx, in, len); #ifdef QAT_OPENSSL_PROVIDER sha3_ctx = ctx->qctx; #else sha3_ctx = QAT_SHA3_GET_CTX(ctx); #endif if (sha3_ctx == NULL) { WARN("SHA3 context hash data is NULL.\n"); QATerr(QAT_F_QAT_SHA3_UPDATE, QAT_R_SHA3_CTX_NULL); return -1; } #ifdef QAT_OPENSSL_PROVIDER data_size = qat_get_sha3_data_size(ctx->md_type); #else data_size = qat_get_sha3_data_size(EVP_MD_CTX_type(ctx)); #endif n = sha3_ctx->num; #ifndef QAT_OPENSSL_PROVIDER # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (sha3_ctx->sw_offload || (len <= CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT)) { DEBUG("Packet size < 2048, Using OpenSSL SW\n"); sha3_ctx->sw_offload = 1; return EVP_MD_meth_get_update(GET_SW_SHA3_DIGEST(ctx)) (ctx, in, len); } # endif #endif /* Packets left from previous process */ if (n != 0) { p = (unsigned char *)sha3_ctx->data; /* Offload threshold met */ if (len >= data_size || len + n >= data_size) { /* Use part of new packet filling the packet buffer */ memcpy(p + n, data, data_size - n); qat_hw_sha3_offload(ctx, p, data_size, CPA_CY_SYM_PACKET_TYPE_PARTIAL); /* The data left of new input */ n = data_size - n; data += n; len -= n; sha3_ctx->num = 0; /* * We use memset rather than OPENSSL_cleanse() here deliberately. * Using OPENSSL_cleanse() here could be a performance issue. It * will get properly cleansed on finalisation so this isn't a * security problem. */ memset(p, 0, data_size); /* keep it zeroed */ } else { /* Append the new packets to buffer */ memcpy(p + n, data, len); sha3_ctx->num += (unsigned int)len; return 1; } } n = len / data_size; if (n > 0) { n *= data_size; qat_hw_sha3_offload(ctx, in, n, CPA_CY_SYM_PACKET_TYPE_PARTIAL); data += n; len -= n; } /* Save the bytes into buffer if there're some bytes left * after the previous update. */ if (len != 0) { p = (unsigned char *)sha3_ctx->data; sha3_ctx->num = (unsigned int)len; memcpy(p, data, len); } return 1; #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) use_sw_method: return EVP_MD_meth_get_update(GET_SW_SHA3_DIGEST(ctx)) (ctx, in, len); DEBUG("SW Finished %p\n", ctx); return sts; #endif } #endif qatengine-1.9.0/qat_hw_sha3.h000066400000000000000000000135471500416242000160520ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sha3.h * * This file provides a interface for SHA3 operations * *****************************************************************************/ #ifndef QAT_HW_SHA3_H # define QAT_HW_SHA3_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "cpa_cy_drbg.h" # define KECCAK1600_WIDTH 1600 # define SHA3_WORD unsigned int # define SHA3_CBLOCK 64 # define SHA3_LBLOCK (SHA3_CBLOCK/4) /* Digest Size */ # define QAT_SHA3_224_DIGEST_SIZE 28 # define QAT_SHA3_256_DIGEST_SIZE 32 # define QAT_SHA3_384_DIGEST_SIZE 48 # define QAT_SHA3_512_DIGEST_SIZE 64 /*Block Size */ # define QAT_SHA3_224_BLOCK_SIZE 144 # define QAT_SHA3_256_BLOCK_SIZE 136 # define QAT_SHA3_384_BLOCK_SIZE 104 # define QAT_SHA3_512_BLOCK_SIZE 72 /* State Size */ # define QAT_SHA3_224_STATE_SIZE 28 # define QAT_SHA3_256_STATE_SIZE 32 # define QAT_SHA3_384_STATE_SIZE 48 # define QAT_SHA3_512_STATE_SIZE 64 # define QAT_SHA3_224_OFFLOAD_THRESHOLD (100 * QAT_SHA3_224_BLOCK_SIZE) # define QAT_SHA3_256_OFFLOAD_THRESHOLD (120 * QAT_SHA3_256_BLOCK_SIZE) # define QAT_SHA3_384_OFFLOAD_THRESHOLD (160 * QAT_SHA3_384_BLOCK_SIZE) # define QAT_SHA3_512_OFFLOAD_THRESHOLD (200 * QAT_SHA3_512_BLOCK_SIZE) # define QAT_SHA3_OFFLOAD_THRESHOLD (160 * QAT_SHA3_384_BLOCK_SIZE) typedef struct SHA3state_st { SHA3_WORD A, B, C, D, E, F, G, H; SHA3_WORD Nl, Nh; SHA3_WORD data[SHA3_LBLOCK]; unsigned int num; } SHA3_CTX; typedef struct { #ifdef QAT_OPENSSL_PROVIDER uint64_t A[5][5]; #endif int inst_num; int context_params_set; /* True if init called */ int session_init; /* True if QAT_HW update called */ unsigned int qat_offloaded; /* True if there was an offload. */ unsigned char data[QAT_SHA3_OFFLOAD_THRESHOLD]; /* The buffer */ unsigned int num; /* The data left in buffer */ unsigned int sw_offload; /* Fallback Flag for small pkt offload */ CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx session_ctx; CpaCySymOpData *opd; CpaBufferList pSrcBufferList; /* For QAT metadata */ CpaFlatBuffer src_buffer; unsigned char digest_data[EVP_MAX_MD_SIZE]; int md_size; /* output length, variable in XOF */ int qat_svm; } qat_sha3_ctx; # ifdef QAT_OPENSSL_PROVIDER typedef struct qat_keccak_st QAT_KECCAK1600_CTX; typedef size_t (sha3_absorb_fn)(void *vctx, const void *inp, size_t len); typedef int (sha3_final_fn)(unsigned char *md, void *vctx); typedef struct prov_sha3_meth_st { sha3_absorb_fn *absorb; sha3_final_fn *final; } QAT_PROV_SHA3_METHOD; struct qat_keccak_st { uint64_t A[5][5]; size_t block_size; /* cached ctx->digest->block_size */ size_t md_size; /* output length, variable in XOF */ size_t bufsz; /* used bytes in below buffer */ unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; unsigned char pad; int md_type; qat_sha3_ctx *qctx; QAT_PROV_SHA3_METHOD meth; EVP_MD *sw_md; EVP_MD_CTX *sw_md_ctx; }; int qat_sha3_init(QAT_KECCAK1600_CTX *ctx); int qat_sha3_cleanup(QAT_KECCAK1600_CTX *ctx); int qat_sha3_final(QAT_KECCAK1600_CTX *ctx, unsigned char *md); int qat_sha3_update(QAT_KECCAK1600_CTX *ctx, const void *in, size_t len); int qat_sha3_copy(QAT_KECCAK1600_CTX *to, const QAT_KECCAK1600_CTX *from); # endif typedef struct { uint64_t A[5][5]; #if OPENSSL_VERSION_NUMBER >= 0x30300000 unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; #endif size_t block_size; /* SW cached ctx->digest->block_size */ size_t md_size; /* SW output length, variable in XOF */ size_t num; /* SW used bytes in below buffer */ #if OPENSSL_VERSION_NUMBER < 0x30300000 unsigned char buf[KECCAK1600_WIDTH / 8 - 32]; #endif unsigned char pad; } KECCAK1600_CTX; # define QAT_SHA3_GET_CTX(ctx) \ ((qat_sha3_ctx *) EVP_MD_CTX_md_data(ctx)) const EVP_MD *qat_create_sha3_meth(int nid, int key_type); #endif /* QAT_HW_SHA3_H */ qatengine-1.9.0/qat_hw_sm2.c000066400000000000000000001405071500416242000157050ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sm2.c * * This file provides SM2 implementaion for QAT_HW * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include "qat_hw_sm2.h" #if defined(ENABLE_QAT_HW_SM2) && !defined(QAT_HW_FBSD_INTREE) typedef struct { /* Key and paramgen group */ EC_GROUP *gen_group; /* message digest */ const EVP_MD *md; /* Distinguishing Identifier, ISO/IEC 15946-3 */ uint8_t *id; size_t id_len; /* id_set indicates if the 'id' field is set (1) or not (0) */ int id_set; } QAT_SM2_PKEY_CTX; # ifdef QAT_OPENSSL_3 typedef struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; OSSL_FUNC_signature_sign_fn *sign; OSSL_FUNC_signature_verify_init_fn *verify_init; OSSL_FUNC_signature_verify_fn *verify; OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; OSSL_FUNC_signature_verify_recover_fn *verify_recover; OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; OSSL_FUNC_signature_digest_sign_fn *digest_sign; OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; OSSL_FUNC_signature_digest_verify_fn *digest_verify; OSSL_FUNC_signature_freectx_fn *freectx; OSSL_FUNC_signature_dupctx_fn *dupctx; OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } QAT_EVP_SIGNATURE /* EVP_SIGNATURE for QAT Provider sm2 */ ; struct bignum_st { BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit * chunks. */ int top; /* Index of last used d +1. */ /* The next are internal book keeping for bn_expand. */ int dmax; /* Size of the d array. */ int neg; /* one if the number is negative */ int flags; }; static QAT_EVP_SIGNATURE get_def_signature_sm2() { static QAT_EVP_SIGNATURE s_signature; static int initilazed = 0; if (!initilazed) { QAT_EVP_SIGNATURE *signature = (QAT_EVP_SIGNATURE *) EVP_SIGNATURE_fetch(NULL, "SM2", "provider=default"); if (signature) { s_signature = *signature; EVP_SIGNATURE_free((QAT_EVP_SIGNATURE *) signature); initilazed = 1; } else { WARN("EVP_SIGNATURE_fetch from default provider failed"); } } return s_signature; } # endif /* Callback to indicate QAT completion of SM2 Sign */ static void qat_sm2SignCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean signStatus, CpaFlatBuffer *pR, CpaFlatBuffer *pS) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, 0, pOpData, NULL, signStatus); } /* Callback to indicate QAT completion of SM2 Verify */ static void qat_sm2VerifyCallbackFn(void *pCallbackTag, CpaStatus status, void *pOpData, CpaBoolean verifyStatus) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, 0, pOpData, NULL, verifyStatus); } int qat_hw_sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const EC_KEY *key) { int rc = 0; const EC_GROUP *group = EC_KEY_get0_group(key); BN_CTX *ctx = NULL; EVP_MD_CTX *hash = NULL; BIGNUM *p = NULL; BIGNUM *a = NULL; BIGNUM *b = NULL; BIGNUM *xG = NULL; BIGNUM *yG = NULL; BIGNUM *xA = NULL; BIGNUM *yA = NULL; int p_bytes = 0; uint8_t *buf = NULL; uint16_t entl = 0; uint8_t e_byte = 0; hash = EVP_MD_CTX_new(); ctx = BN_CTX_new(); if (hash == NULL || ctx == NULL) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_MALLOC_FAILURE); goto done; } p = BN_CTX_get(ctx); a = BN_CTX_get(ctx); b = BN_CTX_get(ctx); xG = BN_CTX_get(ctx); yG = BN_CTX_get(ctx); xA = BN_CTX_get(ctx); yA = BN_CTX_get(ctx); if (yA == NULL) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_MALLOC_FAILURE); goto done; } if (!EVP_DigestInit(hash, digest)) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); goto done; } /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */ if (id_len >= (UINT16_MAX / 8)) { /* too large */ QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_SM2_ID_TOO_LARGE); goto done; } entl = (uint16_t)(8 * id_len); e_byte = entl >> 8; if (!EVP_DigestUpdate(hash, &e_byte, 1)) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); goto done; } e_byte = entl & 0xFF; if (!EVP_DigestUpdate(hash, &e_byte, 1)) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); goto done; } if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); goto done; } if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_EC_LIB); goto done; } p_bytes = BN_num_bytes(p); buf = OPENSSL_zalloc(p_bytes); if (buf == NULL) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_MALLOC_FAILURE); goto done; } if (BN_bn2binpad(a, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || BN_bn2binpad(b, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EC_POINT_get_affine_coordinates(group, EC_GROUP_get0_generator(group), xG, yG, ctx) || BN_bn2binpad(xG, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || BN_bn2binpad(yG, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EC_POINT_get_affine_coordinates(group, EC_KEY_get0_public_key(key), xA, yA, ctx) || BN_bn2binpad(xA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || BN_bn2binpad(yA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EVP_DigestFinal(hash, out, NULL)) { QATerr(QAT_F_QAT_HW_SM2_COMPUTE_Z_DIGEST, QAT_R_INTERNAL_ERROR); goto done; } rc = 1; done: OPENSSL_free(buf); BN_CTX_free(ctx); EVP_MD_CTX_free(hash); return rc; } # ifndef QAT_OPENSSL_PROVIDER int qat_sm2_init(EVP_PKEY_CTX *ctx) { QAT_SM2_PKEY_CTX *smctx = NULL; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return 0; } if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) { WARN("smctx alloc Failure\n"); QATerr(QAT_F_QAT_SM2_INIT, QAT_R_MALLOC_FAILURE); return 0; } EVP_PKEY_CTX_set_data(ctx, smctx); return 1; } void qat_sm2_cleanup(EVP_PKEY_CTX *ctx) { QAT_SM2_PKEY_CTX *smctx = NULL; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return; } smctx = (QAT_SM2_PKEY_CTX *) EVP_PKEY_CTX_get_data(ctx); if (smctx == NULL) { WARN("smctx is NULL\n"); return; } EC_GROUP_free(smctx->gen_group); OPENSSL_free(smctx->id); OPENSSL_free(smctx); } # ifdef QAT_OPENSSL_3 int qat_sm2_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) # else int qat_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) # endif { QAT_SM2_PKEY_CTX *smdctx, *smsctx; if (unlikely(src == NULL)) { WARN("src (type EVP_PKEY_CTX) is NULL \n"); return 0; } if (unlikely(dst == NULL)) { WARN("dst (type EVP_PKEY_CTX) is NULL \n"); return 0; } if (!qat_sm2_init(dst)) return 0; smsctx = EVP_PKEY_CTX_get_data(src); smdctx = EVP_PKEY_CTX_get_data(dst); if (smsctx->gen_group != NULL) { smdctx->gen_group = EC_GROUP_dup(smsctx->gen_group); if (smdctx->gen_group == NULL) { qat_sm2_cleanup(dst); return 0; } } if (smsctx->id != NULL) { smdctx->id = OPENSSL_malloc(smsctx->id_len); if (smdctx->id == NULL) { QATerr(QAT_F_QAT_SM2_COPY, QAT_R_MALLOC_FAILURE); qat_sm2_cleanup(dst); return 0; } memcpy(smdctx->id, smsctx->id, smsctx->id_len); } smdctx->id_len = smsctx->id_len; smdctx->id_set = smsctx->id_set; smdctx->md = smsctx->md; return 1; } int qat_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *) EVP_PKEY_CTX_get_data(ctx); EC_GROUP *group; uint8_t *tmp_id; if (unlikely(smctx == NULL)) { WARN("smctx cannot be NULL\n"); QATerr(QAT_F_QAT_SM2_CTRL, QAT_R_CTX_NULL); return 0; } switch (type) { case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { WARN("Invalid curve\n"); QATerr(QAT_F_QAT_SM2_CTRL, QAT_R_INVALID_CURVE); return 0; } EC_GROUP_free(smctx->gen_group); smctx->gen_group = group; return 1; case EVP_PKEY_CTRL_EC_PARAM_ENC: if (smctx->gen_group == NULL) { WARN("gen group NULL\n"); QATerr(QAT_F_QAT_SM2_CTRL, QAT_R_NO_PARAMETERS_SET); return 0; } EC_GROUP_set_asn1_flag(smctx->gen_group, p1); return 1; case EVP_PKEY_CTRL_MD: smctx->md = p2; return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = smctx->md; return 1; case EVP_PKEY_CTRL_SET1_ID: if (p1 > 0) { tmp_id = OPENSSL_malloc(p1); if (tmp_id == NULL) { WARN("Malloc Failure\n"); QATerr(QAT_F_QAT_SM2_CTRL, QAT_R_MALLOC_FAILURE); return 0; } memcpy(tmp_id, p2, p1); OPENSSL_free(smctx->id); smctx->id = tmp_id; } else { /* set null-ID */ OPENSSL_free(smctx->id); smctx->id = NULL; } smctx->id_len = (size_t)p1; smctx->id_set = 1; return 1; case EVP_PKEY_CTRL_GET1_ID: memcpy(p2, smctx->id, smctx->id_len); return 1; case EVP_PKEY_CTRL_GET1_ID_LEN: *(size_t *)p2 = smctx->id_len; return 1; /* Default behaviour is OK */ case EVP_PKEY_CTRL_PEER_KEY: case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_CMS_SIGN: case EVP_PKEY_CTRL_DIGESTINIT: /* nothing to be inited, this is to suppress the error... */ return 1; default: return -2; } } # ifdef QAT_OPENSSL_3 static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, const EC_KEY *key, const uint8_t *id, const size_t id_len, const uint8_t *msg, size_t msg_len) { EVP_MD_CTX *hash = EVP_MD_CTX_new(); const int md_size = EVP_MD_size(digest); uint8_t *z = NULL; BIGNUM *e = NULL; if (md_size < 0) { QATerr(QAT_F_SM2_COMPUTE_MSG_HASH, QAT_R_SM2_INVALID_DIGEST); goto done; } z = OPENSSL_zalloc(md_size); if (hash == NULL || z == NULL) { QATerr(QAT_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE); goto done; } if (!qat_hw_sm2_compute_z_digest(z, digest, id, id_len, key)) { /* SM2err already called */ goto done; } if (!EVP_DigestInit(hash, digest) || !EVP_DigestUpdate(hash, z, md_size) || !EVP_DigestUpdate(hash, msg, msg_len) /* reuse z buffer to hold H(Z || M) */ || !EVP_DigestFinal(hash, z, NULL)) { QATerr(QAT_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB); goto done; } e = BN_bin2bn(z, md_size, NULL); if (e == NULL) QATerr(QAT_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR); done: OPENSSL_free(z); EVP_MD_CTX_free(hash); return e; } # endif int qat_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { uint8_t z[EVP_MAX_MD_SIZE]; QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *) EVP_PKEY_CTX_get_data(ctx); EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); const EVP_MD *md = EVP_MD_CTX_md(mctx); int mdlen = EVP_MD_size(md); if (!smctx->id_set) { /* * Actually, there is no standard doc which illustrate how to set sm2-id * correctly, only GM/T 0009-2012 gives a fuzzy definition that sm2-id * would be "1234567812345678", and there is no way to get sm2-id from * certificate. In tls handshake, client/server would get a long * certificate chain from peer, we can't find any effective way to * recognize or set sm2-id for each cert, so we choose to set a default * sm2 id for each sm2 sign process. */ smctx->id_set = 1; smctx->id = (uint8_t *)OPENSSL_memdup(SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN); smctx->id_len = SM2_DEFAULT_USERID_LEN; } if (mdlen < 0) { QATerr(QAT_F_QAT_SM2_DIGEST_CUSTOM, QAT_R_SM2_INVALID_DIGEST); return 0; } /* get hashed prefix 'z' of tbs message */ if (!qat_hw_sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, eckey)) return 0; return EVP_DigestUpdate(mctx, z, (size_t)mdlen); } # endif # ifdef QAT_OPENSSL_PROVIDER int qat_sm2_sign(QAT_PROV_SM2_CTX *smctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) # else int qat_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) # endif { int ret = 0, i, sigleni, job_ret = 0, fallback = 0; ECDSA_SIG *s = NULL; size_t buflen = 0; const EC_GROUP *group; const BIGNUM *priv_key, *order; const EC_POINT *pub_key = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; CpaFlatBuffer *pResultR = NULL; CpaFlatBuffer *pResultS = NULL; int inst_num = QAT_INVALID_INSTANCE; BIGNUM *k = NULL, *e = NULL; CpaCyEcsm2SignOpData *opData = NULL; CpaStatus status = CPA_STATUS_FAIL; CpaBoolean bSM2SignStatus = 0; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); thread_local_variables_t *tlv = NULL; BN_CTX *bctx = NULL; int qat_svm = QAT_INSTANCE_ANY; # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int sig_sz; unsigned char *dgst = NULL; BIGNUM *bg = NULL; EVP_MD *md = NULL; int dlen = 0; QAT_PROV_SM2_CTX *sw_ctx; # endif # if defined(QAT_OPENSSL_3) || defined(QAT_OPENSSL_PROVIDER) QAT_EVP_SIGNATURE sw_sm2_signature; # else int (*psign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) = NULL; # endif # ifdef QAT_OPENSSL_PROVIDER const EC_KEY *eckey = smctx->ec; # else EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); # endif DEBUG("Entering \n"); if (unlikely(eckey == NULL) || unlikely(siglen == NULL)) { WARN("Invalid Input params\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_INPUT_PARAM_INVALID); return ret; } # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) sig_sz = ECDSA_size(eckey); if (sig_sz <= 0) return ret; /* To know how much memory is needed to store the sig */ if (sig == NULL) { *siglen = (size_t)sig_sz; return 1; } if (*siglen < (size_t)sig_sz) { WARN("Invalid Input param\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_INPUT_PARAM_INVALID); return ret; } # endif group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); pub_key = EC_KEY_get0_public_key(eckey); order = EC_GROUP_get0_order(group); if (group == NULL || priv_key == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return ret; } # ifndef QAT_OPENSSL_PROVIDER QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *) EVP_PKEY_CTX_get_data(ctx); if (!smctx->id_set) { smctx->id_set = 1; smctx->id = (uint8_t *)OPENSSL_memdup(SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN); smctx->id_len = SM2_DEFAULT_USERID_LEN; } # endif DEBUG("QAT HW SM2 Sign Started \n"); if ((bctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(bctx); k = BN_CTX_get(bctx); e = BN_CTX_get(bctx); if (e == NULL) { WARN("Failure to allocate k, e or order\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_K_E_ORDER_MALLOC_FAILURE); goto err; } i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * tbslen > i) tbslen = (i + 7) / 8; if (!BN_bin2bn(tbs, tbslen, e)) { WARN("Failure to convert dgst to e\n"); QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * tbslen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) { WARN("Failure to truncate e\n"); QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_BN_LIB); goto err; } do if (!BN_rand_range(k, order)) { WARN("Failure to get random number k\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_K_RAND_GENERATE_FAILURE); goto err; } while (BN_is_zero(k)) ; /* SM2 BabaSSL implementaion uses ECDSA hence following * the same */ if ((s = ECDSA_SIG_new()) == NULL) { WARN("Failure to allocate SM2_SIG\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_SM2_SIG_MALLOC_FAILURE); goto err; } sig_r = BN_new(); sig_s = BN_new(); if (ECDSA_SIG_set0(s, sig_r, sig_s) == 0) { WARN("Failure to allocate r and s values to assign to the ECDSA_SIG\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_SM2_SIG_SET_R_S_FAILURE); goto err; } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (qat_get_sw_fallback_enabled()) { WARN("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; goto err; } else { QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); goto err; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; opData = (CpaCyEcsm2SignOpData *) OPENSSL_zalloc(sizeof(CpaCyEcsm2SignOpData)); if (opData == NULL) { WARN("Failed to allocate memory for opData\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_OPDATA_MALLOC_FAILURE); goto err; } /* may be made dynamic */ buflen = QAT_GFP_SM2_SIZE_IN_BITS; /* Only this field type for the operation is supported */ opData->fieldType = CPA_CY_EC_FIELD_TYPE_PRIME; /* * k - scalar multiplier (k > 0 and k < n) * e - digest of the message * d - private key (d > 0 and d < n) */ # ifdef QAT_OPENSSL_PROVIDER if ((qat_BN_to_FB_for_sm2(&(opData->k), k, qat_svm) != 1) || (qat_BN_to_FB(&(opData->e), e, qat_svm) != 1) || (qat_BN_to_FB(&(opData->d), (BIGNUM *)priv_key, qat_svm) != 1)) { WARN("Failure to convert e, tbs and priv_key to flatbuffer\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE); goto err; } # else if ((qat_BN_to_FB(&(opData->k), k, qat_svm) != 1) || (qat_BN_to_FB(&(opData->e), e, qat_svm) != 1) || (qat_BN_to_FB(&(opData->d), (BIGNUM *)priv_key, qat_svm) != 1)) { WARN("Failure to convert e, tbs and priv_key to flatbuffer\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_PRIV_KEY_K_E_D_CONVERT_TO_FB_FAILURE); goto err; } # endif pResultR = (CpaFlatBuffer *) OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (!pResultR) { WARN("Failed to allocate memory for pResultR\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_PRESULTR_MALLOC_FAILURE); goto err; } pResultR->pData = (Cpa8U *) qat_mem_alloc(buflen, qat_svm, __FILE__, __LINE__); if (!pResultR->pData) { WARN("Failed to allocate memory for pResultR data\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_PRESULTR_PDATA_MALLOC_FAILURE); goto err; } pResultR->dataLenInBytes = (Cpa32U) buflen; pResultS = (CpaFlatBuffer *) OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (!pResultS) { WARN("Failed to allocate memory for pResultS\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_PRESULTS_MALLOC_FAILURE); goto err; } pResultS->pData = (Cpa8U *) qat_mem_alloc(buflen, qat_svm, __FILE__, __LINE__); if (!pResultS->pData) { WARN("Failed to allocate memory for pResultS data\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_PRESULTS_PDATA_MALLOC_FAILURE); goto err; } pResultS->dataLenInBytes = (Cpa32U) buflen; tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("KX - %s\n", __func__); do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG ("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } CRYPTO_QAT_LOG("AU - %s\n", __func__); DUMP_SM2_SIGN(qat_instance_handles[inst_num], opData, pResultR, pResultS); status = cpaCyEcsm2Sign(qat_instance_handles[inst_num], qat_sm2SignCallbackFn, &op_done, opData, &bSM2SignStatus, pResultR, pResultS); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG ("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info. physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num]. qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DUMP_SM2_SIGN_OUTPUT(bSM2SignStatus, pResultR, pResultS); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG ("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info. physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } qat_cleanup_op_done(&op_done); /* Convert the flatbuffer results back to a BN */ BN_bin2bn(pResultR->pData, pResultR->dataLenInBytes, sig_r); BN_bin2bn(pResultS->pData, pResultS->dataLenInBytes, sig_s); sigleni = i2d_ECDSA_SIG(s, &sig); if (sigleni < 0) { QATerr(QAT_F_QAT_SM2_SIGN, ERR_R_INTERNAL_ERROR); goto err; } *siglen = (unsigned int)sigleni; ret = 1; DEBUG("Sign operation successful\n"); err: if (!ret) { if (s != NULL) { ECDSA_SIG_free(s); s = NULL; } if (siglen != NULL) *siglen = 0; } if (pResultR) { QAT_MEM_FREE_FLATBUFF(*pResultR, qat_svm); OPENSSL_free(pResultR); } if (pResultS) { QAT_MEM_FREE_FLATBUFF(*pResultS, qat_svm); OPENSSL_free(pResultS); } if (opData) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->k, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->d, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->e, qat_svm); OPENSSL_free(opData); } if (bctx) { BN_CTX_end(bctx); BN_CTX_free(bctx); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); # ifdef QAT_OPENSSL_PROVIDER /* When using OpenSSL 3 provider API */ sw_sm2_signature = get_def_signature_sm2(); if (sw_sm2_signature.digest_sign) { return sw_sm2_signature.digest_sign((void *)smctx, sig, siglen, sigsize, tbs, tbslen); } else { if (sw_sm2_signature.digest_sign_update == NULL || sw_sm2_signature.digest_sign_final == NULL) { WARN("SM2 digest_sign_update is NULL or digest_sign_final is NULL\n"); QATerr(QAT_F_QAT_SM2_SIGN, QAT_R_SM2_SIGN_NULL); return 0; } if (sw_sm2_signature. digest_sign_update((void *)smctx, tbs, tbslen) <= 0) { return 0; } return sw_sm2_signature.digest_sign_final((void *)smctx, sig, siglen, sigsize); } # else # ifdef QAT_OPENSSL_3 /* When using OpenSSL 3 legacy engine API */ sw_ctx = OPENSSL_malloc(sizeof(QAT_PROV_SM2_CTX)); sw_ctx->mdsize = 0; sw_ctx->ec = (EC_KEY *)eckey; md = (EVP_MD *)EVP_sm3(); bg = sm2_compute_msg_hash(md, eckey, smctx->id, smctx->id_len, tbs, tbslen); dgst = OPENSSL_zalloc(SM3_DIGEST_LENGTH); dlen = BN_bn2bin(bg, dgst); sw_sm2_signature = get_def_signature_sm2(); if (sw_sm2_signature.sign) { ret = sw_sm2_signature.sign(sw_ctx, sig, siglen, sig_sz, dgst, dlen); } else { WARN("Failed to obtain sm2 sign func from default provider.\n"); ret = 0; } OPENSSL_free(dgst); BN_free(bg); OPENSSL_free(sw_ctx); return ret; # else /* When using OpenSSL 1.1.1 */ EVP_PKEY_meth_get_sign((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &psign); ret = (*psign) (ctx, sig, siglen, tbs, tbslen); DEBUG("SW Finished, ret: %d\n", ret); return ret; # endif # endif } ECDSA_SIG_free(s); DEBUG("- FinishedP: %d\n", ret); return ret; } # ifdef QAT_OPENSSL_PROVIDER int qat_sm2_verify(QAT_PROV_SM2_CTX *smctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) # else int qat_sm2_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) # endif { int ret = 0, i, job_ret = 0, fallback = 0; ECDSA_SIG *s = NULL; const EC_GROUP *group; BN_CTX *bctx = NULL; const BIGNUM *priv_key, *order; const EC_POINT *pub_key = NULL; const BIGNUM *sig_r = NULL, *sig_s = NULL; int inst_num = QAT_INVALID_INSTANCE; BIGNUM *xp = NULL, *yp = NULL; CpaCyEcsm2VerifyOpData *opData = NULL; CpaStatus status = CPA_STATUS_FAIL; CpaBoolean bSM2VerifyStatus = 0; op_done_t op_done; int qatPerformOpRetries = 0; useconds_t ulPollInterval = getQatPollInterval(); int iMsgRetry = getQatMsgRetryCount(); thread_local_variables_t *tlv = NULL; unsigned char *dgst = NULL; const unsigned char *p = sig; BIGNUM *e = NULL; int dlen = 0; int qat_svm = QAT_INSTANCE_ANY; # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) unsigned char *msdgst = NULL; BIGNUM *bg = NULL; EVP_MD *md = NULL; int mdlen = 0; QAT_PROV_SM2_CTX *sw_ctx; # endif # if defined(QAT_OPENSSL_3) || defined(QAT_OPENSSL_PROVIDER) QAT_EVP_SIGNATURE sw_sm2_signature; # else int (*pverify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) = NULL; # endif # ifdef QAT_OPENSSL_PROVIDER const EC_KEY *eckey = smctx->ec; # else EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); # endif DEBUG("Entering \n"); if (unlikely(eckey == NULL) || unlikely(siglen == 0) || unlikely(tbs == NULL) || unlikely(tbslen == 0)) { WARN("Invalid Input params\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_INPUT_PARAM_INVALID); return ret; } group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || priv_key == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return ret; } # ifndef QAT_OPENSSL_PROVIDER QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *) EVP_PKEY_CTX_get_data(ctx); if (!smctx->id_set) { smctx->id_set = 1; smctx->id = (uint8_t *)OPENSSL_memdup(SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN); smctx->id_len = SM2_DEFAULT_USERID_LEN; } # endif DEBUG("QAT HW SM2 Verify Started \n"); if ((s = ECDSA_SIG_new()) == NULL) { WARN("Failure to allocate ECDSA_SIG_SM2\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_SM2_SIG_MALLOC_FAILURE); return ret; } if (d2i_ECDSA_SIG(&s, &p, siglen) == NULL) { WARN("Failure to get ECDSA_SIG_SM2\n"); return ret; } dlen = i2d_ECDSA_SIG(s, &dgst); if (dlen != siglen || memcmp(sig, dgst, dlen) != 0) { WARN("Invalid Encoding dlen =%d \nsig = %s \ndgst = %s\n", dlen, sig, dgst); return ret; } if ((bctx = BN_CTX_new()) == NULL) { WARN("Failure to allocate ctx\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(bctx); e = BN_CTX_get(bctx); xp = BN_CTX_get(bctx); yp = BN_CTX_get(bctx); if (xp == NULL || yp == NULL || e == NULL) { WARN("Failed to allocate xp or yp or e\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_X_Y_E_MALLOC_FAILURE); goto err; } if ((order = EC_GROUP_get0_order(group)) == NULL) { WARN("Failure to get order from group\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_GET_ORDER_FAILURE); } ECDSA_SIG_get0(s, &sig_r, &sig_s); if (BN_is_zero(sig_r) || BN_is_negative(sig_r) || BN_ucmp(sig_r, order) >= 0 || BN_is_zero(sig_s) || BN_is_negative(sig_s) || BN_ucmp(sig_s, order) >= 0) { WARN("ECDSA_SIG sig is invalid\n"); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); ret = 0; goto err; } i = BN_num_bits(order); /* * Need to truncate digest if it is too long: first truncate whole bytes. */ if (8 * tbslen > i) tbslen = (i + 7) / 8; if (!BN_bin2bn(tbs, tbslen, e)) { WARN("Failure to convert dgst to e\n"); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_BN_LIB); goto err; } /* If still too long truncate remaining bits with a shift */ if ((8 * tbslen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) { WARN("Failure to truncate e\n"); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_BN_LIB); goto err; } if ((inst_num = get_instance(QAT_INSTANCE_ASYM, QAT_INSTANCE_ANY)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG ("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); return 0; } } qat_svm = !qat_instance_details[inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; opData = (CpaCyEcsm2VerifyOpData *) OPENSSL_zalloc(sizeof(CpaCyEcsm2VerifyOpData)); if (opData == NULL) { WARN("Failed to allocate memory for opData\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_OPDATA_MALLOC_FAILURE); goto err; } opData->fieldType = CPA_CY_EC_FIELD_TYPE_PRIME; if (!EC_POINT_get_affine_coordinates(group, pub_key, xp, yp, bctx)) { WARN("Failure to get the affine coordinates\n"); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } if ((qat_BN_to_FB(&(opData->r), (BIGNUM *)sig_r, qat_svm) != 1) || (qat_BN_to_FB(&(opData->s), (BIGNUM *)sig_s, qat_svm) != 1) || (qat_BN_to_FB(&(opData->e), e, qat_svm) != 1) || (qat_BN_to_FB(&(opData->xP), xp, qat_svm) != 1) || (qat_BN_to_FB(&(opData->yP), yp, qat_svm) != 1)) { WARN("Failed to convert sig_r, sig_s, xp or yp to a flatbuffer\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_CURVE_COORDINATE_PARAMS_CONVERT_TO_FB_FAILURE); goto err; } tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } CRYPTO_QAT_LOG("KX - %s\n", __func__); do { if (status == CPA_STATUS_RETRY && (inst_num = get_instance(QAT_INSTANCE_ASYM, qat_svm)) == QAT_INVALID_INSTANCE) { WARN("Failure to get another instance\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG ("Failed to get an instance - fallback to SW - %s\n", __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } CRYPTO_QAT_LOG("AU - %s\n", __func__); DUMP_SM2_VERIFY(qat_instance_handles[inst_num], opData); status = cpaCyEcsm2Verify(qat_instance_handles[inst_num], qat_sm2VerifyCallbackFn, &op_done, opData, &bSM2VerifyStatus); if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + (qatPerformOpRetries % QAT_RETRY_BACKOFF_MODULO_DIVISOR)); qatPerformOpRetries++; if (iMsgRetry != QAT_INFINITE_MAX_NUM_RETRIES) { if (qatPerformOpRetries >= iMsgRetry) { WARN("No. of retries exceeded max retry : %d\n", iMsgRetry); break; } } } else { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || (qat_pause_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0)) { WARN("qat_wake_job or qat_pause_job failed\n"); break; } } } } while (status == CPA_STATUS_RETRY); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to submit request to qat - status = %d\n", status); if (qat_get_sw_fallback_enabled() && (status == CPA_STATUS_RESTARTING || status == CPA_STATUS_FAIL)) { CRYPTO_QAT_LOG ("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info. physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); goto err; } } } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, qat_instance_details[inst_num]. qat_instance_info.physInstId.packageId, __func__); } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_requests_in_flight); } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Verify Status %d\n", bSM2VerifyStatus); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); if (qat_get_sw_fallback_enabled() && op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG ("Verification of result failed for qat inst_num %d device_id %d - fallback to SW - %s\n", inst_num, qat_instance_details[inst_num].qat_instance_info. physInstId.packageId, __func__); fallback = 1; } else { QATerr(QAT_F_QAT_SM2_VERIFY, ERR_R_INTERNAL_ERROR); } qat_cleanup_op_done(&op_done); goto err; } else DEBUG("Verification Status Success\n"); qat_cleanup_op_done(&op_done); ret = 1; err: if (!ret) { ECDSA_SIG_free(s); s = NULL; siglen = 0; } if (opData) { QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->r, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->s, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->e, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->xP, qat_svm); QAT_CLEANSE_MEMFREE_NONZERO_FLATBUFF(opData->yP, qat_svm); OPENSSL_free(opData); } if (bctx) { BN_CTX_end(bctx); BN_CTX_free(bctx); } if (fallback) { WARN("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); # ifdef QAT_OPENSSL_PROVIDER /* When using OpenSSL 3 provider API */ sw_sm2_signature = get_def_signature_sm2(); if (sw_sm2_signature.digest_verify) { return sw_sm2_signature.digest_verify((void *)smctx, sig, siglen, tbs, tbslen); } else { if (sw_sm2_signature.digest_verify_update == NULL || sw_sm2_signature.digest_verify_final == NULL) { WARN("ECDSA digest_verify_update is NULL or digest_verify_final is NULL\n"); QATerr(QAT_F_QAT_SM2_VERIFY, QAT_R_SM2_VERIFY_NULL); return -1; } if (sw_sm2_signature. digest_verify_update((void *)smctx, tbs, tbslen) <= 0) { return -1; } return sw_sm2_signature.digest_verify_final((void *)smctx, sig, siglen); } # else # ifdef QAT_OPENSSL_3 /* When using OpenSSL 3 legacy engine API */ sw_ctx = OPENSSL_malloc(sizeof(QAT_PROV_SM2_CTX)); sw_ctx->mdsize = 0; sw_ctx->ec = (EC_KEY *)eckey; md = (EVP_MD *)EVP_sm3(); bg = sm2_compute_msg_hash(md, eckey, smctx->id, smctx->id_len, tbs, tbslen); msdgst = OPENSSL_zalloc(SM3_DIGEST_LENGTH); mdlen = BN_bn2bin(bg, msdgst); sw_sm2_signature = get_def_signature_sm2(); if (sw_sm2_signature.verify) { ret = sw_sm2_signature.verify(sw_ctx, sig, siglen, msdgst, mdlen); } else { WARN("Failed to obtain sm2 verify func from default provider.\n"); ret = 0; } OPENSSL_free(msdgst); BN_free(bg); OPENSSL_free(sw_ctx); return ret; # else /* When using OpenSSL 1.1.1 */ EVP_PKEY_meth_get_verify((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &pverify); ret = (*pverify) (ctx, sig, siglen, tbs, tbslen); DEBUG("SW Finished, ret: %d\n", ret); return ret; # endif # endif } ECDSA_SIG_free(s); OPENSSL_free(dgst); DEBUG("- Finished\n"); return ret; } #endif qatengine-1.9.0/qat_hw_sm2.h000066400000000000000000000121261500416242000157050ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sm2.h * * This file provides HW driver support interface for SM2 ECDSA * *****************************************************************************/ #ifndef QAT_HW_SM2_H # define QAT_HW_SM2_H # include # include # include # include # include # include # include # include # include /* Local includes */ # include "e_qat.h" # include "qat_utils.h" # include "qat_events.h" # include "qat_fork.h" # include "qat_evp.h" # include "qat_hw_callback.h" # include "qat_hw_polling.h" # include "qat_hw_asym_common.h" # if defined(QAT_OPENSSL_3)|| defined(QAT_OPENSSL_PROVIDER) # include "qat_prov_sign_sm2.h" # endif # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_ec.h" # if defined(ENABLE_QAT_HW_SM2) && !defined( __FreeBSD__) # include "cpa_cy_ecsm2.h" # endif # include "cpa_dev.h" /* The default user id as specified in GM/T 0009-2012 */ # define SM2_DEFAULT_USERID "1234567812345678" # define SM2_DEFAULT_USERID_LEN sizeof(SM2_DEFAULT_USERID) - 1 # define SM3_DIGEST_LENGTH 32 # define QAT_GFP_SM2_SIZE_IN_BITS 32 # ifdef ENABLE_QAT_HW_SM2 # ifdef QAT_OPENSSL_PROVIDER int qat_hw_sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const EC_KEY *key); int qat_sm2_sign(QAT_PROV_SM2_CTX * ctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen); int qat_sm2_verify(QAT_PROV_SM2_CTX * ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); # else /* * SM2 signature operation. Computes Z and then signs H(Z || msg) using SM2 */ ECDSA_SIG *qat_sm2_do_sign(const EC_KEY *key, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const uint8_t *msg, size_t msg_len); int qat_sm2_do_verify(const EC_KEY *key, const EVP_MD *digest, const ECDSA_SIG *signature, const uint8_t *id, const size_t id_len, const uint8_t *msg, size_t msg_len); /* * SM2 signature generation. */ int qat_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); /* * SM2 signature verification. */ int qat_sm2_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); # endif # ifndef QAT_OPENSSL_PROVIDER int qat_sm2_init(EVP_PKEY_CTX *ctx); # ifdef QAT_OPENSSL_3 int qat_sm2_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src); # else int qat_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); # endif int qat_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); void qat_sm2_cleanup(EVP_PKEY_CTX *ctx); int qat_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); # endif # endif /* ENABLE_QAT_HW_SM2 */ #endif /* QAT_HW_SM2_H */ qatengine-1.9.0/qat_hw_sm3.c000066400000000000000000001006511500416242000157020ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sm3.c * * This file contains the engine implementations for SM3 Hash operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include "e_qat.h" #include "qat_utils.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_evp.h" #include "cpa.h" #include "cpa_types.h" #include "cpa_cy_sym.h" #include "qat_hw_sm3.h" #include "qat_hw_ciphers.h" #include #include #include #include #include #ifdef ENABLE_QAT_HW_SM3 static inline QAT_SM3_CTX *qat_hw_sm3_get_ctx(EVP_MD_CTX *ctx) { if (unlikely(ctx == NULL)) { WARN("hw sm3 ctx %p is NULL\n", ctx); return NULL; } return ((QAT_SM3_CTX *) (EVP_MD_CTX_md_data(ctx) + sizeof(SM3_CTX))); } /****************************************************************************** * function: * * static void qat_hw_sm3_cb(void *pCallbackTag, CpaStatus status, * const CpaCySymOp operationType, * void *pOpData, CpaBufferList *pDstBuffer, * CpaBoolean verifyResult) * * @param pCallbackTag [IN] - Opaque value provided by user while making * individual function call. Cast to op_done_pipe_t. * @param status [IN] - Status of the operation. * @param operationType [IN] - Identifies the operation type requested. * @param pOpData [IN] - Pointer to structure with input parameters. * @param pDstBuffer [IN] - Destination buffer to hold the data output. * @param verifyResult [IN] - Used to verify digest result. * * description: Callback to indicate the completion of crypto operation ******************************************************************************/ static void qat_hw_sm3_cb(void *pCallbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList *pDstBuffer, CpaBoolean verifyResult) { if (enable_heuristic_polling) QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_HASH, pOpData, NULL, CPA_TRUE); } /****************************************************************************** * function: * qat_hw_sm3_setup_param(EVP_MD_CTX *ctx) * * @param ctx [IN] - pointer to context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function synchronises the initialisation of the QAT session and * pre-allocates the necessary buffers for the session. ******************************************************************************/ static int qat_hw_sm3_setup_param(QAT_SM3_CTX *qat_sm3_ctx) { int numBuffers = 2; Cpa32U bufferMetaSize = 0; Cpa32U sctx_size = 0; CpaStatus status; CpaCySymSessionSetupData *session_data; session_data = OPENSSL_zalloc(sizeof(CpaCySymSessionSetupData) + sizeof(CpaCySymOpData) + sizeof(int)); if (NULL == session_data) { WARN("session setup data Malloc failure\n"); QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, ERR_R_MALLOC_FAILURE); return 0; } qat_sm3_ctx->session_data = session_data; qat_sm3_ctx->pOpData = (void *)session_data + sizeof(CpaCySymSessionSetupData); qat_sm3_ctx->rc_refs = (void *)session_data + sizeof(CpaCySymSessionSetupData) + sizeof(CpaCySymOpData); session_data->sessionPriority = CPA_CY_PRIORITY_HIGH; /* Hash only operation on the data */ session_data->symOperation = CPA_CY_SYM_OP_HASH; /* Place the digest result in a buffer unrelated to srcBuffer */ session_data->digestIsAppended = CPA_FALSE; /* Set FALSE to generate a message digest, instead of doing digest verify */ session_data->verifyDigest = CPA_FALSE; /* Set the hash mode and the length of the digest */ session_data->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SM3; session_data->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN; session_data->hashSetupData.digestResultLenInBytes = QAT_SM3_DIGEST_SIZE; session_data->hashSetupData.authModeSetupData.authKey = NULL; session_data->hashSetupData.nestedModeSetupData.pInnerPrefixData = NULL; session_data->hashSetupData.nestedModeSetupData.pOuterPrefixData = NULL; DUMP_SESSION_SETUP_DATA(qat_sm3_ctx->session_data); /* Allocate instance */ qat_sm3_ctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (qat_sm3_ctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, QAT_R_GET_INSTANCE_FAILURE); goto err; } qat_sm3_ctx->qat_svm = !qat_instance_details[qat_sm3_ctx->inst_num].qat_instance_info.requiresPhysicallyContiguousMemory; DEBUG("inst_num = %d inst mem type = %d \n", qat_sm3_ctx->inst_num, qat_sm3_ctx->qat_svm); /* Determine size of session context to allocate */ status = cpaCySymSessionCtxGetSize(qat_instance_handles[qat_sm3_ctx->inst_num], qat_sm3_ctx->session_data, &sctx_size); if (status != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); goto err; } DEBUG("Size of session ctx = %d\n", sctx_size); qat_sm3_ctx->session_ctx = (CpaCySymSessionCtx) qat_mem_alloc(sctx_size, qat_sm3_ctx->qat_svm,__FILE__, __LINE__); if (qat_sm3_ctx->session_ctx == NULL) { WARN("Memory alloc failed for session ctx\n"); QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, ERR_R_MALLOC_FAILURE); goto err; } /* Initialise Session data */ status = cpaCySymInitSession(qat_instance_handles[qat_sm3_ctx->inst_num], qat_hw_sm3_cb, qat_sm3_ctx->session_data, qat_sm3_ctx->session_ctx); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCySymInitSession failed! Status = %d\n", status); if (((status == CPA_STATUS_RESTARTING) || (status == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG ("Failed to submit request to qat inst_num %d device_id %d\n", qat_sm3_ctx->inst_num, qat_instance_details[qat_sm3_ctx->inst_num].qat_instance_info. physInstId.packageId); } QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); goto err; } /* Get buffer metasize */ status = cpaCyBufferListGetMetaSize(qat_instance_handles[qat_sm3_ctx->inst_num], numBuffers, &bufferMetaSize); if (status != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetMetaSize failed for the instance id %d\n", qat_sm3_ctx->inst_num); QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, ERR_R_INTERNAL_ERROR); goto err; } DEBUG("Buffer MetaSize : %d\n", bufferMetaSize); if (bufferMetaSize) { qat_sm3_ctx->pSrcBufferList.pPrivateMetaData = qat_mem_alloc(bufferMetaSize, qat_sm3_ctx->qat_svm, __FILE__, __LINE__); if (qat_sm3_ctx->pSrcBufferList.pPrivateMetaData == NULL) { WARN("QMEM alloc failed for PrivateData\n"); QATerr(QAT_F_QAT_HW_SM3_SETUP_PARAM, ERR_R_MALLOC_FAILURE); goto err; } qat_sm3_ctx->pSrcBufferList.numBuffers = 1; } else { qat_sm3_ctx->pSrcBufferList.pPrivateMetaData = NULL; qat_sm3_ctx->pSrcBufferList.numBuffers = 0; } qat_sm3_ctx->context_params_set = 1; return 1; err: QAT_MEM_FREE_NONZERO_BUFF(qat_sm3_ctx->pSrcBufferList.pPrivateMetaData, qat_sm3_ctx->qat_svm); QAT_MEM_FREE_NONZERO_BUFF(qat_sm3_ctx->session_ctx, qat_sm3_ctx->qat_svm); OPENSSL_free(session_data); qat_sm3_ctx->session_data = NULL; qat_sm3_ctx->pOpData = NULL; qat_sm3_ctx->rc_refs = NULL; return 0; } static int qat_hw_sm3_do_offload(QAT_SM3_CTX *qat_sm3_ctx, const void *in, size_t len, int packet_type) { int job_ret = 0; int ret = 0; /* Default fail */ CpaStatus status; op_done_t op_done; thread_local_variables_t *tlv = NULL; CpaFlatBuffer src_buffer; if (!qat_sm3_ctx->context_params_set) { if (!qat_hw_sm3_setup_param(qat_sm3_ctx)) { WARN("SM3 operational params setup failed.\n"); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); return 0; } } /* The variables in and out remain separate */ if (!qat_sm3_ctx->qat_svm) { src_buffer.pData = qaeCryptoMemAlloc(len + QAT_SM3_DIGEST_SIZE, __FILE__, __LINE__); if ((src_buffer.pData) == NULL) { WARN("Unable to allocate memory for buffer for sm3 hash.\n"); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_MALLOC_FAILURE); goto err; } } src_buffer.dataLenInBytes = len + QAT_SM3_DIGEST_SIZE; if (len == 0) { DEBUG("qat hw start offload: Length 0\n"); } else { DUMPL("qat hw start offload", in, (len < 128) ? len : 128); if (!qat_sm3_ctx->qat_svm) memcpy(src_buffer.pData, in, len); else src_buffer.pData = (Cpa8U *)in; } qat_sm3_ctx->pSrcBufferList.pBuffers = &src_buffer; tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); goto err; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failed to setup async event notification\n"); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); goto err; } } qat_sm3_ctx->pSrcBufferList.pUserData = NULL; qat_sm3_ctx->pOpData->sessionCtx = qat_sm3_ctx->session_ctx; if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packet_type && qat_sm3_ctx->qat_offloaded == 0) { qat_sm3_ctx->pOpData->packetType = CPA_CY_SYM_PACKET_TYPE_FULL; } else { qat_sm3_ctx->pOpData->packetType = packet_type; } /* The message length, in bytes, of the source buffer that the hash * will be computed on. */ qat_sm3_ctx->pOpData->messageLenToHashInBytes = len; qat_sm3_ctx->pOpData->pDigestResult = src_buffer.pData + len; if (!is_instance_available(qat_sm3_ctx->inst_num)) { WARN("QAT instance %d not available.\n", qat_sm3_ctx->inst_num); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } qat_cleanup_op_done(&op_done); goto err; } /* same src & dst for an in-place operation */ status = qat_sym_perform_op(qat_sm3_ctx->inst_num, &op_done, qat_sm3_ctx->pOpData, &(qat_sm3_ctx->pSrcBufferList), &(qat_sm3_ctx->pSrcBufferList), &(qat_sm3_ctx->session_data->verifyDigest)); if (status != CPA_STATUS_SUCCESS) { if (((status == CPA_STATUS_RESTARTING) || (status == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG ("Failed to submit request to qat inst_num %d device_id %d - %s\n", qat_sm3_ctx->inst_num, qat_instance_details[qat_sm3_ctx->inst_num].qat_instance_info. physInstId.packageId, __func__); } QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.job != NULL) qat_clear_async_event_notification(op_done.job); qat_cleanup_op_done(&op_done); goto err; } } } if (enable_heuristic_polling) QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (op_done.verifyResult != CPA_TRUE) { WARN("Verification of result failed\n"); QATerr(QAT_F_QAT_HW_SM3_DO_OFFLOAD, ERR_R_INTERNAL_ERROR); if (op_done.status == CPA_STATUS_FAIL) { CRYPTO_QAT_LOG ("Verification of result failed for qat inst_num %d device_id %d - %s\n", qat_sm3_ctx->inst_num, qat_instance_details[qat_sm3_ctx->inst_num].qat_instance_info. physInstId.packageId, __func__); qat_cleanup_op_done(&op_done); goto err; } } qat_cleanup_op_done(&op_done); /* final partial */ if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packet_type) { memcpy(qat_sm3_ctx->digest_data, src_buffer.pData + len, QAT_SM3_DIGEST_SIZE); ret = 1; } else { qat_sm3_ctx->qat_offloaded = 1; ret = 1; } err: if (!qat_sm3_ctx->qat_svm) qaeCryptoMemFreeNonZero(src_buffer.pData); return ret; } /****************************************************************************** * function: * qat_hw_sm3_init(EVP_MD_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the hash algorithm parameters for EVP context. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_hw_sm3_init(void *ctx) #else int qat_hw_sm3_init(EVP_MD_CTX *ctx) #endif { #ifndef QAT_OPENSSL_PROVIDER memset(QAT_SM3_GET_CTX(ctx), 0, sizeof(QAT_SM3_CTX)); # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) if (qat_openssl3_sm3_fallback == 1) { DEBUG("- Switched to software mode\n"); int sts = 0; int (*sw_fn_ptr)(EVP_MD_CTX *) = NULL; sw_fn_ptr = EVP_MD_meth_get_init((EVP_MD *)EVP_sm3()); sts = (*sw_fn_ptr)(ctx); DEBUG("SW Finished %p\n", ctx); return sts; } # endif #else if ((!qat_hw_sm3_offload) || (qat_get_qat_offload_disabled())) { QAT_SM3_CTX *qat_sm3_ctx = (QAT_SM3_CTX *) ctx; qat_sm3_ctx->sw_md_ctx = EVP_MD_CTX_new(); if (qat_sm3_ctx->sw_md_ctx == NULL) { WARN("EVP_MD_CTX_new failed.\n"); } qat_sm3_ctx->sw_md = EVP_MD_fetch(NULL, "sm3", "provider=default"); if (qat_sm3_ctx->sw_md == NULL) { WARN("EVP_MD_fetch failed.\n"); } if (!EVP_DigestInit_ex(qat_sm3_ctx->sw_md_ctx, qat_sm3_ctx->sw_md, NULL)) { WARN("Software calculate failed \n"); return 0; } DEBUG("SW Init Finished %p\n", qat_sm3_ctx); return 1; } #endif return 1; } /****************************************************************************** * function: * qat_hw_sm3_update(EVP_MD_CTX *ctx, const void *in, size_t len) * * @param ctx [IN] - pointer to existing context * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval len function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_hw_sm3_update(void *ctx, const void *in, size_t len) #else int qat_hw_sm3_update(EVP_MD_CTX *ctx, const void *in, size_t len) #endif { const unsigned char *data = in; # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int sts = 0; int (*sw_fn_ptr)(EVP_MD_CTX *, const void *, size_t) = NULL; #endif QAT_SM3_CTX *qat_sm3_ctx = NULL; unsigned char *p; size_t n; if (len == 0) { DEBUG("sm3 hw update with len = 0 %p\n", ctx); return 1; } if (unlikely(in == NULL)) { WARN("in %p is NULL\n", in); QATerr(QAT_F_QAT_HW_SM3_UPDATE, QAT_R_INVALID_INPUT); return 0; } #ifdef QAT_OPENSSL_PROVIDER qat_sm3_ctx = (QAT_SM3_CTX *)ctx; #else qat_sm3_ctx = qat_hw_sm3_get_ctx(ctx); #endif if (unlikely(qat_sm3_ctx == NULL)) { WARN("SM3 context hash data is NULL.\n"); QATerr(QAT_F_QAT_HW_SM3_UPDATE, QAT_R_SM3_CTX_NULL); return 0; } if ((qat_openssl3_sm3_fallback == 1) || (!qat_hw_sm3_offload) || (qat_get_qat_offload_disabled())) { DEBUG("- Switched to software mode\n"); goto fallback; } qat_sm3_ctx->rcv_count += len; DUMPL("sm3 hw update receive", in, len); n = qat_sm3_ctx->num; /* Packets left from previous process */ if (n != 0) { p = (unsigned char *)qat_sm3_ctx->data; /* Offload threshold met */ if (len >= QAT_SM3_OFFLOAD_THRESHOLD || len + n >= QAT_SM3_OFFLOAD_THRESHOLD) { /* Use part of new packet filling the packet buffer */ memcpy(p + n, data, QAT_SM3_OFFLOAD_THRESHOLD - n); if (!qat_hw_sm3_do_offload (qat_sm3_ctx, p, QAT_SM3_OFFLOAD_THRESHOLD, CPA_CY_SYM_PACKET_TYPE_PARTIAL)) return 1; /* The data left of new input */ n = QAT_SM3_OFFLOAD_THRESHOLD - n; data += n; len -= n; qat_sm3_ctx->num = 0; /* * We use memset rather than OPENSSL_cleanse() here deliberately. * Using OPENSSL_cleanse() here could be a performance issue. It * will get properly cleansed on finalisation so this isn't a * security problem. */ memset(p, 0, QAT_SM3_OFFLOAD_THRESHOLD); /* keep it zeroed */ } else { /* Append the new packets to buffer */ memcpy(p + n, data, len); qat_sm3_ctx->num += (unsigned int)len; return 1; } } n = len / QAT_SM3_OFFLOAD_THRESHOLD; if (n > 0) { n *= QAT_SM3_OFFLOAD_THRESHOLD; if (!qat_hw_sm3_do_offload(qat_sm3_ctx, in, n, CPA_CY_SYM_PACKET_TYPE_PARTIAL)) return 1; data += n; len -= n; } /* Save the bytes into buffer if there're some bytes left after the previous update. */ if (len != 0) { qat_sm3_ctx->data = OPENSSL_zalloc(QAT_SM3_OFFLOAD_THRESHOLD); qat_sm3_ctx->data_refs = OPENSSL_zalloc(sizeof(int)); p = (unsigned char *)qat_sm3_ctx->data; qat_sm3_ctx->num = (unsigned int)len; memcpy(p, data, len); } #ifndef QAT_OPENSSL_PROVIDER EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE); #endif return 1; fallback: # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) sw_fn_ptr = EVP_MD_meth_get_update((EVP_MD *)EVP_sm3()); sts = (*sw_fn_ptr)(ctx, in, len); DEBUG("SW Finished %p\n", ctx); return sts; # else if (!EVP_DigestUpdate(qat_sm3_ctx->sw_md_ctx, in, len)) { WARN("Software calculate failed \n"); return 0; } DEBUG("SW Update Finished %p\n", qat_sm3_ctx); return 1; # endif } #ifdef QAT_OPENSSL_PROVIDER int qat_hw_sm3_copy(QAT_SM3_CTX *to, const QAT_SM3_CTX *from) #else int qat_hw_sm3_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) #endif { QAT_SM3_CTX *qat_from; if (NULL == from) { WARN("sm3 copy from %p is NULL\n", from); QATerr(QAT_F_QAT_HW_SM3_COPY, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER /* Digest-copy can be called without a md_data in some condition */ if (EVP_MD_CTX_md_data(from) == 0) { DEBUG("digest copy without md_data\n"); return 1; } qat_from = QAT_SM3_GET_CTX(from); #else qat_from = (QAT_SM3_CTX *)from; #endif if (NULL == qat_from) { WARN("qat_from %p is NULL\n", qat_from); QATerr(QAT_F_QAT_HW_SM3_COPY, QAT_R_CTX_NULL); return 0; } if (qat_from->rc_refs) (*qat_from->rc_refs)++; if (qat_from->data_refs) (*qat_from->data_refs)++; return 1; } /****************************************************************************** * function: * qat_hw_sm3_final(EVP_MD_CTX *ctx, unsigned char *md) * * @param ctx [IN] - pointer to existing context * @param md [OUT] - output buffer for digest result * * @retval -1 function failed * @retval 1 function succeeded * * description: * This function performs the copy operation of digest into md buffer. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_hw_sm3_final(void *ctx, unsigned char *md) #else int qat_hw_sm3_final(EVP_MD_CTX *ctx, unsigned char *md) #endif { QAT_SM3_CTX *qat_sm3_ctx = NULL; # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) int sts = 0; int (*sw_fn_ptr)(EVP_MD_CTX *, unsigned char *) = NULL; #endif if (md == NULL) { WARN("hw sm3 md is null\n"); QATerr(QAT_F_QAT_HW_SM3_FINAL, QAT_R_INPUT_PARAM_INVALID); return 0; } #ifdef QAT_OPENSSL_PROVIDER qat_sm3_ctx = (QAT_SM3_CTX *)ctx; #else qat_sm3_ctx = qat_hw_sm3_get_ctx(ctx); #endif if (qat_sm3_ctx == NULL) { WARN("qat_sm3_ctx is NULL\n"); QATerr(QAT_F_QAT_HW_SM3_FINAL, QAT_R_CTX_NULL); return 0; } if ((qat_openssl3_sm3_fallback == 1) || (!qat_hw_sm3_offload) || (qat_get_qat_offload_disabled())) { DEBUG("- Switched to software mode\n"); goto fallback; } # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (qat_sm3_ctx->rcv_count <= CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_HW_SM3) { /* Software calculation can start from init, because SPO threshold will always small than context buffer and all data are stored in context buffer */ #ifndef QAT_OPENSSL_PROVIDER int (*sw_init_ptr)(EVP_MD_CTX *); int (*sw_update_ptr)(EVP_MD_CTX *, const void *, size_t); int (*sw_final_ptr)(EVP_MD_CTX *, unsigned char *); DUMPL("Start ossl calculate", qat_sm3_ctx->data, qat_sm3_ctx->num); sw_init_ptr = EVP_MD_meth_get_init((EVP_MD *)EVP_sm3()); sw_update_ptr = EVP_MD_meth_get_update((EVP_MD *)EVP_sm3()); sw_final_ptr = EVP_MD_meth_get_final((EVP_MD *)EVP_sm3()); if ((*sw_init_ptr) (ctx) != 1 || (*sw_update_ptr) (ctx, qat_sm3_ctx->data, qat_sm3_ctx->num) != 1 || (*sw_final_ptr) (ctx, md) != 1) { WARN("Software calculate failed %p\n", ctx); return 0; } DUMPL("DigestResult (OSSL)", md, QAT_SM3_DIGEST_SIZE); return 1; #else qat_sm3_ctx->sw_md_ctx = EVP_MD_CTX_new(); if (qat_sm3_ctx->sw_md_ctx == NULL) WARN("EVP_MD_CTX_new failed.\n"); qat_sm3_ctx->sw_md = EVP_MD_fetch(NULL, "sm3", "provider=default"); if (qat_sm3_ctx->sw_md == NULL) { WARN("EVP_MD_fetch failed.\n"); } if (!EVP_DigestInit_ex(qat_sm3_ctx->sw_md_ctx, qat_sm3_ctx->sw_md, NULL) || !EVP_DigestUpdate(qat_sm3_ctx->sw_md_ctx, qat_sm3_ctx->data, qat_sm3_ctx->num) || !EVP_DigestFinal_ex(qat_sm3_ctx->sw_md_ctx, md, NULL)) { WARN("QAT_SW SM3 Offload failed \n"); return 0; } DUMPL("DigestResult (OSSL)", md, QAT_SM3_DIGEST_SIZE); return 1; # endif } #endif qat_sm3_ctx->digest_data = md; if (!qat_hw_sm3_do_offload(qat_sm3_ctx, qat_sm3_ctx->data, qat_sm3_ctx->num, CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL)) return 0; DUMPL("DigestResult (QAT_HW)", md, QAT_SM3_DIGEST_SIZE); return 1; fallback: # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) sw_fn_ptr = EVP_MD_meth_get_final((EVP_MD *)EVP_sm3()); sts = (*sw_fn_ptr)(ctx, md); DEBUG("SW Finished %p\n", ctx); return sts; # else if (!EVP_DigestFinal_ex(qat_sm3_ctx->sw_md_ctx, md, NULL)) { WARN("Software calculate failed \n"); return 0; } DEBUG("SW Final Finished %p\n", qat_sm3_ctx); return 1; # endif } /****************************************************************************** * function: * qat_hw_sm3_cleanup(EVP_MD_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int qat_hw_sm3_cleanup(QAT_SM3_CTX *ctx) #else int qat_hw_sm3_cleanup(EVP_MD_CTX *ctx) #endif { QAT_SM3_CTX *qat_sm3_ctx; CpaStatus status = 0; int ret_val = 1; CpaBoolean sessionInUse = CPA_FALSE; #ifdef QAT_OPENSSL_PROVIDER qat_sm3_ctx = (QAT_SM3_CTX *)ctx; #else qat_sm3_ctx = qat_hw_sm3_get_ctx(ctx); #endif if (NULL == qat_sm3_ctx) { WARN("qat_sm3_ctx is NULL\n"); QATerr(QAT_F_QAT_HW_SM3_CLEANUP, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER if (EVP_MD_CTX_md_data(ctx) == NULL) { DEBUG("digest cleanup without md_data\n"); return 1; } #endif if (qat_sm3_ctx->data_refs) { if (*qat_sm3_ctx->data_refs > 0) { (*qat_sm3_ctx->data_refs)--; DEBUG("HW SM3 data reference decrease to %d\n", *qat_sm3_ctx->data_refs); } else { OPENSSL_free(qat_sm3_ctx->data); OPENSSL_free(qat_sm3_ctx->data_refs); } } if (qat_sm3_ctx->context_params_set) { if (*qat_sm3_ctx->rc_refs > 0) { (*qat_sm3_ctx->rc_refs)--; DEBUG("HW SM3 resource reference decrease to %d\n", *qat_sm3_ctx->rc_refs); return 1; } if (is_instance_available(qat_sm3_ctx->inst_num)) { /* Wait for in-flight requests before removing session */ if (qat_sm3_ctx->session_ctx != NULL) { do { cpaCySymSessionInUse(qat_sm3_ctx->session_ctx, &sessionInUse); } while (sessionInUse); } if ((status = cpaCySymRemoveSession(qat_instance_handles [qat_sm3_ctx->inst_num], qat_sm3_ctx->session_ctx)) != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, status= %d.!\n", status); ret_val = 0; } } else { WARN("instance no longer available\n"); } QAT_MEM_FREE_NONZERO_BUFF(qat_sm3_ctx->session_ctx, qat_sm3_ctx->qat_svm); qat_sm3_ctx->session_ctx = NULL; QAT_MEM_FREE_NONZERO_BUFF(qat_sm3_ctx->pSrcBufferList.pPrivateMetaData, qat_sm3_ctx->qat_svm); qat_sm3_ctx->pSrcBufferList.pPrivateMetaData = NULL; OPENSSL_free(qat_sm3_ctx->session_data); qat_sm3_ctx->session_data = NULL; qat_sm3_ctx->context_params_set = 0; } return ret_val; } int qat_hw_sm3_md_methods(EVP_MD *c) { int res = 1; res &= EVP_MD_meth_set_result_size(c, QAT_SM3_STATE_SIZE); res &= EVP_MD_meth_set_input_blocksize(c, QAT_SM3_BLOCK_SIZE); /* Totally 3 memory sections in application data, common EVP_MD, SM3_CTX used for SM3 software, and QAT_SM3_CTX for QAT_HW */ res &= EVP_MD_meth_set_app_datasize(c, sizeof(EVP_MD *) + sizeof(SM3_CTX) + sizeof(QAT_SM3_CTX)); res &= EVP_MD_meth_set_flags(c, EVP_MD_CTX_FLAG_REUSE); #ifndef QAT_OPENSSL_PROVIDER res &= EVP_MD_meth_set_init(c, qat_hw_sm3_init); res &= EVP_MD_meth_set_update(c, qat_hw_sm3_update); res &= EVP_MD_meth_set_final(c, qat_hw_sm3_final); res &= EVP_MD_meth_set_copy(c, qat_hw_sm3_copy); res &= EVP_MD_meth_set_cleanup(c, qat_hw_sm3_cleanup); #endif return res; } const EVP_MD *qat_hw_create_sm3_meth(int nid, int key_type) { int res = 1; EVP_MD *qat_hw_sm3_meth = NULL; if ((qat_hw_sm3_meth = EVP_MD_meth_new(nid, key_type)) == NULL) { WARN("Failed to allocate digest methods for nid %d\n", nid); QATerr(QAT_F_QAT_HW_CREATE_SM3_METH, QAT_R_INIT_FAILURE); return NULL; } if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_SM3)) { res = qat_hw_sm3_md_methods(qat_hw_sm3_meth); if (0 == res) { WARN("Failed to set MD methods for nid %d\n", nid); QATerr(QAT_F_QAT_HW_CREATE_SM3_METH, QAT_R_INIT_FAILURE); EVP_MD_meth_free(qat_hw_sm3_meth); return NULL; } qat_hw_sm3_offload = 1; DEBUG("QAT HW SM3 Registration succeeded\n"); return qat_hw_sm3_meth; } else { qat_hw_sm3_offload = 0; DEBUG("QAT HW SM3 is disabled, using OpenSSL SW\n"); # if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) qat_openssl3_sm3_fallback = 1; res = qat_hw_sm3_md_methods(qat_hw_sm3_meth); if (0 == res) { WARN("Failed to set MD methods for nid %d\n", nid); EVP_MD_meth_free(qat_hw_sm3_meth); return NULL; } return qat_hw_sm3_meth; # else # ifdef OPENSSL_NO_SM2_SM3 return NULL; # else return (EVP_MD *)EVP_sm3(); # endif # endif } } #endif /* ENABLE_QAT_HW_SM3 */ qatengine-1.9.0/qat_hw_sm3.h000066400000000000000000000106751500416242000157150ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sm3.h * * This file provides a interface for SM3 operations * *****************************************************************************/ #ifndef QAT_HW_SM3_H # define QAT_HW_SM3_H #ifndef QAT_OPENSSL_PROVIDER # include #endif # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "cpa_cy_drbg.h" # ifdef ENABLE_QAT_HW_SM3 /* Digest Size */ # define QAT_SM3_DIGEST_SIZE 32 /*Block Size */ # define QAT_SM3_BLOCK_SIZE 64 /* State Size */ # define QAT_SM3_STATE_SIZE 32 /* Min 260x to met 16k record offload, 16461 bytes in bulk crypto test */ # define QAT_SM3_OFFLOAD_THRESHOLD (260 * QAT_SM3_BLOCK_SIZE) # define SM3_DIGEST_LENGTH 32 # define SM3_WORD unsigned int # define SM3_CBLOCK 64 # define SM3_LBLOCK (SM3_CBLOCK/4) typedef struct SM3state_st { SM3_WORD A, B, C, D, E, F, G, H; SM3_WORD Nl, Nh; SM3_WORD data[SM3_LBLOCK]; unsigned int num; } SM3_CTX; typedef struct { int inst_num; int context_params_set; /* True if init called */ int qat_offloaded; /* True if there was an offload. */ int *rc_refs; /* The count of the resource reference */ int *data_refs; /* The count of the resource reference */ unsigned char *data; /* The buffer */ unsigned int num; /* The data left in buffer */ unsigned int rcv_count; /* The data received */ CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx session_ctx; CpaCySymOpData *pOpData; CpaBufferList pSrcBufferList; /* For QAT metadata */ unsigned char *digest_data; EVP_MD *sw_md; EVP_MD_CTX *sw_md_ctx; int qat_svm; } QAT_SM3_CTX; /* Totally 3 memory sections in application data, common EVP_MD, SM3_CTX used for SM3 software, and QAT_SM3_CTX for QAT_HW */ # define QAT_SM3_GET_CTX(ctx) \ ((QAT_SM3_CTX *) (EVP_MD_CTX_md_data(ctx) + sizeof(SM3_CTX))) const EVP_MD *qat_hw_create_sm3_meth(int nid, int key_type); # ifndef QAT_OPENSSL_PROVIDER int qat_hw_sm3_init(EVP_MD_CTX *ctx); int qat_hw_sm3_update(EVP_MD_CTX *ctx, const void *in, size_t len); int qat_hw_sm3_final(EVP_MD_CTX *ctx, unsigned char *md); # else int qat_hw_sm3_init(void *ctx); int qat_hw_sm3_update(void *ctx, const void *in, size_t len); int qat_hw_sm3_copy(QAT_SM3_CTX *to, const QAT_SM3_CTX *from); int qat_hw_sm3_final(void *ctx, unsigned char *md); int qat_hw_sm3_cleanup(QAT_SM3_CTX *ctx); # endif /* QAT_OPENSSL_PROVIDER */ # endif /* ENABLE_QAT_HW_SM3 */ #endif /* QAT_HW_SM3_H */ qatengine-1.9.0/qat_hw_sm4_cbc.c000066400000000000000000001026561500416242000165210ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sm4_cbc.c * * This file contains the engine implementations for SM4-CBC operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifdef ENABLE_QAT_HW_SM4_CBC #include #include #include "qat_utils.h" #include "e_qat.h" #include "qat_hw_callback.h" #include "qat_hw_polling.h" #include "qat_events.h" #include "qat_evp.h" #include "qat_hw_sm4_cbc.h" #ifdef ENABLE_QAT_SW_SM4_CBC # include "qat_sw_sm4_cbc.h" #endif /* Setup template for Session Setup Data as most of the fields * are constant. The constant values of some of the fields are * chosen for Encryption operation. */ static const CpaCySymSessionSetupData template_ssd = { .sessionPriority = CPA_CY_PRIORITY_HIGH, .symOperation = CPA_CY_SYM_OP_CIPHER, .digestIsAppended = CPA_FALSE, .verifyDigest = CPA_FALSE, .partialsNotRequired = CPA_TRUE, .cipherSetupData = { .cipherAlgorithm = CPA_CY_SYM_CIPHER_SM4_CBC, .cipherKeyLenInBytes = 0, .pCipherKey = NULL, .cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT, }, }; static const CpaCySymOpData template_opData = { .sessionCtx = NULL, .packetType = CPA_CY_SYM_PACKET_TYPE_FULL, .pIv = NULL, .ivLenInBytes = 0, .cryptoStartSrcOffsetInBytes = 0, .messageLenToCipherInBytes = 0, .hashStartSrcOffsetInBytes = 0, .messageLenToHashInBytes = 0, .pDigestResult = NULL, .pAdditionalAuthData = NULL }; #ifdef QAT_OPENSSL_PROVIDER static QAT_EVP_CIPHER_SM4_CBC get_default_cipher_sm4_cbc() { static QAT_EVP_CIPHER_SM4_CBC sm4_cipher; static int initilazed = 0; if (!initilazed) { QAT_EVP_CIPHER_SM4_CBC *cipher = (QAT_EVP_CIPHER_SM4_CBC *)EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); if (cipher) { sm4_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initilazed = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return sm4_cipher; } #endif static inline void qat_sm4_cbc_free_op(qat_sm4_op_params *op, int qat_svm) { if (op == NULL) return; if (!qat_svm) qaeCryptoMemFree(op->src_fbuf.pData); QAT_MEM_FREE_BUFF(op->src_sgl.pPrivateMetaData, qat_svm); QAT_MEM_FREE_BUFF(op->dst_sgl.pPrivateMetaData, qat_svm); QAT_MEM_FREE_BUFF(op->op_data.pIv, qat_svm); OPENSSL_free(op); op = NULL; } #ifdef QAT_OPENSSL_PROVIDER static int qat_setup_op_params(QAT_PROV_CBC_CTX *ctx) #else static int qat_setup_op_params(EVP_CIPHER_CTX *ctx) #endif { CpaCySymOpData *opd = NULL; Cpa32U msize = 0; #ifndef QAT_OPENSSL_PROVIDER qat_sm4_ctx *qctx = qat_sm4_get_cipher_data(ctx); size_t iv_len = EVP_CIPHER_CTX_iv_length(ctx); #else qat_sm4_ctx *qctx = (qat_sm4_ctx *)ctx->qat_cipher_ctx; size_t iv_len = ctx->ivlen; #endif if (qctx->op != NULL) { qat_sm4_cbc_free_op(qctx->op, qctx->qat_svm); DEBUG("[%p] qop memory freed\n", ctx); } qctx->op = (qat_sm4_op_params *) OPENSSL_zalloc(sizeof(qat_sm4_op_params)); if (qctx->op == NULL) { WARN("Unable to allocate memory[%lu bytes] for qat op params\n", sizeof(qat_sm4_op_params)); QATerr(QAT_F_QAT_SETUP_OP_PARAMS, QAT_R_SM4_MALLOC_FAILED); return 0; } qctx->op->src_fbuf.pData = NULL; qctx->op->dst_fbuf.pData = NULL; qctx->op->src_fbuf.dataLenInBytes = 0; qctx->op->dst_fbuf.dataLenInBytes = 0; qctx->op->src_sgl.numBuffers = 1; qctx->op->src_sgl.pBuffers = &qctx->op->src_fbuf; qctx->op->src_sgl.pUserData = NULL; qctx->op->src_sgl.pPrivateMetaData = NULL; qctx->op->dst_sgl.numBuffers = 1; qctx->op->dst_sgl.pBuffers = &qctx->op->dst_fbuf; qctx->op->dst_sgl.pUserData = NULL; qctx->op->dst_sgl.pPrivateMetaData = NULL; /* setup meta data for buffer lists */ if (cpaCyBufferListGetMetaSize(qat_instance_handles[qctx->inst_num], qctx->op->src_sgl.numBuffers, &msize) != CPA_STATUS_SUCCESS) { WARN("cpaCyBufferListGetBufferSize failed.\n"); QATerr(QAT_F_QAT_SETUP_OP_PARAMS, QAT_R_SM4_SETUP_META_DATA_FAILED); goto err; } DEBUG("Size of meta data = %d\n", msize); if (msize) { qctx->op->src_sgl.pPrivateMetaData = qat_mem_alloc(msize, qctx->qat_svm, __FILE__, __LINE__); qctx->op->dst_sgl.pPrivateMetaData = qat_mem_alloc(msize, qctx->qat_svm, __FILE__, __LINE__); if (qctx->op->src_sgl.pPrivateMetaData == NULL || qctx->op->dst_sgl.pPrivateMetaData == NULL) { WARN("QMEM alloc failed for PrivateData\n"); QATerr(QAT_F_QAT_SETUP_OP_PARAMS, QAT_R_SM4_MALLOC_FAILED); goto err; } } opd = &qctx->op->op_data; /* Copy the opData template */ memcpy(opd, &template_opData, sizeof(template_opData)); /* Update Opdata */ opd->sessionCtx = qctx->session_ctx; opd->pIv = qat_mem_alloc(iv_len, qctx->qat_svm, __FILE__, __LINE__); if (opd->pIv == NULL) { WARN("QMEM Mem Alloc failed for pIv.\n"); QATerr(QAT_F_QAT_SETUP_OP_PARAMS, QAT_R_SM4_MALLOC_FAILED); goto err; } opd->ivLenInBytes = (Cpa32U)iv_len; DEBUG("[%p] op setup done.\n", ctx); return 1; err: qat_sm4_cbc_free_op(qctx->op, qctx->qat_svm); return 0; } static void qat_sm4_cbc_cb(void *pCallbackTag, CpaStatus status, const CpaCySymOp operationType, void *pOpData, CpaBufferList *pDstBuffer, CpaBoolean verifyResult) { if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_cipher_pipeline_requests_in_flight); } qat_crypto_callbackFn(pCallbackTag, status, CPA_CY_SYM_OP_CIPHER, pOpData, NULL, CPA_TRUE); } #ifdef QAT_OPENSSL_PROVIDER int qat_sm4_cbc_init(QAT_PROV_CBC_CTX *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) #else int qat_sm4_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc) #endif { CpaCySymSessionSetupData *ssd = NULL; Cpa32U sctx_size = 0; CpaCySymSessionCtx sctx = NULL; CpaStatus sts = 0; qat_sm4_ctx *qctx = NULL; #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_CBC sw_sm4_cbc_cipher; #endif int ret = 0; unsigned char *ckey = NULL; int ckeylen; #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) sm4cbc_coexistence_ctx *sm4cbc_hw_sw_ctx = NULL; #endif #ifndef QAT_OPENSSL_PROVIDER if (ctx == NULL || inkey == NULL) { WARN("ctx or inkey is NULL.\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_NULL_CTX_OR_KEY); return 0; } #else if (ctx == NULL) { WARN("ctx is NULL.\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_NULL_CTX); return 0; } #endif #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sm4_cbc_coexist) { (void)qat_sw_sm4_cbc_key_init(ctx, inkey, iv, enc); /* Saving qat sw sm4cbc cipher data for coexistence. */ sm4cbc_hw_sw_ctx = (sm4cbc_coexistence_ctx *)(EVP_CIPHER_CTX_get_cipher_data(ctx)); qctx = &(sm4cbc_hw_sw_ctx->sm4cbc_qat_hw_ctx); } else { qctx = qat_sm4_get_cipher_data(ctx); } # else qctx = qat_sm4_get_cipher_data(ctx); # endif #else qctx = (qat_sm4_ctx *)ctx->qat_cipher_ctx; #endif if (qctx == NULL) { WARN("qctx is NULL.\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_NULL_QCTX); return 0; } DEBUG("QAT HW SM4 CBC Started\n"); INIT_SM4_CLEAR_ALL_FLAGS(qctx); #ifndef QAT_OPENSSL_PROVIDER if (iv != NULL) memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx)); else memset(EVP_CIPHER_CTX_iv_noconst(ctx), 0, EVP_CIPHER_CTX_iv_length(ctx)); ckeylen = EVP_CIPHER_CTX_key_length(ctx); #else if (iv != NULL) memcpy(ctx->iv, iv, ivlen); else memset(ctx->iv, 0, ivlen); ctx->enc = enc; ckeylen = ctx->keylen; #endif ckey = OPENSSL_malloc(ckeylen); if (ckey == NULL) { WARN("Unable to allocate memory for Cipher key.\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_NULL_CKEY); return 0; } if (inkey != NULL) memcpy(ckey, inkey, ckeylen); else WARN("SM4-CBC key is NULL \n"); qctx->fallback = 0; #ifndef QAT_OPENSSL_PROVIDER const EVP_CIPHER *sw_cipher = EVP_sm4_cbc(); unsigned int sw_size = EVP_CIPHER_impl_ctx_size(sw_cipher); if (sw_size != 0) { qctx->sw_ctx_cipher_data = OPENSSL_zalloc(sw_size); if (qctx->sw_ctx_cipher_data == NULL) { WARN("Unable to allocate memory [%u bytes] for sw_ctx_cipher_data\n", sw_size); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_MALLOC_FAILED); goto err; } } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); /* Run the software init function */ ret = EVP_CIPHER_meth_get_init(sw_cipher)(ctx, inkey, iv, enc); # ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sm4_cbc_coexist) { EVP_CIPHER_CTX_set_cipher_data(ctx, sm4cbc_hw_sw_ctx); } else { EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); } # else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); # endif if (ret != 1) goto err; #else OSSL_PARAM params[2] = {OSSL_PARAM_END, OSSL_PARAM_END}; sw_sm4_cbc_cipher = get_default_cipher_sm4_cbc(); if (enc) { if (!ctx->sw_ctx) ctx->sw_ctx = sw_sm4_cbc_cipher.newctx(ctx); ret = sw_sm4_cbc_cipher.einit(ctx->sw_ctx, inkey, keylen, iv, ivlen, params); } else { if (!ctx->sw_ctx) ctx->sw_ctx = sw_sm4_cbc_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); ret = sw_sm4_cbc_cipher.dinit(ctx->sw_ctx, inkey, keylen, iv, ivlen, params); } if (ret != 1) goto err; #endif if (qat_get_qat_offload_disabled()) { /* * Setting qctx->fallback as a flag for the other functions. * This means in the other functions (and in the err section in this function) * we no longer need to check qat_get_qat_offload_disabled() but just check * the fallback flag instead. This has the added benefit that even if * the engine control message to enable HW offload is sent it will not affect * requests that have already been init'd, they will continue to use SW until * the request is complete, i.e. no race condition. */ qctx->fallback = 1; goto err; } ssd = OPENSSL_malloc(sizeof(CpaCySymSessionSetupData)); if (ssd == NULL) { WARN("Failed to allocate session setup data\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_MALLOC_FAILED); goto err; } qctx->session_data = ssd; /* Copy over the template for most of the values */ memcpy(ssd, &template_ssd, sizeof(template_ssd)); /* Change constant values for decryption */ if (!enc) { ssd->cipherSetupData.cipherDirection = CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT; ssd->algChainOrder = CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; ssd->verifyDigest = CPA_FALSE; } ssd->cipherSetupData.cipherKeyLenInBytes = ckeylen; ssd->cipherSetupData.pCipherKey = ckey; qctx->inst_num = get_instance(QAT_INSTANCE_SYM, QAT_INSTANCE_ANY); if (qctx->inst_num == QAT_INVALID_INSTANCE) { WARN("Failed to get a QAT instance.\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_GET_INSTANCE_FAILED); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); qctx->fallback = 1; } goto err; } DEBUG("inst_num = %d inst mem type = %d\n", qctx->inst_num, qctx->qat_svm); DUMP_SESSION_SETUP_DATA(ssd); sts = cpaCySymSessionCtxGetSize(qat_instance_handles[qctx->inst_num], ssd, &sctx_size); if (sts != CPA_STATUS_SUCCESS) { WARN("Failed to get SessionCtx size.\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT,QAT_R_SM4_GET_SESSIONCTX_SIZE_FAILED); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qctx->fallback = 1; } goto err; } DEBUG("Size of session ctx = %d\n", sctx_size); sctx = (CpaCySymSessionCtx) qat_mem_alloc(sctx_size, qctx->qat_svm, __FILE__, __LINE__); if (sctx == NULL) { WARN("QMEM alloc failed for session ctx!\n"); QATerr(QAT_F_QAT_SM4_CBC_INIT, QAT_R_SM4_MALLOC_FAILED); goto err; } qctx->session_ctx = sctx; qctx->op = NULL; INIT_SM4_SET_FLAG(qctx, INIT_SM4_QAT_CTX_INIT); DEBUG("[%p] qat chained cipher ctx %p initialised\n",ctx, qctx); return 1; err: /* NOTE: no init seq flags will have been set if this 'err:' label code section is entered. */ QAT_CLEANSE_FREE_BUFF(ckey, ckeylen); if (ssd != NULL) OPENSSL_free(ssd); qctx->session_data = NULL; QAT_MEM_FREE_BUFF(qctx->session_ctx, qctx->qat_svm); if (qctx->fallback == 1) { #ifndef QAT_OPENSSL_PROVIDER if ((qctx->sw_ctx_cipher_data != NULL) && (ret == 1)) { #else if (ret == 1) { #endif DEBUG("- Fallback to software mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to SW - %s\n", __func__); return ret; /* result returned from running software init function */ } #ifndef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx_cipher_data != NULL) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } #endif } return 0; } #ifdef QAT_OPENSSL_PROVIDER int qat_sm4_cbc_cleanup(QAT_PROV_CBC_CTX *ctx) #else int qat_sm4_cbc_cleanup(EVP_CIPHER_CTX *ctx) #endif { qat_sm4_ctx *qctx = NULL; CpaStatus sts = 0; CpaCySymSessionSetupData *ssd = NULL; int retVal = 1; #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) sm4cbc_coexistence_ctx *sm4cbc_hw_sw_ctx = NULL; #endif if (ctx == NULL) { WARN("ctx parameter is NULL.\n"); QATerr(QAT_F_QAT_SM4_CBC_CLEANUP, QAT_R_SM4_NULL_POINTER); return 0; } #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sm4_cbc_coexist) { (void)qat_sw_sm4_cbc_cleanup(ctx); /* Clean coexistence sm4cbc cipher data for qat sw. */ sm4cbc_hw_sw_ctx = (sm4cbc_coexistence_ctx *)(EVP_CIPHER_CTX_get_cipher_data(ctx)); qctx = &(sm4cbc_hw_sw_ctx->sm4cbc_qat_hw_ctx); } else { qctx = qat_sm4_get_cipher_data(ctx); } # else qctx = qat_sm4_get_cipher_data(ctx); # endif #else qctx = (qat_sm4_ctx *)ctx->qat_cipher_ctx; #endif if (qctx == NULL) { WARN("qctx parameter is NULL.\n"); QATerr(QAT_F_QAT_SM4_CBC_CLEANUP, QAT_R_SM4_NULL_POINTER); return 0; } #ifndef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx_cipher_data != NULL) { OPENSSL_free(qctx->sw_ctx_cipher_data); qctx->sw_ctx_cipher_data = NULL; } #else if (ctx->sw_ctx) { OPENSSL_free(ctx->sw_ctx); ctx->sw_ctx = NULL; } #endif /* ctx may be cleaned before it gets a chance to allocate qop */ qat_sm4_cbc_free_op(qctx->op ,qctx->qat_svm); ssd = qctx->session_data; if (ssd) { if (INIT_SM4_IS_FLAG_SET(qctx, INIT_SM4_QAT_SESSION_INIT)) { if (is_instance_available(qctx->inst_num)) { /* Clean up session if hardware available regardless of whether in */ /* fallback or not, if in INIT_SM4_QAT_SESSION_INIT */ sts = cpaCySymRemoveSession(qat_instance_handles[qctx->inst_num], qctx->session_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymRemoveSession FAILED, sts = %d\n", sts); QATerr(QAT_F_QAT_SM4_CBC_CLEANUP, QAT_R_SM4_REMOVE_SESSION_FAILED); retVal = 0; } } } QAT_MEM_FREE_BUFF(qctx->session_ctx, qctx->qat_svm); QAT_CLEANSE_FREE_BUFF(ssd->hashSetupData.authModeSetupData.authKey, ssd->hashSetupData.authModeSetupData. authKeyLenInBytes); QAT_CLEANSE_FREE_BUFF(ssd->cipherSetupData.pCipherKey, ssd->cipherSetupData.cipherKeyLenInBytes); OPENSSL_free(ssd); } qctx->fallback = 0; INIT_SM4_CLEAR_ALL_FLAGS(qctx); DEBUG("[%p] EVP CTX cleaned up\n", ctx); return retVal; } #ifdef QAT_OPENSSL_PROVIDER int qat_sm4_cbc_do_cipher(QAT_PROV_CBC_CTX *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t len) #else int qat_sm4_cbc_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { CpaStatus sts = 0; CpaCySymOpData *opd = NULL; CpaBufferList *s_sgl = NULL; CpaBufferList *d_sgl = NULL; CpaFlatBuffer *s_fbuf = NULL; CpaFlatBuffer *d_fbuf = NULL; int retVal = 0, job_ret = 0; op_done_t op_done; qat_sm4_ctx *qctx = NULL; #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_CBC sw_sm4_cbc_cipher; #endif unsigned int ivlen = 0; int enc; int error = 0; int outlen = -1; #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD int nid = 0; #endif thread_local_variables_t *tlv = NULL; #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) sm4cbc_coexistence_ctx *sm4cbc_hw_sw_ctx = NULL; #endif if (ctx == NULL) { WARN("CTX parameter is NULL.\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_NULL_POINTER); return -1; } #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sm4_cbc_coexist) { sm4cbc_hw_sw_ctx = (sm4cbc_coexistence_ctx *)(EVP_CIPHER_CTX_get_cipher_data(ctx)); qctx = &(sm4cbc_hw_sw_ctx->sm4cbc_qat_hw_ctx); } else { qctx = qat_sm4_get_cipher_data(ctx); } # else qctx = qat_sm4_get_cipher_data(ctx); # endif #else qctx = ctx->qat_cipher_ctx; #endif if (qctx == NULL) { WARN("QAT CTX NULL\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_NULL_POINTER); return -1; } #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) if (qat_sm4_cbc_coexist) { /* 1. Requests will fallback to QAT SW if QAT HW initialize fail. * SM4_CBC_COEXIST_QAT_SW_MAX_PKT_LEN, using QAT_SW, otherwise using * 2. CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_SM4_CBC < len < * SM4_CBC_COEXIST_QAT_SW_MAX_PKT_LEN, using QAT_SW, otherwise using * QAT_HW. */ if (fallback_to_qat_sw || ((len >= SM4_CBC_COEXIST_QAT_SW_MIN_PKT_LEN) && (len <= SM4_CBC_COEXIST_QAT_SW_MAX_PKT_LEN))) { return qat_sw_sm4_cbc_cipher(ctx, out, in, len); } /* 1. A retry occurs, 16 requests will switche to QAT SW to be processed. */ if (qat_sw_sm4_cbc_cipher_req > 0) { qat_sw_sm4_cbc_cipher_req--; return qat_sw_sm4_cbc_cipher(ctx, out, in, len); } } #endif if (qctx->fallback == 1) { goto fallback; } #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifndef QAT_OPENSSL_PROVIDER nid = EVP_CIPHER_CTX_nid(ctx); # else nid = ctx->nid; # endif #endif if (!(is_instance_available(qctx->inst_num))) { WARN("No QAT instance available.\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); qctx->fallback = 1; goto fallback; } else { WARN("Fail - No QAT instance available and s/w fallback is not enabled.\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE); return -1; /* Fail if software fallback not enabled. */ } } else { if (!INIT_SM4_IS_FLAG_SET(qctx, INIT_SM4_QAT_CTX_INIT)) { WARN("QAT Context not initialised"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_QAT_CONTEXT_NOT_INITIALISED); return -1; } } #ifndef QAT_OPENSSL_PROVIDER enc = EVP_CIPHER_CTX_encrypting(ctx); ivlen = EVP_CIPHER_CTX_iv_length(ctx); #else enc = ctx->enc; ivlen = ctx->ivlen; #endif /* If we are encrypting and EVP_EncryptFinal_ex is called with a NULL input buffer then return 0. Note: we don't actually support partial requests in the engine but this workaround avoids an error from OpenSSL speed on the last request when measuring cipher performance. Speed is written to measure performance using partial requests.*/ if (in == NULL && out != NULL && enc) { DEBUG("QAT partial requests work-around: NULL input buffer passed.\n"); return 0; } else if (in == NULL || out == NULL) { WARN("in and out cannot be NULL pointer!\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_NULL_POINTER); return -1; } if (!INIT_SM4_IS_FLAG_SET(qctx, INIT_SM4_QAT_SESSION_INIT)) { DEBUG("inst_num = %d\n", qctx->inst_num); DUMP_SESSION_SETUP_DATA(qctx->session_data); DEBUG("session_ctx = %p\n", qctx->session_ctx); if (!(is_instance_available(qctx->inst_num))) { WARN("No QAT instance available so not initialising session.\n"); if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Failed to get an instance - fallback to SW - %s\n", __func__); qctx->fallback = 1; goto fallback; } WARN("Fail - No QAT instance available and s/w fallback is not enabled.\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_NO_QAT_INSTANCE_AVAILABLE); return -1; /* Fail if software fallback not enabled. */ } sts = cpaCySymInitSession(qat_instance_handles[qctx->inst_num], qat_sm4_cbc_cb, qctx->session_data, qctx->session_ctx); if (sts != CPA_STATUS_SUCCESS) { WARN("cpaCySymInitSession failed! Status = %d\n", sts); if (qat_get_sw_fallback_enabled() && ((sts == CPA_STATUS_RESTARTING) || (sts == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qctx->fallback = 1; goto fallback; } WARN("cpaCySymInitSession failed and cannot fallback to SW\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_QAT_INITSESSION_FAILED); return -1; } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } INIT_SM4_SET_FLAG(qctx, INIT_SM4_QAT_SESSION_INIT); } #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (len <= qat_pkt_threshold_table_get_threshold(nid)) { # ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); retVal = EVP_CIPHER_meth_get_do_cipher(EVP_sm4_cbc())(ctx, out, in, len); if (retVal) outlen = len; # ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sm4_cbc_coexist) { EVP_CIPHER_CTX_set_cipher_data(ctx, sm4cbc_hw_sw_ctx); } else { EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); } # else EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); # endif # else sw_sm4_cbc_cipher = get_default_cipher_sm4_cbc(); if (sw_sm4_cbc_cipher.cupdate == NULL) return 0; if (in != NULL) { retVal = sw_sm4_cbc_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, len); *outl = len; } else { retVal = sw_sm4_cbc_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); *outl = len; } if (retVal) outlen = 1; # endif goto cleanup; } #endif DEBUG("[%p] Start Cipher operation.\n", ctx); tlv = qat_check_create_local_variables(); if (NULL == tlv) { WARN("could not create local variables\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_NULL_POINTER); return -1; } if (qat_setup_op_params(ctx) != 1) { WARN("Failure in qat_setup_op_params.\n"); return -1; } qat_init_op_done(&op_done); if (op_done.job != NULL) { if (qat_setup_async_event_notification(op_done.job) == 0) { WARN("Failure to setup async event notifications\n"); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, ERR_R_INTERNAL_ERROR); qat_cleanup_op_done(&op_done); return -1; } } opd = &qctx->op->op_data; s_fbuf = &qctx->op->src_fbuf; d_fbuf = &qctx->op->dst_fbuf; s_sgl = &qctx->op->src_sgl; d_sgl = &qctx->op->dst_sgl; #ifndef QAT_OPENSSL_PROVIDER memcpy(opd->pIv, EVP_CIPHER_CTX_iv(ctx), ivlen); #else memcpy(opd->pIv, ctx->iv, ivlen); #endif opd->messageLenToCipherInBytes = len; if (!qctx->qat_svm) { FLATBUFF_ALLOC_AND_CHAIN(*s_fbuf, *d_fbuf, len); } else { s_fbuf->pData = (Cpa8U *)in; d_fbuf->pData = s_fbuf->pData; s_fbuf->dataLenInBytes = len; d_fbuf->dataLenInBytes = len; } if ((s_fbuf->pData) == NULL) { WARN("Src buffer is not allocated.\n"); error = 1; goto end; } if (!qctx->qat_svm) memcpy(d_fbuf->pData, in, len); DUMP_SYM_PERFORM_OP(qat_instance_handles[qctx->inst_num], opd, s_sgl, d_sgl); sts = qat_sym_perform_op(qctx->inst_num, &op_done, opd, s_sgl, d_sgl, NULL); /* QAT_HW return retry, 16 requests will switche to QAT SW to be processed. */ #if defined(ENABLE_QAT_SW_SM4_CBC) && !defined(QAT_OPENSSL_PROVIDER) if (qat_sm4_cbc_coexist && (sts == CPA_STATUS_RETRY)) { DEBUG("Qat retry occurred.\n"); qaeCryptoMemFreeNonZero(qctx->op->src_fbuf.pData); qctx->op->src_fbuf.pData = NULL; qctx->op->dst_fbuf.pData = NULL; qat_sw_sm4_cbc_cipher_req--; return qat_sw_sm4_cbc_cipher(ctx, out, in, len); } #endif if (sts != CPA_STATUS_SUCCESS) { if (qat_get_sw_fallback_enabled() && ((sts == CPA_STATUS_RESTARTING) || (sts == CPA_STATUS_FAIL))) { CRYPTO_QAT_LOG("Failed to submit request to qat inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qctx->fallback = 1; } WARN("Failed to submit request to qat - status = %d\n", sts); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED); error = 1; goto end; } if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); } QAT_INC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); if (qat_use_signals()) { if (tlv->localOpsInFlight == 1) { if (sem_post(&hw_polling_thread_sem) != 0) { WARN("hw sem_post failed!, hw_polling_thread_sem address: %p.\n", &hw_polling_thread_sem); QATerr(QAT_F_QAT_SM4_CBC_DO_CIPHER, QAT_R_SM4_QAT_SUBMIT_REQUEST_FAILED); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); return -1; } } } if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_cipher_pipeline_requests_in_flight); } if (qat_sm4_cbc_coexist) { ++num_sm4_cbc_hw_cipher_reqs; } do { if (op_done.job != NULL) { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(op_done.job, ASYNC_STATUS_OK)) == 0) sched_yield(); } else { sched_yield(); } } while (!op_done.flag || QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); end: DUMP_SYM_PERFORM_OP_OUTPUT(&(qctx->session_data->verifyDigest), d_sgl); if (error == 0) { #ifndef QAT_OPENSSL_PROVIDER retVal = 1; outlen = len; #else *outl = len; outlen = 1; #endif if (!qctx->qat_svm) memcpy(out, qctx->op->dst_fbuf.pData, len); else qctx->op->dst_fbuf.pData = (Cpa8U *)out; } else { if (qat_get_sw_fallback_enabled() && op_done.verifyResult == CPA_FALSE) { CRYPTO_QAT_LOG("Verification of result failed for qat \ inst_num %d device_id %d - fallback to SW - %s\n", qctx->inst_num, qat_instance_details[qctx->inst_num].qat_instance_info.physInstId.packageId, __func__); qctx->fallback = 1; /* Probably already set anyway */ } if (op_done.job != NULL) { qat_clear_async_event_notification(op_done.job); } } qat_cleanup_op_done(&op_done); if (!qctx->qat_svm) qaeCryptoMemFreeNonZero(qctx->op->src_fbuf.pData); qctx->op->src_fbuf.pData = NULL; qctx->op->dst_fbuf.pData = NULL; if (enc) { #ifndef QAT_OPENSSL_PROVIDER memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), out + len - ivlen, ivlen); #else memcpy(ctx->iv, out + len - ctx->ivlen, ctx->ivlen); #endif DEBUG("Encryption succeeded.\n"); } else { DEBUG("Decryption succeeded.\n"); } #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD cleanup: #endif fallback: if (qctx->fallback == 1) { DEBUG("- Switched to OpenSSL SW mode.\n"); CRYPTO_QAT_LOG("Resubmitting request to OpenSSL SW - %s\n", __func__); #ifndef QAT_OPENSSL_PROVIDER EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); retVal = EVP_CIPHER_meth_get_do_cipher(EVP_sm4_cbc())(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); if (retVal) outlen = len; #else sw_sm4_cbc_cipher = get_default_cipher_sm4_cbc(); if (sw_sm4_cbc_cipher.cupdate == NULL) return 0; if (in != NULL) { retVal = sw_sm4_cbc_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, len); *outl = len; } else { retVal = sw_sm4_cbc_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); *outl = len; } if (retVal) outlen = 1; #endif } return outlen; } #endif /* ENABLE_QAT_HW_SM4_CBC */ qatengine-1.9.0/qat_hw_sm4_cbc.h000066400000000000000000000126221500416242000165170ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_sm4_cbc.h * * This file provides an interface for engine SM4-CBC operations * *****************************************************************************/ #ifndef QAT_HW_SM4_CBC_H # define QAT_HW_SM4_CBC_H #ifdef QAT_HW #ifndef SM4_BLOCK_SIZE # define SM4_BLOCK_SIZE 16 #endif # ifdef ENABLE_QAT_HW_SM4_CBC # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" #ifdef ENABLE_QAT_SW_SM4_CBC # include "qat_sw_sm4_cbc.h" #endif #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_sm4_cbc.h" #endif #ifndef SM4_KEY_SIZE # define SM4_KEY_SIZE 16 #endif # define SM4_CBC_IV_LEN 16 # define INIT_SM4_QAT_CTX_INIT 0x0001 # define INIT_SM4_QAT_SESSION_INIT 0x0002 # define SM4_CBC_COEXIST_QAT_SW_MIN_PKT_LEN 256 # define SM4_CBC_COEXIST_QAT_SW_MAX_PKT_LEN 1024 # define QAT_COMMON_CIPHER_FLAG EVP_CIPH_FLAG_DEFAULT_ASN1 # define QAT_CBC_FLAGS (QAT_COMMON_CIPHER_FLAG | \ EVP_CIPH_CBC_MODE | \ EVP_CIPH_CUSTOM_IV) # define qat_sm4_get_cipher_data(ctx) \ ((qat_sm4_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx)) # define INIT_SM4_CLEAR_ALL_FLAGS(qctx) ((qctx)->init_flags = 0) # define INIT_SM4_SET_FLAG(qctx, f) ((qctx)->init_flags |= (f)) # define INIT_SM4_CLEAR_FLAG(qctx, f) ((qctx)->init_flags &= ~(f)) # define INIT_SM4_IS_FLAG_SET(qctx,f) ((qctx)->init_flags & (f)) typedef struct qat_sm4_op_params_t { CpaCySymOpData op_data; CpaBufferList src_sgl; CpaBufferList dst_sgl; CpaFlatBuffer src_fbuf; CpaFlatBuffer dst_fbuf; } qat_sm4_op_params; typedef struct qat_sm4_ctx_t { /* Pointer to context cipher data (ctx->cipher_data) that will be used by * Small packet offload feature and the s/w fallback feature. */ void *sw_ctx_cipher_data; /* QAT Session Params */ int inst_num; int qat_svm; CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx session_ctx; int init_flags; qat_sm4_op_params *op; unsigned int fallback; } qat_sm4_ctx; #ifdef ENABLE_QAT_SW_SM4_CBC typedef struct { qat_sm4_ctx sm4cbc_qat_hw_ctx; SM4_CBC_CTX sm4cbc_qat_sw_ctx; } sm4cbc_coexistence_ctx; #endif extern CpaStatus qat_sym_perform_op(int inst_num, void *pCallbackTag, const CpaCySymOpData * pOpData, const CpaBufferList * pSrcBuffer, CpaBufferList * pDstBuffer, CpaBoolean * pVerifyResult); # ifdef QAT_OPENSSL_PROVIDER int qat_sm4_cbc_init(QAT_PROV_CBC_CTX *ctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_sm4_cbc_cleanup(QAT_PROV_CBC_CTX *ctx); int qat_sm4_cbc_do_cipher(QAT_PROV_CBC_CTX *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t len); # else int qat_sm4_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char *inkey, const unsigned char *iv, int enc); int qat_sm4_cbc_cleanup(EVP_CIPHER_CTX *ctx); int qat_sm4_cbc_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); # endif # endif /* ENABLE_QAT_HW_SM4_CBC */ # endif /* QAT_HW */ #endif /* QAT_HW_SM4_H */ qatengine-1.9.0/qat_hw_usdm_inf.c000066400000000000000000000133651500416242000170110ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file cmn_mem_drv_inf.c * * This file provides an interface to use a memory driver to provide contig * pinned memory. * *****************************************************************************/ #include #include #include #include "qat_utils.h" #include "qat_hw_usdm_inf.h" #include "qae_mem.h" #define unlikely(x) __builtin_expect (!!(x), 0) static int crypto_inited = 0; static void crypto_init(void) { MEM_WARN("Memory Driver Warnings Enabled.\n"); MEM_DEBUG("Memory Driver Debug Enabled.\n"); crypto_inited = 1; } void qaeCryptoMemFree(void *ptr) { MEM_DEBUG("Address: %p\n", ptr); if (unlikely(NULL == ptr)) { MEM_WARN("qaeCryptoMemFree trying to free NULL pointer.\n"); return; } qaeMemFreeNUMA(&ptr); } void qaeCryptoMemFreeNonZero(void *ptr) { MEM_DEBUG("Address: %p\n", ptr); if (unlikely(NULL == ptr)) { MEM_WARN("qaeCryptoMemFreeNonZero trying to free NULL pointer.\n"); return; } #ifdef QAT_HW_DISABLE_NONZERO_MEMFREE qaeMemFreeNUMA(&ptr); #else qaeMemFreeNonZeroNUMA(&ptr); #endif } void *qaeCryptoMemAlloc(size_t memsize, const char *file, int line) { /* Input params should already have been sanity-checked by calling function. */ void *pAddress = NULL; if (!crypto_inited) crypto_init(); pAddress = qaeMemAllocNUMA(memsize, NUMA_ANY_NODE, QAT_BYTE_ALIGNMENT); MEM_DEBUG("Address: %p Size: %zd File: %s:%d\n", pAddress, memsize, file, line); return pAddress; } void *qaeCryptoMemRealloc(void *ptr, size_t memsize, const char *file, int line) { void *nptr; /* copyAllocPinnedMemory() will check the input params. */ nptr = copyAllocPinnedMemory(ptr, memsize, file, line); if (nptr) qaeCryptoMemFree(ptr); return nptr; } void *qaeCryptoMemReallocClean(void *ptr, size_t memsize, size_t original_size, const char *file, int line) { void *nptr; /* copyAllocPinnedMemoryClean() checks the input params. */ nptr = copyAllocPinnedMemoryClean(ptr, memsize, original_size, file, line); if (nptr) qaeCryptoMemFree(ptr); return nptr; } void *copyAllocPinnedMemory(void *ptr, size_t size, const char *file, int line) { void *nptr; if (unlikely((ptr == NULL) || (size == 0) || (file == NULL) || ((nptr = qaeCryptoMemAlloc(size, file, line)) == NULL))) { MEM_WARN("Pinned memory allocation failure\n"); return NULL; } memcpy(nptr, ptr, size); return nptr; } void *copyAllocPinnedMemoryClean(void *ptr, size_t size, size_t original_size, const char *file, int line) { void *nptr; if (unlikely((ptr == NULL) || (size == 0) || (original_size == 0) || (file == NULL))) { MEM_WARN("Invalid input params.\n"); return NULL; } if (original_size > size) { MEM_WARN("original_size : %zd > size : %zd", original_size, size); return NULL; } if ((nptr = qaeCryptoMemAlloc(size, file, line)) == NULL) { MEM_WARN("Clean pinned memory allocation failure\n"); return NULL; } memcpy(nptr, ptr, original_size); return nptr; } int copyFreePinnedMemory(void *uptr, void *kptr, int size) { if (uptr == NULL || kptr == NULL || size <= 0) { MEM_WARN("Input pointers uptr or kptr are NULL, or size invalid.\n"); return 0; } memcpy(uptr, kptr, size); qaeCryptoMemFree(kptr); return 1; } CpaPhysicalAddr qaeCryptoMemV2P(void *v) { if (v == NULL) { MEM_WARN("NULL address passed to function\n"); return (CpaPhysicalAddr)0; } return qaeVirtToPhysNUMA(v); } void qaeCryptoAtFork() { qaeAtFork(); } qatengine-1.9.0/qat_hw_usdm_inf.h000066400000000000000000000103441500416242000170100ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_hw_usdm_inf.h * * This file provides an interface to USDM memory driver that supplies contig * pinned memory. * *****************************************************************************/ #ifndef USDM_MEM_DRV_INF_H # define USDM_MEM_DRV_INF_H # include # include # include "cpa.h" extern FILE* qatDebugLogFile; #ifdef QAT_MEM_DEBUG # define MEM_DEBUG(fmt_str, ...) \ do { \ fprintf(qatDebugLogFile,"[MEM_DEBUG][%s:%d:%s()] "fmt_str, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while(0) #else # define MEM_DEBUG(...) #endif # define MEM_ERROR(fmt_str, ...) \ do { \ fprintf(qatDebugLogFile,"[MEM_ERROR][%s:%d:%s()] "fmt_str, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while(0) #if defined(QAT_MEM_WARN) || defined(QAT_MEM_DEBUG) # define MEM_WARN(fmt_str, ...) \ do { \ fprintf(qatDebugLogFile,"[MEM_WARN][%s:%d:%s()] "fmt_str, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while(0) #else # define MEM_WARN(...) #endif void qaeCryptoMemFree(void *ptr); void qaeCryptoMemFreeNonZero(void *ptr); void *qaeCryptoMemAlloc(size_t memsize, const char *file, int line); void *qaeCryptoMemRealloc(void *ptr, size_t memsize, const char *file, int line); void *qaeCryptoMemReallocClean(void *ptr, size_t memsize, size_t original_size, const char *file, int line); CpaPhysicalAddr qaeCryptoMemV2P(void *v); void qaeCryptoAtFork(); void *copyAllocPinnedMemory(void *ptr, size_t size, const char *file, int line); void *copyAllocPinnedMemoryClean(void *ptr, size_t size, size_t original_size, const char *file, int line); int copyFreePinnedMemory(void *uptr, void *kptr, int size); #endif /* USDM_MEM_DRV_INF_H */ qatengine-1.9.0/qat_prov_aes_ccm.c000066400000000000000000000610371500416242000171460ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2024-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @qat_prov_aes_ccm.c * * This file contains the qatprovider implementation for AES-CCM operations * *****************************************************************************/ #include "qat_provider.h" #include "qat_prov_aes_ccm.h" #include "qat_utils.h" #include "e_qat.h" #include "qat_evp.h" #ifdef ENABLE_QAT_HW_CCM # include "qat_hw_ccm.h" #endif #define AES_CCM_IV_MIN_SIZE (64 / 8) #define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) #define QAT_AES_CCM_OP_VALUE 15 #ifdef ENABLE_QAT_HW_CCM static OSSL_FUNC_cipher_freectx_fn qat_aes_ccm_freectx; void qat_aes_ccm_init_ctx(void *provctx, QAT_PROV_CCM_CTX * ctx, size_t keybits, size_t ivlen_min) { ctx->keylen = keybits / 8; ctx->key_set = 0; ctx->iv_set = 0; ctx->tag_set = 0; ctx->len_set = 0; ctx->L = 8; ctx->M = 12; ctx->tls_aad_len = -1; ctx->pad = 1; ctx->mode = EVP_CIPH_CCM_MODE; ctx->tag_len = -1; ctx->ivlen_min = ivlen_min; ctx->libctx = prov_libctx_of(provctx); ctx->iv_len = (EVP_CCM_TLS_FIXED_IV_LEN + EVP_CCM_TLS_EXPLICIT_IV_LEN); } const char *qat_ccm_cipher_name(int nid) { switch (nid) { case NID_aes_128_ccm: return LN_aes_128_ccm; case NID_aes_192_ccm: return LN_aes_192_ccm; case NID_aes_256_ccm: return LN_aes_256_ccm; default: WARN("Invalid nid %d\n", nid); return NULL; } } QAT_EVP_CIPHER get_default_cipher_aes_ccm(int nid) { static QAT_EVP_CIPHER ccm_cipher; static int initialized = 0; if (!initialized) { QAT_EVP_CIPHER *cipher = (QAT_EVP_CIPHER *) EVP_CIPHER_fetch(NULL, qat_ccm_cipher_name(nid), "provider=default"); if (cipher) { ccm_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initialized = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return ccm_cipher; } static int qat_aes_ccm_tls_init(QAT_PROV_CCM_CTX *ctx, unsigned char *aad, size_t alen) { size_t len; if (!qat_prov_is_running() || alen != EVP_AEAD_TLS1_AAD_LEN) return 0; /* Save the aad for later use. */ memcpy(ctx->buf, aad, alen); ctx->tls_aad_len = alen; len = ctx->buf[alen - 2] << 8 | ctx->buf[alen - 1]; if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN) return 0; /* Correct length for explicit iv. */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; if (!ctx->enc) { if (len < ctx->M) return 0; /* Correct length for tag. */ len -= ctx->M; } ctx->buf[alen - 2] = (unsigned char)(len >> 8); ctx->buf[alen - 1] = (unsigned char)(len & 0xff); /* Extra padding: tag appended to record. */ return ctx->M; } static void *qat_aes_ccm_newctx(void *provctx, size_t keybits, int nid) { QAT_PROV_AES_CCM_CTX *ctx = NULL; QAT_EVP_CIPHER *cipher; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); cipher = OPENSSL_zalloc(sizeof(QAT_EVP_CIPHER)); cipher->nid = nid; ctx->cipher = cipher; ctx->base.nid = nid; if (ctx != NULL) { qat_aes_ccm_init_ctx(provctx, &ctx->base, keybits, AES_CCM_IV_MIN_SIZE); } return ctx; } size_t qat_aes_ccm_get_ivlen(QAT_PROV_CCM_CTX * ctx) { return QAT_AES_CCM_OP_VALUE - ctx->L; } int qat_aes_ccm_einit(void *vctx, const unsigned char *inkey, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM param[]) { int sts = 0; QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; ctx->enc = 1; # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; # ifdef QAT_INSECURE_ALGO if (qctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; if (qctx->nid != NID_aes_256_ccm) goto end; # endif # endif if (qat_hw_aes_ccm_offload) { sts = qat_aes_ccm_init(ctx, inkey, keylen, iv, ivlen, 1); if (sts != 1) { QATerr(ERR_LIB_PROV, QAT_R_EINIT_OPERATION_FAILED); return sts; } } return qat_aes_ccm_set_ctx_params(ctx, param); # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(qctx->nid); if (qctx->sw_ctx || (qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx))) return sw_aes_ccm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); return 0; #endif } int qat_aes_ccm_dinit(void *vctx, const unsigned char *inkey, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM param[]) { int sts = 0; QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; ctx->enc = 0; # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; # ifdef QAT_INSECURE_ALGO if (qctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; if (qctx->nid != NID_aes_256_ccm) goto end; # endif # endif if (qat_hw_aes_ccm_offload) { sts = qat_aes_ccm_init(ctx, inkey, keylen, iv, ivlen, 0); if (sts != 1) { QATerr(ERR_LIB_PROV, QAT_R_DINIT_OPERATION_FAILED); return sts; } } return qat_aes_ccm_set_ctx_params(ctx, param); # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(qctx->nid); if (!qctx->sw_ctx) qctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); sts = sw_aes_ccm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); if (sts != 1) return 0; return sts; #endif } int qat_aes_ccm_stream_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; if (inl == 0) { *outl = 0; return 1; } if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) # ifdef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_256_ccm) goto end; # endif # endif if (qat_hw_aes_ccm_offload) { if ((qat_aes_ccm_cipher(ctx, out, outl, outsize, in, inl)) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); return 0; } } else { /* Set *outl to NULL when offload is disabled to avoid garbage values and prevent errors. */ *outl = 0; } return 1; # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); if (sw_aes_ccm_cipher.cupdate == NULL) return 0; if (sw_aes_ccm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) return 0; return 1; #endif } int qat_aes_ccm_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { int i = 0; QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; if (!qat_prov_is_running()) return 0; # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) # ifdef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_256_ccm) goto end; # endif # endif if (qat_hw_aes_ccm_offload) { i = qat_aes_ccm_cipher(ctx, out, outl, outsize, NULL, 0); if (i <= 0) return 0; } *outl = 0; return 1; # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); if (sw_aes_ccm_cipher.cfinal == NULL) return 0; i = sw_aes_ccm_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); *outl = 0; return 1; #endif } int qat_aes_ccm_do_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; if (!qat_prov_is_running()) return 0; if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) # ifdef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_256_ccm) goto end; # endif # endif if (qat_hw_aes_ccm_offload) { if (qat_aes_ccm_cipher(ctx, out, outl, outsize, in, inl) <= 0) { return 0; } } *outl = inl; return 1; # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); if (sw_aes_ccm_cipher.cupdate == NULL) return 0; if (sw_aes_ccm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) return 0; return 1; #endif } int qat_aes_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]) { QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; OSSL_PARAM *p; # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) # ifdef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_256_ccm) goto end; # endif # endif p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, qat_aes_ccm_get_ivlen(ctx))) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); if (p != NULL) { size_t m = ctx->M; if (!OSSL_PARAM_set_size_t(p, m)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL) { if (qat_aes_ccm_get_ivlen(ctx) > p->data_size) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (qat_aes_ccm_get_ivlen(ctx) > p->data_size) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (!ctx->enc) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); return 0; } if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } memcpy(p->data, ctx->buf, p->data_size); ctx->iv_set = 0; ctx->len_set = 0; if (ctx->tag_set) { ctx->tag_set = 0; return 1; } } if (ctx->sw_ctx) { QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); sw_aes_ccm_cipher.get_ctx_params(ctx->sw_ctx, params); } return 1; # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); if (ctx->sw_ctx || (ctx->sw_ctx = sw_aes_ccm_cipher.newctx(ctx))) return sw_aes_ccm_cipher.get_ctx_params(ctx->sw_ctx, params); return 0; #endif } int qat_aes_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; const OSSL_PARAM *p; size_t sz = 0; if (params == NULL) return 1; # if !defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) # ifdef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_128_ccm) goto end; # else goto end; # endif # else # ifndef QAT_INSECURE_ALGO if (ctx->nid != NID_aes_256_ccm) goto end; # endif # endif p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if ((p->data_size & 1) || (p->data_size < 4) || p->data_size > 16) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); return 0; } if (p->data != NULL) { if (ctx->enc) { QATerr(ERR_LIB_PROV, QAT_R_TAG_NOT_NEEDED); return 0; } memcpy(ctx->buf, p->data, p->data_size); ctx->tag_set = 1; } ctx->M = p->data_size; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); if (p != NULL) { size_t ivlen; if (!OSSL_PARAM_get_size_t(p, &sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } ivlen = QAT_AES_CCM_OP_VALUE - sz; if (ivlen < 2 || ivlen > 8) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (ctx->L != ivlen) { ctx->L = ivlen; ctx->iv_set = 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if (qat_hw_aes_ccm_offload) sz = qat_aes_ccm_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data); else sz = qat_aes_ccm_tls_init(ctx, p->data, p->data_size); if (sz == 0) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_DATA); return 0; } ctx->tls_aad_pad_sz = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if (qat_hw_aes_ccm_offload) { if (qat_aes_ccm_ctrl (ctx, EVP_CTRL_CCM_SET_IV_FIXED, p->data_size, p->data) == 0) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } } } if (ctx->sw_ctx) { QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); sw_aes_ccm_cipher.set_ctx_params(ctx->sw_ctx, params); } return 1; # if (!defined(QAT20_OOT) && !defined(QAT_HW_INTREE) \ && !defined(QAT_HW_FBSD_OOT) && !defined(QAT_HW_FBSD_INTREE) \ && defined(QAT_INSECURE_ALGO)) || !defined(QAT_INSECURE_ALGO) end: if (ctx->sw_ctx) { QAT_EVP_CIPHER sw_aes_ccm_cipher = get_default_cipher_aes_ccm(ctx->nid); return sw_aes_ccm_cipher.set_ctx_params(ctx->sw_ctx, params); } return 0; #endif } int qat_aes_ccm_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static void qat_aes_ccm_freectx(void *vctx) { QAT_PROV_AES_CCM_CTX *ctx = (QAT_PROV_AES_CCM_CTX *) vctx; if (ctx != NULL) { if (ctx->cipher) { OPENSSL_free(ctx->cipher); ctx->cipher = NULL; } if (qat_hw_aes_ccm_offload) qat_aes_ccm_cleanup(&ctx->base); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } static const OSSL_PARAM qat_aes_ccm_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_aes_ccm_generic_gettable_params(ossl_unused void *provctx) { return qat_aes_ccm_known_gettable_params; } static const OSSL_PARAM qat_aes_ccm_aead_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_aes_ccm_aead_gettable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_aes_ccm_aead_known_gettable_ctx_params; } static const OSSL_PARAM qat_aes_ccm_aead_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_aes_ccm_aead_settable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_aes_ccm_aead_known_settable_ctx_params; } /* qat_aes_128_ccm_functions */ QAT_aes_cipher(qat_aes, ccm, CCM, AEAD_FLAGS, 128, 8, 96, NID_aes_128_ccm); /* qat_aes_192_ccm_functions */ QAT_aes_cipher(qat_aes, ccm, CCM, AEAD_FLAGS, 192, 8, 96, NID_aes_192_ccm); /* qat_aes_256_ccm_functions */ QAT_aes_cipher(qat_aes, ccm, CCM, AEAD_FLAGS, 256, 8, 96, NID_aes_256_ccm); #endif /* ENABLE_QAT_HW_CCM */ qatengine-1.9.0/qat_prov_aes_ccm.h000066400000000000000000000300641500416242000171470ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2024-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_aes_ccm.h * * This file provides an interface to QAT provider AES-CCM operations * *****************************************************************************/ #ifndef QAT_PROV_AES_CCM_H # define QAT_PROV_AES_CCM_H # ifdef ENABLE_QAT_HW_CCM # include # include # include # include # include # include # include # include # include # include # include "qat_utils.h" # include "e_qat.h" # include "qat_hw_ccm.h" # define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ # define QAT_AES_BLOCK_SIZE 16 # define PROV_CIPHER_FLAG_AEAD 0x0001 # define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 # define PROV_CIPHER_FLAG_CTS 0x0004 # define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 # define PROV_CIPHER_FLAG_RAND_KEY 0x0010 typedef struct qat_evp_cipher_st { int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup)(EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; } QAT_EVP_CIPHER; # pragma pack(push, 16) typedef struct qat_ccm_ctx_st { int inst_num; CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx qat_ctx; int init_params_set; /* This flag is set to 1 when the session has been initialized */ int is_session_init; /* QAT Op Params */ CpaCySymOpData OpData; CpaBufferList srcBufferList; CpaBufferList dstBufferList; CpaFlatBuffer srcFlatBuffer; CpaFlatBuffer dstFlatBuffer; /* -- Crypto -- */ /* Pointer to AAD. * In the TLS case this will contain the TLS header */ Cpa8U *aad; /* Size of the meta data for the driver * It cannot allocate memory so this must be done by the user application */ unsigned int meta_size; /* Pointer to pCipherKey */ Cpa8U *cipher_key; /* Flag to keep track of key passed */ int key_set; int qat_svm; int tls_aad_len; int tag_len; int iv_len; unsigned int iv_set; int iv_gen; Cpa8U next_iv[EVP_MAX_IV_LENGTH]; unsigned char *iv; unsigned int mode; /* The mode that we are using */ size_t keylen; size_t ivlen_min; size_t tls_aad_pad_sz; uint64_t tls_enc_records; /* Number of TLS records encrypted */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ size_t num; size_t bufsz; /* Number of bytes in buf */ unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */ unsigned int pad:1; /* Whether padding should be used or not */ unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ unsigned char buf[QAT_AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ OSSL_LIB_CTX *libctx; /* needed for rand calls */ ctr128_f ctr; size_t L, M; int tag_set, len_set; int packet_size; int nid; void *sw_ctx_cipher_data; EVP_CIPHER_CTX *sw_ctx; QAT_EVP_CIPHER *sw_cipher; } QAT_PROV_CCM_CTX; # pragma pack(pop) struct evp_cipher_ctx_st { const EVP_CIPHER *cipher; ENGINE *engine; /* functional reference if 'cipher' is * ENGINE-provided */ int encrypt; /* encrypt or decrypt */ int buf_len; /* number we have left */ unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ int num; /* used by cfb/ofb/ctr mode */ void *app_data; /* application stuff */ int key_len; /* May change for variable length cipher */ unsigned long flags; /* Various flags */ void *cipher_data; /* per EVP data */ int final_used; int block_mask; unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ /* * Opaque ctx returned from a providers cipher algorithm implementation * OSSL_FUNC_cipher_newctx() */ void *algctx; EVP_CIPHER *fetched_cipher; } /* EVP_CIPHER_CTX */ ; typedef struct prov_aes_ccm_ctx_st { QAT_PROV_CCM_CTX base; /* must be first entry in struct */ QAT_EVP_CIPHER *cipher; } QAT_PROV_AES_CCM_CTX; size_t qat_aes_ccm_get_ivlen(QAT_PROV_CCM_CTX * ctx); void qat_aes_ccm_init_ctx(void *provctx, QAT_PROV_CCM_CTX * ctx, size_t keybits, size_t ivlen_min); int qat_aes_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]); int qat_aes_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]); int qat_aes_ccm_einit(void *ctx, const unsigned char *inkey, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]); int qat_aes_ccm_dinit(void *ctx, const unsigned char *inkey, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]); int qat_aes_ccm_stream_update(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); int qat_aes_ccm_stream_final(void *ctx, unsigned char *out, size_t *outl, size_t outsize); int qat_aes_ccm_do_cipher(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); const char *qat_ccm_cipher_name(int nid); QAT_EVP_CIPHER get_default_cipher_aes_ccm(int nid); # define QAT_aes_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits,nid) \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ return qat_aes_ccm_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lc##_newctx; \ static void *alg##_##kbits##_##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits, nid); \ } \ const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##_##kbits##_##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))alg##_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))alg##_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))alg##_##lc##_stream_update }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))alg##_##lc##_stream_final }, \ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))alg##_##lc##_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))alg##_##lc##_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))alg##_##lc##_aead_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))alg##_##lc##_aead_settable_ctx_params }, \ { 0, NULL } \ } # endif /* ENABLE_QAT_HW_CCM */ #endif /* QAT_PROV_AES_CCM_H */ qatengine-1.9.0/qat_prov_bio.c000066400000000000000000000147571500416242000163340ustar00rootroot00000000000000#include #include #include #include "qat_prov_bio.h" static OSSL_FUNC_BIO_new_file_fn *c_bio_new_file = NULL; static OSSL_FUNC_BIO_new_membuf_fn *c_bio_new_membuf = NULL; static OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex = NULL; static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex = NULL; static OSSL_FUNC_BIO_gets_fn *c_bio_gets = NULL; static OSSL_FUNC_BIO_puts_fn *c_bio_puts = NULL; static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl = NULL; static OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref = NULL; static OSSL_FUNC_BIO_free_fn *c_bio_free = NULL; static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf = NULL; int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) { for (; fns->function_id != 0; fns++) { switch (fns->function_id) { case OSSL_FUNC_BIO_NEW_FILE: if (c_bio_new_file == NULL) c_bio_new_file = OSSL_FUNC_BIO_new_file(fns); break; case OSSL_FUNC_BIO_NEW_MEMBUF: if (c_bio_new_membuf == NULL) c_bio_new_membuf = OSSL_FUNC_BIO_new_membuf(fns); break; case OSSL_FUNC_BIO_READ_EX: if (c_bio_read_ex == NULL) c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns); break; case OSSL_FUNC_BIO_WRITE_EX: if (c_bio_write_ex == NULL) c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns); break; case OSSL_FUNC_BIO_GETS: if (c_bio_gets == NULL) c_bio_gets = OSSL_FUNC_BIO_gets(fns); break; case OSSL_FUNC_BIO_PUTS: if (c_bio_puts == NULL) c_bio_puts = OSSL_FUNC_BIO_puts(fns); break; case OSSL_FUNC_BIO_CTRL: if (c_bio_ctrl == NULL) c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns); break; case OSSL_FUNC_BIO_UP_REF: if (c_bio_up_ref == NULL) c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns); break; case OSSL_FUNC_BIO_FREE: if (c_bio_free == NULL) c_bio_free = OSSL_FUNC_BIO_free(fns); break; case OSSL_FUNC_BIO_VPRINTF: if (c_bio_vprintf == NULL) c_bio_vprintf = OSSL_FUNC_BIO_vprintf(fns); break; } } return 1; } OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode) { if (c_bio_new_file == NULL) return NULL; return c_bio_new_file(filename, mode); } OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len) { if (c_bio_new_membuf == NULL) return NULL; return c_bio_new_membuf(filename, len); } int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len, size_t *bytes_read) { if (c_bio_read_ex == NULL) return 0; return c_bio_read_ex(bio, data, data_len, bytes_read); } int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len, size_t *written) { if (c_bio_write_ex == NULL) return 0; return c_bio_write_ex(bio, data, data_len, written); } int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size) { if (c_bio_gets == NULL) return -1; return c_bio_gets(bio, buf, size); } int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str) { if (c_bio_puts == NULL) return -1; return c_bio_puts(bio, str); } int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr) { if (c_bio_ctrl == NULL) return -1; return c_bio_ctrl(bio, cmd, num, ptr); } int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio) { if (c_bio_up_ref == NULL) return 0; return c_bio_up_ref(bio); } int ossl_prov_bio_free(OSSL_CORE_BIO *bio) { if (c_bio_free == NULL) return 0; return c_bio_free(bio); } int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap) { if (c_bio_vprintf == NULL) return -1; return c_bio_vprintf(bio, format, ap); } int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...) { va_list ap; int ret; va_start(ap, format); ret = ossl_prov_bio_vprintf(bio, format, ap); va_end(ap); return ret; } #ifndef FIPS_MODULE /* No direct BIO support in the FIPS module */ static int bio_core_read_ex(BIO *bio, char *data, size_t data_len, size_t *bytes_read) { return ossl_prov_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read); } static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len, size_t *written) { return ossl_prov_bio_write_ex(BIO_get_data(bio), data, data_len, written); } static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr) { return ossl_prov_bio_ctrl(BIO_get_data(bio), cmd, num, ptr); } static int bio_core_gets(BIO *bio, char *buf, int size) { return ossl_prov_bio_gets(BIO_get_data(bio), buf, size); } static int bio_core_puts(BIO *bio, const char *str) { return ossl_prov_bio_puts(BIO_get_data(bio), str); } static int bio_core_new(BIO *bio) { BIO_set_init(bio, 1); return 1; } BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(QAT_PROV_CTX *ctx) { if (ctx == NULL) return NULL; return ctx->corebiometh; } static int bio_core_free(BIO *bio) { BIO_set_init(bio, 0); ossl_prov_bio_free(BIO_get_data(bio)); return 1; } BIO_METHOD *ossl_bio_prov_init_bio_method(void) { BIO_METHOD *corebiometh = NULL; corebiometh = BIO_meth_new(BIO_TYPE_CORE_TO_PROV, "BIO to Core filter"); if (corebiometh == NULL || !BIO_meth_set_write_ex(corebiometh, bio_core_write_ex) || !BIO_meth_set_read_ex(corebiometh, bio_core_read_ex) || !BIO_meth_set_puts(corebiometh, bio_core_puts) || !BIO_meth_set_gets(corebiometh, bio_core_gets) || !BIO_meth_set_ctrl(corebiometh, bio_core_ctrl) || !BIO_meth_set_create(corebiometh, bio_core_new) || !BIO_meth_set_destroy(corebiometh, bio_core_free)) { BIO_meth_free(corebiometh); return NULL; } return corebiometh; } BIO *ossl_bio_new_from_core_bio(QAT_PROV_CTX *provctx, OSSL_CORE_BIO *corebio) { BIO *outbio; BIO_METHOD *corebiometh = ossl_prov_ctx_get0_core_bio_method(provctx); if (corebiometh == NULL) return NULL; if ((outbio = BIO_new(corebiometh)) == NULL) return NULL; if (!ossl_prov_bio_up_ref(corebio)) { BIO_free(outbio); return NULL; } BIO_set_data(outbio, corebio); return outbio; } #endif qatengine-1.9.0/qat_prov_bio.h000066400000000000000000000022531500416242000163250ustar00rootroot00000000000000#include #include #include #include "qat_provider.h" int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns); OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode); OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len); int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len, size_t *bytes_read); int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len, size_t *written); int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size); int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str); int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr); int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio); int ossl_prov_bio_free(OSSL_CORE_BIO *bio); int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap); int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...); BIO_METHOD *ossl_bio_prov_init_bio_method(void); BIO *ossl_bio_new_from_core_bio(QAT_PROV_CTX *provctx, OSSL_CORE_BIO *corebio); BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(QAT_PROV_CTX *ctx); qatengine-1.9.0/qat_prov_capabilities.c000066400000000000000000000223361500416242000202040ustar00rootroot00000000000000#include #include #include #include /* For TLS1_VERSION etc */ #include #include #include "qat_provider.h" /* If neither ec or dh is available then we have no TLS-GROUP capabilities */ #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) # define OSSL_TLS_GROUP_ID_sect163k1 0x0001 # define OSSL_TLS_GROUP_ID_sect163r1 0x0002 # define OSSL_TLS_GROUP_ID_sect163r2 0x0003 # define OSSL_TLS_GROUP_ID_sect193r1 0x0004 # define OSSL_TLS_GROUP_ID_sect193r2 0x0005 # define OSSL_TLS_GROUP_ID_sect233k1 0x0006 # define OSSL_TLS_GROUP_ID_sect233r1 0x0007 # define OSSL_TLS_GROUP_ID_sect239k1 0x0008 # define OSSL_TLS_GROUP_ID_sect283k1 0x0009 # define OSSL_TLS_GROUP_ID_sect283r1 0x000A # define OSSL_TLS_GROUP_ID_sect409k1 0x000B # define OSSL_TLS_GROUP_ID_sect409r1 0x000C # define OSSL_TLS_GROUP_ID_sect571k1 0x000D # define OSSL_TLS_GROUP_ID_sect571r1 0x000E # define OSSL_TLS_GROUP_ID_secp160k1 0x000F # define OSSL_TLS_GROUP_ID_secp160r1 0x0010 # define OSSL_TLS_GROUP_ID_secp160r2 0x0011 # define OSSL_TLS_GROUP_ID_secp192k1 0x0012 # define OSSL_TLS_GROUP_ID_secp192r1 0x0013 # define OSSL_TLS_GROUP_ID_secp224k1 0x0014 # define OSSL_TLS_GROUP_ID_secp224r1 0x0015 # define OSSL_TLS_GROUP_ID_secp256k1 0x0016 # define OSSL_TLS_GROUP_ID_secp256r1 0x0017 # define OSSL_TLS_GROUP_ID_secp384r1 0x0018 # define OSSL_TLS_GROUP_ID_secp521r1 0x0019 # define OSSL_TLS_GROUP_ID_brainpoolP256r1 0x001A # define OSSL_TLS_GROUP_ID_brainpoolP384r1 0x001B # define OSSL_TLS_GROUP_ID_brainpoolP512r1 0x001C # define OSSL_TLS_GROUP_ID_x25519 0x001D # define OSSL_TLS_GROUP_ID_x448 0x001E # define OSSL_TLS_GROUP_ID_ffdhe2048 0x0100 # define OSSL_TLS_GROUP_ID_ffdhe3072 0x0101 # define OSSL_TLS_GROUP_ID_ffdhe4096 0x0102 # define OSSL_TLS_GROUP_ID_ffdhe6144 0x0103 # define OSSL_TLS_GROUP_ID_ffdhe8192 0x0104 # define OSSL_TLS_GROUP_ID_sm2 0x0029 # if !defined(NTLS1_1_VERSION) /* NTLS version. OpenSSL3 doesn't support yet, define to pass the compile. */ # define NTLS1_1_VERSION 0x0101 # endif typedef struct tls_group_constants_st { unsigned int group_id; /* Group ID */ unsigned int secbits; /* Bits of security */ int mintls; /* Minimum TLS version, -1 unsupported */ int maxtls; /* Maximum TLS version (or 0 for undefined) */ int mindtls; /* Minimum DTLS version, -1 unsupported */ int maxdtls; /* Maximum DTLS version (or 0 for undefined) */ } TLS_GROUP_CONSTANTS; static const TLS_GROUP_CONSTANTS group_list[36] = { { OSSL_TLS_GROUP_ID_sect163k1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect163r1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect163r2, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect193r1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect193r2, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect233k1, 112, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect233r1, 112, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect239k1, 112, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect283k1, 128, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect283r1, 128, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect409k1, 192, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect409r1, 192, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect571k1, 256, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_sect571r1, 256, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp160k1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp160r1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp160r2, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp192k1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp192r1, 80, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp224k1, 112, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp224r1, 112, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp256k1, 128, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_secp256r1, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, { OSSL_TLS_GROUP_ID_secp384r1, 192, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, { OSSL_TLS_GROUP_ID_secp521r1, 256, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, { OSSL_TLS_GROUP_ID_brainpoolP256r1, 128, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_brainpoolP384r1, 192, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_brainpoolP512r1, 256, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION }, { OSSL_TLS_GROUP_ID_x25519, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, { OSSL_TLS_GROUP_ID_x448, 224, TLS1_VERSION, 0, DTLS1_VERSION, 0 }, /* Security bit values as given by BN_security_bits() */ { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, -1, -1 }, { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, -1, -1 }, { OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, -1, -1 }, { OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, -1, -1 }, { OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, -1, -1 }, { OSSL_TLS_GROUP_ID_sm2, 128, NTLS1_1_VERSION, 0, -1, -1 }, }; #define TLS_GROUP_ENTRY(tlsname, realname, algorithm, idx) \ { \ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, \ tlsname, \ sizeof(tlsname)), \ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, \ realname, \ sizeof(realname)), \ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, \ algorithm, \ sizeof(algorithm)), \ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, \ (unsigned int *)&group_list[idx].group_id), \ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, \ (unsigned int *)&group_list[idx].secbits), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, \ (unsigned int *)&group_list[idx].mintls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, \ (unsigned int *)&group_list[idx].maxtls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, \ (unsigned int *)&group_list[idx].mindtls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, \ (unsigned int *)&group_list[idx].maxdtls), \ OSSL_PARAM_END \ } static const OSSL_PARAM param_group_list[][10] = { TLS_GROUP_ENTRY("secp256r1", "prime256v1", "EC", 22), TLS_GROUP_ENTRY("P-256", "prime256v1", "EC", 22), /* Alias of above */ TLS_GROUP_ENTRY("secp384r1", "secp384r1", "EC", 23), TLS_GROUP_ENTRY("P-384", "secp384r1", "EC", 23), /* Alias of above */ TLS_GROUP_ENTRY("secp521r1", "secp521r1", "EC", 24), TLS_GROUP_ENTRY("P-521", "secp521r1", "EC", 24), /* Alias of above */ TLS_GROUP_ENTRY("x25519", "X25519", "X25519", 28), TLS_GROUP_ENTRY("x448", "X448", "X448", 29), /* Security bit values for FFDHE groups are as per RFC 7919 */ TLS_GROUP_ENTRY("ffdhe2048", "ffdhe2048", "DH", 30), TLS_GROUP_ENTRY("ffdhe3072", "ffdhe3072", "DH", 31), TLS_GROUP_ENTRY("ffdhe4096", "ffdhe4096", "DH", 32), TLS_GROUP_ENTRY("ffdhe6144", "ffdhe6144", "DH", 33), TLS_GROUP_ENTRY("ffdhe8192", "ffdhe8192", "DH", 34), TLS_GROUP_ENTRY("curveSM2", "SM2", "SM2", 35), }; #endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ static int tls_group_capability(OSSL_CALLBACK *cb, void *arg) { #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) size_t i; for (i = 0; i < OSSL_NELEM(param_group_list); i++) if (!cb(param_group_list[i], arg)) return 0; #endif return 1; } int qat_prov_get_capabilities(void *provctx, const char *capability, OSSL_CALLBACK *cb, void *arg) { if (strcasecmp(capability, "TLS-GROUP") == 0) return tls_group_capability(cb, arg); /* We don't support this capability */ return 0; } qatengine-1.9.0/qat_prov_cbc.c000066400000000000000000001014621500416242000163000ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include "qat_prov_cbc.h" #include "qat_provider.h" #include "e_qat.h" # ifdef QAT_HW # define AES_CBC_HMAC_SHA_FLAGS (PROV_CIPHER_FLAG_AEAD \ | PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) static OSSL_FUNC_cipher_encrypt_init_fn qat_aes_einit; static OSSL_FUNC_cipher_decrypt_init_fn qat_aes_dinit; static OSSL_FUNC_cipher_freectx_fn qat_aes_cbc_hmac_sha1_freectx; static OSSL_FUNC_cipher_freectx_fn qat_aes_cbc_hmac_sha256_freectx; static OSSL_FUNC_cipher_get_ctx_params_fn qat_aes_get_ctx_params; static OSSL_FUNC_cipher_gettable_ctx_params_fn qat_aes_gettable_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn qat_aes_set_ctx_params; static OSSL_FUNC_cipher_settable_ctx_params_fn qat_aes_settable_ctx_params; # define qat_aes_gettable_params qat_cipher_generic_gettable_params # define qat_aes_update qat_cipher_generic_stream_update # define qat_aes_final qat_cipher_generic_stream_final # define qat_aes_cipher qat_aes_cbc_cipher_do_cipher # define ossl_assert(x) ((x) != 0) const char *qat_get_cipher_name_from_nid(int nid) { switch (nid) { case NID_aes_128_cbc_hmac_sha1: return "AES-128-CBC-HMAC-SHA1"; case NID_aes_256_cbc_hmac_sha1: return "AES-256-CBC-HMAC-SHA1"; case NID_aes_128_cbc_hmac_sha256: return "AES-128-CBC-HMAC-SHA256"; case NID_aes_256_cbc_hmac_sha256: return "AES-256-CBC-HMAC-SHA256"; default: WARN("Invalid nid %d\n", nid); return NULL; } } PROV_EVP_CIPHER get_default_cipher_aes_cbc(int nid) { static PROV_EVP_CIPHER cbc_cipher; static int initialized = 0; if (!initialized) { PROV_EVP_CIPHER *cipher = (PROV_EVP_CIPHER *) EVP_CIPHER_fetch(NULL, qat_get_cipher_name_from_nid(nid), "provider=default"); if (cipher) { cbc_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initialized = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return cbc_cipher; } static int qat_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, size_t ivlen) { if (ivlen != ctx->ivlen || ivlen > sizeof(ctx->iv)) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } ctx->iv_set = 1; memcpy(ctx->iv, iv, ivlen); memcpy(ctx->oiv, iv, ivlen); return 1; } static int qat_aes_einit(void *vctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; ctx->num = 0; ctx->bufsz = 0; ctx->updated = 0; ctx->enc = 1; if (!qat_prov_is_running()) return 0; # ifndef QAT_INSECURE_ALGO if (ctx->nid == NID_aes_128_cbc_hmac_sha256) goto end; # endif if (key != NULL && !qat_chained_ciphers_init(ctx, key, keylen, iv, ivlen, 1)){ WARN("qat_chained_ciphers_init failed\n"); return 0; } if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (!qat_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } if (iv == NULL && ctx->iv_set && (ctx->mode == EVP_CIPH_CBC_MODE || ctx->mode == EVP_CIPH_CFB_MODE || ctx->mode == EVP_CIPH_OFB_MODE)) /* reset IV for these modes to keep compatibility with 1.1.1 */ memcpy(ctx->iv, ctx->oiv, ctx->ivlen); if (key != NULL) { if (ctx->variable_keylength == 0) { if (keylen != ctx->keylen) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } } else { ctx->keylen = keylen; } } return qat_aes_set_ctx_params(ctx, params); #ifndef QAT_INSECURE_ALGO end: const OSSL_PARAM ps[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); if (ctx->sw_ctx || (ctx->sw_ctx = sw_aes_cbc_cipher.newctx(ctx))) return sw_aes_cbc_cipher.einit(ctx->sw_ctx, key, keylen, iv, ivlen, ps); return 0; #endif } static int qat_aes_dinit(void *vctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; ctx->num = 0; ctx->bufsz = 0; ctx->updated = 0; ctx->enc = 0; # ifndef QAT_INSECURE_ALGO if (ctx->nid == NID_aes_128_cbc_hmac_sha256) goto end; # endif if (!qat_prov_is_running()) return 0; if (key != NULL && !qat_chained_ciphers_init(ctx, key, keylen, iv, ivlen, 0)){ WARN("qat_chained_ciphers_init failed\n"); return 0; } if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (!qat_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } if (iv == NULL && ctx->iv_set && (ctx->mode == EVP_CIPH_CBC_MODE || ctx->mode == EVP_CIPH_CFB_MODE || ctx->mode == EVP_CIPH_OFB_MODE)) /* reset IV for these modes to keep compatibility with 1.1.1 */ memcpy(ctx->iv, ctx->oiv, ctx->ivlen); if (key != NULL) { if (ctx->variable_keylength == 0) { if (keylen != ctx->keylen) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } } else { ctx->keylen = keylen; } } return qat_aes_set_ctx_params(ctx, params); #ifndef QAT_INSECURE_ALGO end: const OSSL_PARAM ps[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); if (ctx->sw_ctx || (ctx->sw_ctx = sw_aes_cbc_cipher.newctx(ctx))) return sw_aes_cbc_cipher.dinit(ctx->sw_ctx, key, keylen, iv, ivlen, ps); return 0; #endif } static const OSSL_PARAM cipher_aes_known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_MAC_KEY, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), # if !defined(OPENSSL_NO_MULTIBLOCK) OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, NULL), OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, NULL, 0), # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_aes_settable_ctx_params(ossl_unused void *cctx, ossl_unused void *provctx) { return cipher_aes_known_settable_ctx_params; } static int qat_aes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_AES_HMAC_SHA_CTX *ctx = (PROV_AES_HMAC_SHA_CTX *)vctx; const OSSL_PARAM *p; int ret = 1; # if !defined(OPENSSL_NO_MULTIBLOCK) EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; # endif if (params == NULL) return 1; # ifndef QAT_INSECURE_ALGO if (ctx->base.nid == NID_aes_128_cbc_hmac_sha256) goto end; # endif p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_MAC_KEY); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (!qat_chained_ciphers_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, p->data_size, p->data)){ WARN("Failed in setting ctx mac key.\n"); return 0; } } # if !defined(OPENSSL_NO_MULTIBLOCK) p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT); if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->multiblock_max_send_fragment)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } /* * The inputs to tls1_multiblock_aad are: * mb_param->inp * mb_param->len * mb_param->interleave * The outputs of tls1_multiblock_aad are written to: * ctx->multiblock_interleave * ctx->multiblock_aad_packlen */ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD); if (p != NULL) { const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE); if (p->data_type != OSSL_PARAM_OCTET_STRING || p1 == NULL || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } mb_param.inp = p->data; mb_param.len = p->data_size; } /* * The inputs to tls1_multiblock_encrypt are: * mb_param->inp * mb_param->len * mb_param->interleave * mb_param->out * The outputs of tls1_multiblock_encrypt are: * ctx->multiblock_encrypt_len */ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC); if (p != NULL) { const OSSL_PARAM *p1 = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE); const OSSL_PARAM *pin = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN); if (p->data_type != OSSL_PARAM_OCTET_STRING || pin == NULL || pin->data_type != OSSL_PARAM_OCTET_STRING || p1 == NULL || !OSSL_PARAM_get_uint(p1, &mb_param.interleave)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } mb_param.out = p->data; mb_param.inp = pin->data; mb_param.len = pin->data_size; } # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (!qat_chained_ciphers_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data)){ WARN("Failed in setting ctx TLS1_ADD.\n"); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL) { size_t keylen; if (!OSSL_PARAM_get_size_t(p, &keylen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (ctx->base.keylen != keylen) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION); if (p != NULL) { if (!OSSL_PARAM_get_uint(p, &ctx->base.tlsversion)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (ctx->base.tlsversion == SSL3_VERSION || ctx->base.tlsversion == TLS1_VERSION) { if (!ossl_assert(ctx->base.removetlsfixed >= AES_BLOCK_SIZE)) { QATerr(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } /* * There is no explicit IV with these TLS versions, so don't attempt * to remove it. */ ctx->base.removetlsfixed -= AES_BLOCK_SIZE; } } if (ctx->base.sw_ctx) { PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->base.nid); sw_aes_cbc_cipher.set_ctx_params(ctx->base.sw_ctx, params); } return ret; #ifndef QAT_INSECURE_ALGO end: if (ctx->base.sw_ctx) { PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->base.nid); return sw_aes_cbc_cipher.set_ctx_params(ctx->base.sw_ctx, params); } return 0; #endif } static int qat_aes_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_AES_HMAC_SHA_CTX *ctx = (PROV_AES_HMAC_SHA_CTX *)vctx; OSSL_PARAM *p; # ifndef QAT_INSECURE_ALGO if (ctx->base.nid == NID_aes_128_cbc_hmac_sha256) goto end; # endif # if !defined(OPENSSL_NO_MULTIBLOCK) p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE); if (p != NULL) { WARN("Do not support OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE\n"); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->multiblock_interleave)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->multiblock_aad_packlen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->multiblock_encrypt_len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */ p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.keylen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.ivlen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL && !OSSL_PARAM_set_octet_string(p, ctx->base.oiv, ctx->base.ivlen) && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.oiv, ctx->base.ivlen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL && !OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen) && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.iv, ctx->base.ivlen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; #ifndef QAT_INSECURE_ALGO end: PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->base.nid); ctx->base.sw_ctx = sw_aes_cbc_cipher.newctx(ctx); if (ctx->base.sw_ctx) return sw_aes_cbc_cipher.get_ctx_params(ctx->base.sw_ctx, params); return 0; #endif } static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = { # if !defined(OPENSSL_NO_MULTIBLOCK) OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, NULL), OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, NULL), OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_LEN, NULL), # endif /* !defined(OPENSSL_NO_MULTIBLOCK) */ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_aes_gettable_ctx_params(ossl_unused void *cctx, ossl_unused void *provctx) { return cipher_aes_known_gettable_ctx_params; } static void *qat_aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags, int nid) { PROV_AES_HMAC_SHA1_CTX *ctx = NULL; PROV_CIPHER_CTX *base_ctx = NULL; PROV_EVP_CIPHER sw_aes_cbc_cipher; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL){ base_ctx = &ctx->base_ctx.base; base_ctx->nid = nid; base_ctx->qat_cipher_ctx = OPENSSL_zalloc(sizeof(qat_chained_ctx)); if (base_ctx->qat_cipher_ctx == NULL){ WARN("qat_cipher_ctx zalloc failed.\n"); goto err; } sw_aes_cbc_cipher = get_default_cipher_aes_cbc(base_ctx->nid); #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD base_ctx->sw_ctx = sw_aes_cbc_cipher.newctx(base_ctx); if (base_ctx->sw_ctx == NULL){ WARN("base_ctx->sw_ctx zalloc failed.\n"); goto err; } #else if (enable_sw_fallback){ base_ctx->sw_ctx = sw_aes_cbc_cipher.newctx(base_ctx); if (base_ctx->sw_ctx == NULL){ WARN("base_ctx->sw_ctx zalloc failed.\n"); goto err; } } #endif if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0) base_ctx->inverse_cipher = 1; if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0) base_ctx->variable_keylength = 1; base_ctx->pad = 1; base_ctx->keylen = ((kbits) / 8); base_ctx->ivlen = ((ivbits) / 8); base_ctx->mode = EVP_CIPH_CBC_MODE; base_ctx->blocksize = blkbits / 8; if (provctx != NULL) base_ctx->libctx = prov_libctx_of(provctx); /* used for rand */ } return ctx; err: if (base_ctx->sw_ctx != NULL) OPENSSL_free(base_ctx->sw_ctx); if (base_ctx->qat_cipher_ctx != NULL) OPENSSL_free(base_ctx->qat_cipher_ctx); OPENSSL_free(ctx); return NULL; } static void *qat_aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags, int nid) { PROV_AES_HMAC_SHA256_CTX *ctx = NULL; PROV_CIPHER_CTX *base_ctx = NULL; PROV_EVP_CIPHER sw_aes_cbc_cipher; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL){ base_ctx = &ctx->base_ctx.base; base_ctx->nid = nid; base_ctx->qat_cipher_ctx = OPENSSL_zalloc(sizeof(qat_chained_ctx)); if (base_ctx->qat_cipher_ctx == NULL){ WARN("qat_cipher_ctx zalloc failed.\n"); goto err; } sw_aes_cbc_cipher = get_default_cipher_aes_cbc(base_ctx->nid); #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD base_ctx->sw_ctx = sw_aes_cbc_cipher.newctx(base_ctx); if (base_ctx->sw_ctx == NULL){ WARN("base_ctx->sw_ctx zalloc failed.\n"); goto err; } EVP_CIPHER_CTX_init(base_ctx->sw_ctx); #else if (enable_sw_fallback){ base_ctx->sw_ctx = sw_aes_cbc_cipher.newctx(base_ctx); if (base_ctx->sw_ctx == NULL){ WARN("base_ctx->sw_ctx zalloc failed.\n"); goto err; } EVP_CIPHER_CTX_init(base_ctx->sw_ctx); } #endif if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0) base_ctx->inverse_cipher = 1; if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0) base_ctx->variable_keylength = 1; base_ctx->pad = 1; base_ctx->keylen = ((kbits) / 8); base_ctx->ivlen = ((ivbits) / 8); base_ctx->mode = EVP_CIPH_CBC_MODE; base_ctx->blocksize = blkbits / 8; if (provctx != NULL) base_ctx->libctx = prov_libctx_of(provctx); /* used for rand */ } return ctx; err: if (base_ctx->sw_ctx != NULL) OPENSSL_free(base_ctx->sw_ctx); if (base_ctx->qat_cipher_ctx != NULL) OPENSSL_free(base_ctx->qat_cipher_ctx); OPENSSL_free(ctx); return NULL; } static void qat_aes_cbc_hmac_sha1_freectx(void *vctx) { PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx; PROV_CIPHER_CTX *base_ctx = (PROV_CIPHER_CTX *)vctx; if (ctx != NULL) { if (base_ctx != NULL){ if (!qat_chained_ciphers_cleanup(base_ctx)){ WARN("Failed clean up the base_ctx!\n"); } OPENSSL_clear_free(base_ctx->qat_cipher_ctx, sizeof(qat_chained_ctx)); } if (base_ctx != NULL && base_ctx->alloced) { OPENSSL_free(base_ctx->tlsmac); base_ctx->alloced = 0; base_ctx->tlsmac = NULL; } OPENSSL_clear_free(ctx, sizeof(*ctx)); } } static void qat_aes_cbc_hmac_sha256_freectx(void *vctx) { PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx; PROV_CIPHER_CTX *base_ctx = (PROV_CIPHER_CTX *)vctx; if (ctx != NULL) { if (base_ctx != NULL){ if (!qat_chained_ciphers_cleanup(base_ctx)){ WARN("Failed clean up the base_ctx!\n"); } OPENSSL_clear_free(base_ctx->qat_cipher_ctx, sizeof(qat_chained_ctx)); } if (base_ctx != NULL && base_ctx->alloced) { OPENSSL_free(base_ctx->tlsmac); base_ctx->alloced = 0; base_ctx->tlsmac = NULL; } OPENSSL_clear_free(ctx, sizeof(*ctx)); } } int qat_aes_cbc_cipher_do_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; # ifndef QAT_INSECURE_ALGO if (ctx->nid == NID_aes_128_cbc_hmac_sha256) goto end; # endif if (!qat_prov_is_running()) return 0; if (outsize < inl) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (qat_chained_ciphers_do_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } *outl = inl; return 1; #ifndef QAT_INSECURE_ALGO end: if (ctx->sw_ctx) { PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); return sw_aes_cbc_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl); } return 0; #endif } int qat_cipher_generic_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { # ifndef QAT_INSECURE_ALGO PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; if (ctx->nid == NID_aes_128_cbc_hmac_sha256) { if (ctx->sw_ctx) { PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); return sw_aes_cbc_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); } return 0; } # endif if (!qat_prov_is_running()) return 0; *outl = 0; return 1; } int qat_cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; # ifndef QAT_INSECURE_ALGO if (ctx->nid == NID_aes_128_cbc_hmac_sha256) goto end; # endif if (inl == 0) { *outl = 0; return 1; } if (outsize < inl) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (qat_chained_ciphers_do_cipher(ctx, out, outl, outsize, in, inl) <= 0){ QATerr(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); return 0; } *outl = inl; if (!ctx->enc && ctx->tlsversion > 0) { /* * Remove any TLS padding. Only used by cipher_aes_cbc_hmac_sha1_hw.c and * cipher_aes_cbc_hmac_sha256_hw.c */ if (ctx->removetlspad) { /* * We should have already failed in the cipher() call above if this * isn't true. */ if (!ossl_assert(*outl >= (size_t)(out[inl - 1] + 1))) return 0; /* The actual padding length */ *outl -= out[inl - 1] + 1; } /* TLS MAC and explicit IV if relevant. We should have already failed * in the cipher() call above if *outl is too short. */ if (!ossl_assert(*outl >= ctx->removetlsfixed)) return 0; *outl -= ctx->removetlsfixed; /* Extract the MAC if there is one */ if (ctx->tlsmacsize > 0) { if (*outl < ctx->tlsmacsize) return 0; ctx->tlsmac = out + *outl - ctx->tlsmacsize; *outl -= ctx->tlsmacsize; } } return 1; #ifndef QAT_INSECURE_ALGO end: if (ctx->sw_ctx) { PROV_EVP_CIPHER sw_aes_cbc_cipher = get_default_cipher_aes_cbc(ctx->nid); return sw_aes_cbc_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl); } return 0; #endif } static const OSSL_PARAM cipher_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; static const OSSL_PARAM *qat_cipher_generic_gettable_params(ossl_unused void *provctx) { return cipher_known_gettable_params; } static int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags, nid) \ static OSSL_FUNC_cipher_newctx_fn qat_##nm##_##kbits##_##sub##_newctx; \ static void *qat_##nm##_##kbits##_##sub##_newctx(void *provctx) \ { \ return qat_##nm##_##sub##_newctx(provctx, kbits, blkbits, ivbits, flags, nid); \ } \ static OSSL_FUNC_cipher_get_params_fn qat_##nm##_##kbits##_##sub##_get_params; \ static int qat_##nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[]) \ { \ return ossl_cipher_generic_get_params(params, EVP_CIPH_CBC_MODE, \ flags, kbits, blkbits, ivbits); \ } \ const OSSL_DISPATCH qat_##nm##kbits##sub##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))qat_##nm##_##kbits##_##sub##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))qat_##nm##_##sub##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))qat_##nm##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))qat_##nm##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))qat_##nm##_update }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))qat_##nm##_final }, \ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))qat_##nm##_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))qat_##nm##_##kbits##_##sub##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))qat_##nm##_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void))qat_##nm##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))qat_##nm##_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void))qat_##nm##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))qat_##nm##_settable_ctx_params }, \ { 0, NULL } \ }; IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS, NID_aes_128_cbc_hmac_sha1) IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS, NID_aes_256_cbc_hmac_sha1) IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS, NID_aes_128_cbc_hmac_sha256) IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS, NID_aes_256_cbc_hmac_sha256) #endif /* QAT_HW */ qatengine-1.9.0/qat_prov_cbc.h000066400000000000000000000211571500416242000163070ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #ifndef QAT_PROV_CBC_H # define QAT_PROV_CBC_H # ifdef QAT_HW # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include #include "qat_hw_ciphers.h" #include "e_qat.h" # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "cpa_cy_drbg.h" # include "qat_utils.h" #define MAXCHUNK ((size_t)1 << (sizeof(long) * 8 - 2)) #define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4)) #define GENERIC_BLOCK_SIZE 16 #define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ #define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */ #define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */ #define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */ #define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; /* Internal flags that can be queried */ #define PROV_CIPHER_FLAG_AEAD 0x0001 #define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 #define PROV_CIPHER_FLAG_CTS 0x0004 #define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 #define PROV_CIPHER_FLAG_RAND_KEY 0x0010 /* Internal flags that are only used within the provider */ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 #define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 typedef struct evp_cipher_st { int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup) (EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; # endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; }PROV_EVP_CIPHER; struct prov_cipher_ctx_st { int nid; block128_f block; union { cbc128_f cbc; ctr128_f ctr; ecb128_f ecb; } stream; unsigned int mode; size_t keylen; /* key size (in bytes) */ size_t ivlen; size_t blocksize; size_t bufsz; /* Number of bytes in buf */ unsigned int cts_mode; /* Use to set the type for CTS modes */ unsigned int pad : 1; /* Whether padding should be used or not */ unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */ unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */ unsigned int updated : 1; /* Set to 1 during update for one shot ciphers */ unsigned int variable_keylength : 1; unsigned int inverse_cipher : 1; /* set to 1 to use inverse cipher */ unsigned int use_bits : 1; /* Set to 0 for cfb1 to use bits instead of bytes */ unsigned int tlsversion; /* If TLS padding is in use the TLS version number */ unsigned char *tlsmac; /* tls MAC extracted from the last record */ int alloced; /* * Whether the tlsmac data has been allocated or * points into the user buffer. */ size_t tlsmacsize; /* Size of the TLS MAC */ int removetlspad; /* Whether TLS padding should be removed or not */ size_t removetlsfixed; /* * Length of the fixed size data to remove when * processing TLS data (equals mac size plus * IV size if applicable) */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ unsigned int num; /* The original value of the iv */ unsigned char oiv[GENERIC_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ unsigned char buf[GENERIC_BLOCK_SIZE]; unsigned char iv[GENERIC_BLOCK_SIZE]; const void *ks; /* Pointer to algorithm specific key data */ OSSL_LIB_CTX *libctx; void *qat_cipher_ctx; EVP_CIPHER_CTX *sw_ctx; EVP_CIPHER *sw_cipher; }; typedef struct prov_aes_hmac_sha_ctx_st { PROV_CIPHER_CTX base; AES_KEY ks; size_t payload_length; /* AAD length in decrypt case */ union { unsigned int tls_ver; unsigned char tls_aad[16]; /* 13 used */ } aux; /* some value that are setup by set methods - that can be retrieved */ unsigned int multiblock_interleave; unsigned int multiblock_aad_packlen; size_t multiblock_max_send_fragment; size_t multiblock_encrypt_len; size_t tls_aad_pad; } PROV_AES_HMAC_SHA_CTX; typedef struct prov_aes_hmac_sha1_ctx_st { PROV_AES_HMAC_SHA_CTX base_ctx; SHA_CTX head, tail, md; } PROV_AES_HMAC_SHA1_CTX; typedef struct prov_aes_hmac_sha256_ctx_st { PROV_AES_HMAC_SHA_CTX base_ctx; SHA256_CTX head, tail, md; } PROV_AES_HMAC_SHA256_CTX; PROV_EVP_CIPHER get_default_cipher_aes_cbc(int nid); const char *qat_get_cipher_name_from_nid(int nid); # endif /* QAT_HW */ #endif /* QAT_PROV_CBC_H */ qatengine-1.9.0/qat_prov_chachapoly.c000066400000000000000000000531201500416242000176610ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_chachapoly.c * * This file provides an implementation of CHACHAPOLY operations for OpenSSL * 3.0 qatprovider. * *****************************************************************************/ #include #ifdef QAT_HW_INTREE # ifndef ENABLE_QAT_HW_CHACHAPOLY # define ENABLE_QAT_HW_CHACHAPOLY # endif #endif #ifdef ENABLE_QAT_HW_CHACHAPOLY #include "qat_prov_chachapoly.h" #include "e_qat.h" #include "qat_utils.h" #include "qat_evp.h" #define CHACHA20_POLY1305_KEYLEN 32 #define CHACHA20_POLY1305_BLKLEN 1 #define CHACHA20_POLY1305_MAX_IVLEN 12 #define CHACHA20_POLY1305_MODE 0 #define CHACHA20_POLY1305_FLAGS (PROV_CIPHER_FLAG_AEAD \ | PROV_CIPHER_FLAG_CUSTOM_IV) static OSSL_FUNC_cipher_newctx_fn qat_chacha20_poly1305_newctx; static OSSL_FUNC_cipher_freectx_fn qat_chacha20_poly1305_freectx; static OSSL_FUNC_cipher_encrypt_init_fn qat_chacha20_poly1305_einit; static OSSL_FUNC_cipher_decrypt_init_fn qat_chacha20_poly1305_dinit; static OSSL_FUNC_cipher_get_params_fn qat_chacha20_poly1305_get_params; static OSSL_FUNC_cipher_get_ctx_params_fn qat_chacha20_poly1305_get_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn qat_chacha20_poly1305_set_ctx_params; static OSSL_FUNC_cipher_cipher_fn qat_chacha20_poly1305_cipher; static OSSL_FUNC_cipher_final_fn qat_chacha20_poly1305_final; static OSSL_FUNC_cipher_gettable_ctx_params_fn qat_chacha20_poly1305_gettable_ctx_params; static OSSL_FUNC_cipher_gettable_params_fn qat_cipher_generic_gettable_params; static OSSL_FUNC_cipher_settable_ctx_params_fn qat_cipher_aead_settable_ctx_params; #define qat_chacha20_poly1305_update qat_chacha20_poly1305_cipher static void qat_cipher_generic_reset_ctx(QAT_PROV_CIPHER_CTX *ctx) { if (ctx != NULL && ctx->alloced) { OPENSSL_free(ctx->tlsmac); ctx->alloced = 0; ctx->tlsmac = NULL; } } QAT_EVP_CIPHER get_default_cipher_chachapoly() { static QAT_EVP_CIPHER chachapoly_cipher; static int initialized = 0; if (!initialized) { QAT_EVP_CIPHER *cipher = (QAT_EVP_CIPHER *) EVP_CIPHER_fetch(NULL, "ChaCha20-Poly1305", "provider=default"); if (cipher) { chachapoly_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initialized = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return chachapoly_cipher; } static int qat_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static void qat_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, size_t ivbits, unsigned int mode, uint64_t flags, void *provctx) { QAT_PROV_CIPHER_CTX *ctx = (QAT_PROV_CIPHER_CTX *)vctx; if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0) ctx->inverse_cipher = 1; if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0) ctx->variable_keylength = 1; ctx->pad = 1; ctx->keylen = ((kbits) / 8); ctx->ivlen = ((ivbits) / 8); ctx->mode = mode; ctx->blocksize = blkbits / 8; if (provctx != NULL) ctx->libctx = prov_libctx_of(provctx); /* used for rand */ } static void *qat_chacha20_poly1305_newctx(void *provctx) { PROV_CHACHA20_POLY1305_CTX *ctx; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { qat_cipher_generic_initkey(&ctx->base, CHACHA20_POLY1305_KEYLEN * 8, CHACHA20_POLY1305_BLKLEN * 8, CHACHA20_POLY1305_IVLEN * 8, CHACHA20_POLY1305_MODE, CHACHA20_POLY1305_FLAGS, NULL); ctx->nonce_len = CHACHA20_POLY1305_IVLEN; ctx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; qat_cipher_generic_initkey(&ctx->chacha, CHACHA20_KEYLEN * 8, CHACHA20_BLKLEN * 8, CHACHA20_IVLEN * 8, 0, CHACHA20_FLAGS, NULL); ctx->base.nid = NID_chacha20_poly1305; ctx->base.nonce_len = CHACHA20_POLY1305_IVLEN; ctx->base.tls_payload_length = NO_TLS_PAYLOAD_LENGTH; } return ctx; } static void qat_chacha20_poly1305_freectx(void *vctx) { PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; if (ctx != NULL) { EVP_CIPHER_free((EVP_CIPHER *)ctx->base.sw_cipher); /* Free the memory of qat chachapoly context structure. */ qat_chacha20_poly1305_cleanup(&ctx->base); qat_cipher_generic_reset_ctx((QAT_PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } static int qat_chacha20_poly1305_get_params(OSSL_PARAM params[]) { return qat_cipher_generic_get_params(params, 0, CHACHA20_POLY1305_FLAGS, CHACHA20_POLY1305_KEYLEN * 8, CHACHA20_POLY1305_BLKLEN * 8, CHACHA20_POLY1305_IVLEN * 8); } static int qat_chacha20_poly1305_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; OSSL_PARAM *p; int ret = 1; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL) { if (!OSSL_PARAM_set_size_t(p, ctx->nonce_len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, CHACHA20_POLY1305_KEYLEN)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tag_len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } if (!ctx->base.enc) { QATerr(ERR_LIB_PROV, PROV_R_TAG_NOT_SET); return 0; } if (p->data_size == 0 || p->data_size > QAT_POLY1305_BLOCK_SIZE) { if (ctx->base.tag_set) QATerr(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH); ret = 0; ctx->base.tag_set = 0; goto end; } memcpy(p->data, ctx->base.tag, p->data_size); if (ctx->base.tag_set) { ctx->base.tag_set = 0; return 1; } } end: if (ctx->base.sw_ctx) { QAT_EVP_CIPHER sw_chachapoly_cipher = get_default_cipher_chachapoly(); sw_chachapoly_cipher.get_ctx_params(ctx->base.sw_ctx, params); } return ret; } static const OSSL_PARAM chacha20_poly1305_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_END }; static const OSSL_PARAM *qat_chacha20_poly1305_gettable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return chacha20_poly1305_known_gettable_ctx_params; } static int qat_chacha20_poly1305_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; size_t len; PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (len != CHACHA20_POLY1305_KEYLEN) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (len == 0 || len > CHACHA20_POLY1305_MAX_IVLEN) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } ctx->nonce_len = len; qat_chacha20_poly1305_ctrl(&ctx->base, EVP_CTRL_AEAD_SET_IVLEN, len, NULL); } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (p->data_size == 0 || p->data_size > QAT_POLY1305_BLOCK_SIZE) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH); return 0; } if (p->data != NULL) { if (ctx->base.enc) { QATerr(ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED); return 0; } memcpy(ctx->base.tag, p->data, p->data_size); ctx->base.tag_set = 1; } ctx->base.tag_len = p->data_size; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } len = qat_chacha20_poly1305_ctrl(&ctx->base, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data); if (len == 0) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_DATA); return 0; } ctx->tls_aad_pad_sz = len; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (qat_chacha20_poly1305_ctrl(&ctx->base, EVP_CTRL_AEAD_SET_IV_FIXED, p->data_size, p->data) == 0) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } } if (ctx->base.sw_ctx) { QAT_EVP_CIPHER sw_chachapoly_cipher = get_default_cipher_chachapoly(); sw_chachapoly_cipher.set_ctx_params(ctx->base.sw_ctx, params); } /* ignore OSSL_CIPHER_PARAM_AEAD_MAC_KEY */ return 1; } static int qat_cipher_generic_initiv(QAT_PROV_CIPHER_CTX *ctx, const unsigned char *iv, size_t ivlen) { if (ivlen != ctx->ivlen || ivlen > sizeof(ctx->iv)) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } ctx->iv_set = 1; memcpy(ctx->iv, iv, ivlen); memcpy(ctx->oiv, iv, ivlen); return 1; } static int qat_chacha20_poly1305_einit(void *vctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]) { QAT_PROV_CIPHER_CTX *ctx = (QAT_PROV_CIPHER_CTX *)vctx; int ret; ctx->num = 0; ctx->bufsz = 0; ctx->updated = 0; ctx->enc = 1; if (!qat_prov_is_running()) return 0; if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (!qat_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } if (iv == NULL && ctx->iv_set && (ctx->mode == EVP_CIPH_CBC_MODE || ctx->mode == EVP_CIPH_CFB_MODE || ctx->mode == EVP_CIPH_OFB_MODE)) /* reset IV for these modes to keep compatibility with 1.1.1 */ memcpy(ctx->iv, ctx->oiv, ctx->ivlen); if (key != NULL) { if (ctx->variable_keylength == 0) { if (keylen != ctx->keylen) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } } else { ctx->keylen = keylen; } } ret = qat_chacha20_poly1305_init(ctx, key, keylen, iv, ivlen, 1); if (ret && !qat_chacha20_poly1305_set_ctx_params(vctx, params)) ret = 0; return ret; } static int qat_chacha20_poly1305_dinit(void *vctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, const OSSL_PARAM params[]) { QAT_PROV_CIPHER_CTX *ctx = (QAT_PROV_CIPHER_CTX *)vctx; PROV_CHACHA20_POLY1305_CTX *cp_ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; int ret; ctx->num = 0; ctx->bufsz = 0; ctx->updated = 0; ctx->enc = 0; if (!qat_prov_is_running()) return 0; if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (!qat_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } if (iv == NULL && ctx->iv_set && (ctx->mode == EVP_CIPH_CBC_MODE || ctx->mode == EVP_CIPH_CFB_MODE || ctx->mode == EVP_CIPH_OFB_MODE)) /* reset IV for these modes to keep compatibility with 1.1.1 */ memcpy(ctx->iv, ctx->oiv, ctx->ivlen); if (key != NULL) { if (ctx->variable_keylength == 0) { if (keylen != ctx->keylen) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } } else { ctx->keylen = keylen; } } ret = qat_chacha20_poly1305_init(ctx, key, keylen, iv, ivlen, 0); if (ret && !qat_chacha20_poly1305_set_ctx_params(vctx, params)) ret = 0; memcpy(cp_ctx->tag, ctx->tag, ctx->tag_len); return ret; } static int qat_chacha20_poly1305_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { QAT_PROV_CIPHER_CTX *ctx = (QAT_PROV_CIPHER_CTX *)vctx; if (!qat_prov_is_running()) return 0; if (inl == 0) { *outl = 0; return 1; } if (outsize < inl) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!qat_chacha20_poly1305_do_cipher(ctx, out, outl, outsize, in, inl)) return 0; return 1; } static int qat_chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { QAT_PROV_CIPHER_CTX *ctx = (QAT_PROV_CIPHER_CTX *)vctx; if (!qat_prov_is_running()) return 0; if (qat_chacha20_poly1305_do_cipher(ctx, out, outl, outsize, NULL, 0) <= 0) return 0; *outl = 0; return 1; } static const OSSL_PARAM qat_cipher_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; static const OSSL_PARAM *qat_cipher_generic_gettable_params(void *provctx) { return qat_cipher_known_gettable_params; } static const OSSL_PARAM qat_cipher_aead_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; static const OSSL_PARAM *qat_cipher_aead_settable_ctx_params( ossl_unused void *cctx, ossl_unused void *provctx ) { return qat_cipher_aead_known_settable_ctx_params; } /* qat_chacha20_poly1305_functions */ const OSSL_DISPATCH qat_chacha20_poly1305_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))qat_chacha20_poly1305_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))qat_chacha20_poly1305_freectx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))qat_chacha20_poly1305_einit }, { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))qat_chacha20_poly1305_dinit }, { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))qat_chacha20_poly1305_update }, { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))qat_chacha20_poly1305_final }, { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))qat_chacha20_poly1305_cipher }, { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))qat_chacha20_poly1305_get_params }, { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))qat_cipher_generic_gettable_params }, { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))qat_chacha20_poly1305_get_ctx_params }, { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))qat_chacha20_poly1305_gettable_ctx_params }, { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))qat_chacha20_poly1305_set_ctx_params }, { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))qat_cipher_aead_settable_ctx_params }, { 0, NULL } }; #endif /* ENABLE_QAT_HW_CHACHAPOLY */ qatengine-1.9.0/qat_prov_chachapoly.h000066400000000000000000000301131500416242000176630ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_chachapoly.h * * This file provides an interface of CHACHAPOLY operations for OpenSSL * 3.0 qatprovider. * *****************************************************************************/ #ifndef QAT_PROV_CHACHAPOLY_H # define QAT_PROV_CHACHAPOLY_H # include # include # include # include # include # include # include # include # include # include # include # include # include # include # ifdef ENABLE_QAT_HW_CHACHAPOLY #include "qat_hw_chachapoly.h" #include "qat_provider.h" #include "e_qat.h" /* Internal flags that can be queried */ #define PROV_CIPHER_FLAG_AEAD 0x0001 #define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 #define PROV_CIPHER_FLAG_CTS 0x0004 #define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 #define PROV_CIPHER_FLAG_RAND_KEY 0x0010 /* Internal flags that are only used within the provider */ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 #define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 #define CHACHA20_KEYLEN (QAT_CHACHA_KEY_SIZE) #define CHACHA20_BLKLEN (1) #define CHACHA20_IVLEN (QAT_CHACHA_CTR_SIZE) #define CHACHA20_FLAGS (PROV_CIPHER_FLAG_CUSTOM_IV) # define OSSL_UNION_ALIGN \ double align; \ ossl_uintmax_t align_int; \ void *align_ptr # define NO_TLS_PAYLOAD_LENGTH ((size_t)-1) # define CHACHA20_POLY1305_IVLEN 12 # define GENERIC_BLOCK_SIZE 16 # define QAT_PROV_GET_ENC(ctx) ((ctx)->enc) typedef void (*poly1305_blocks_f) (void *ctx, const unsigned char *inp, size_t len, unsigned int padbit); typedef void (*poly1305_emit_f) (void *ctx, unsigned char mac[16], const unsigned int nonce[4]); typedef struct qat_evp_cipher_st QAT_EVP_CIPHER; typedef struct prov_cp_cipher_ctx_st QAT_PROV_CIPHER_CTX; struct prov_cp_cipher_ctx_st { int nid; block128_f block; union { cbc128_f cbc; ctr128_f ctr; ecb128_f ecb; } stream; unsigned int mode; size_t keylen; /* key size (in bytes) */ size_t ivlen; size_t blocksize; size_t bufsz; /* Number of bytes in buf */ unsigned int cts_mode; /* Use to set the type for CTS modes */ unsigned int pad : 1; /* Whether padding should be used or not */ unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */ unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */ unsigned int updated : 1; /* Set to 1 during update for one shot ciphers */ unsigned int variable_keylength : 1; unsigned int inverse_cipher : 1; /* set to 1 to use inverse cipher */ unsigned int use_bits : 1; /* Set to 0 for cfb1 to use bits instead of bytes */ unsigned int tlsversion; /* If TLS padding is in use the TLS version number */ unsigned char *tlsmac; /* tls MAC extracted from the last record */ int alloced; /* * Whether the tlsmac data has been allocated or * points into the user buffer. */ size_t tlsmacsize; /* Size of the TLS MAC */ int removetlspad; /* Whether TLS padding should be removed or not */ size_t removetlsfixed; /* * Length of the fixed size data to remove when * processing TLS data (equals mac size plus * IV size if applicable) */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ unsigned int num; /* The original value of the iv */ unsigned char oiv[GENERIC_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ unsigned char buf[GENERIC_BLOCK_SIZE]; unsigned char iv[GENERIC_BLOCK_SIZE]; const void *ks; /* Pointer to algorithm specific key data */ OSSL_LIB_CTX *libctx; EVP_CIPHER_CTX *sw_ctx; QAT_EVP_CIPHER *sw_cipher; void *sw_ctx_cipher_data; int inst_num; int context_params_set; int session_init; CpaCySymSessionSetupData *session_data; CpaCySymSessionCtx session_ctx; CpaCySymOpData *opd; CpaBufferList pSrcBufferList; CpaBufferList pDstBufferList; CpaFlatBuffer src_buffer; CpaFlatBuffer dst_buffer; unsigned char tag[QAT_POLY1305_BLOCK_SIZE]; unsigned char *tls_aad; unsigned char cipher_key[QAT_CHACHA_KEY_SIZE]; unsigned char *mac_key; unsigned char nonce[QAT_CHACHA20_POLY1305_MAX_IVLEN]; unsigned char derived_iv[QAT_CHACHA20_POLY1305_MAX_IVLEN]; unsigned int counter[QAT_CHACHA_CTR_SIZE/4]; unsigned int chacha_key[QAT_CHACHA_KEY_SIZE/4]; int key_set; int mac_key_set; int tag_len; int nonce_len; int tls_aad_len; size_t tls_payload_length; int packet_size; int qat_svm; /* If tag_set 1 Encryption in qat,if tag_set 0 Encryption in Openssl SW */ int tag_set; }; typedef struct { QAT_PROV_CIPHER_CTX base; /* must be first */ union { OSSL_UNION_ALIGN; unsigned int d[QAT_CHACHA_KEY_SIZE / 4]; } key; unsigned int counter[QAT_CHACHA_CTR_SIZE / 4]; unsigned char buf[QAT_CHACHA_BLK_SIZE]; unsigned int partial_len; } PROV_CHACHA20_CTX; typedef struct poly1305_context { double opaque[24]; /* large enough to hold internal state, declared * 'double' to ensure at least 64-bit invariant * alignment across all platforms and * configurations */ unsigned int nonce[4]; unsigned char data[QAT_POLY1305_BLOCK_SIZE]; size_t num; struct { poly1305_blocks_f blocks; poly1305_emit_f emit; } func; } POLY1305; typedef struct { QAT_PROV_CIPHER_CTX base; /* must be first */ PROV_CHACHA20_CTX chacha; POLY1305 poly1305; unsigned int nonce[12 / 4]; unsigned char tag[QAT_POLY1305_BLOCK_SIZE]; unsigned char tls_aad[QAT_POLY1305_BLOCK_SIZE]; struct { uint64_t aad, text; } len; unsigned int aad : 1; unsigned int mac_inited : 1; size_t tag_len, nonce_len; size_t tls_payload_length; size_t tls_aad_pad_sz; } PROV_CHACHA20_POLY1305_CTX; struct qat_evp_cipher_st{ int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup) (EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; } /* EVP_CIPHER */ ; struct evp_cipher_ctx_st { const EVP_CIPHER *cipher; ENGINE *engine; /* functional reference if 'cipher' is * ENGINE-provided */ int encrypt; /* encrypt or decrypt */ int buf_len; /* number we have left */ unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ unsigned int iv[3]; /* working iv */ unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ int num; /* used by cfb/ofb/ctr mode */ /* FIXME: Should this even exist? It appears unused */ void *app_data; /* application stuff */ int key_len; /* May change for variable length cipher */ unsigned long flags; /* Various flags */ void *cipher_data; /* per EVP data */ int final_used; int block_mask; unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ /* * Opaque ctx returned from a providers cipher algorithm implementation * OSSL_FUNC_cipher_newctx() */ void *algctx; EVP_CIPHER *fetched_cipher; } /* EVP_CIPHER_CTX */ ; QAT_EVP_CIPHER get_default_cipher_chachapoly(); int qat_chacha20_poly1305_init(QAT_PROV_CIPHER_CTX *ctx, const unsigned char *user_key, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_chacha20_poly1305_do_cipher(QAT_PROV_CIPHER_CTX * ctx, unsigned char *out, size_t *padlen, size_t outl, const unsigned char *in, size_t len); int qat_chacha20_poly1305_cleanup(QAT_PROV_CIPHER_CTX *ctx); int qat_chacha20_poly1305_ctrl(QAT_PROV_CIPHER_CTX *ctx, int type, int arg, void *ptr); # endif /* ENABLE_QAT_HW_CHACHAPOLY */ #endif qatengine-1.9.0/qat_prov_ciphers.c000066400000000000000000000553041500416242000172110ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @qat_prov_ciphers.c * * This file contains the qatprovider implementation for AES-GCM operations * *****************************************************************************/ #include "qat_provider.h" #include "qat_prov_ciphers.h" #include "qat_utils.h" #include "e_qat.h" #ifdef ENABLE_QAT_HW_GCM #include "qat_hw_gcm.h" #endif #ifdef ENABLE_QAT_SW_GCM #include "qat_sw_gcm.h" #endif int nid; #define AES_GCM_IV_MIN_SIZE (64 / 8) #define UNINITIALISED_SIZET ((int)-1) #define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) const char *qat_gcm_cipher_name(int nid) { switch (nid) { case NID_aes_128_gcm: return LN_aes_128_gcm; case NID_aes_192_gcm: return LN_aes_192_gcm; case NID_aes_256_gcm: return LN_aes_256_gcm; default: WARN("Invalid nid %d\n", nid); return NULL; } } QAT_EVP_CIPHER get_default_cipher_aes_gcm(int nid) { static QAT_EVP_CIPHER gcm_cipher; static int initialized = 0; if (!initialized) { QAT_EVP_CIPHER *cipher = (QAT_EVP_CIPHER *) EVP_CIPHER_fetch(NULL, qat_gcm_cipher_name(nid), "provider=default"); if (cipher) { gcm_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initialized = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return gcm_cipher; } int qat_aes_gcm_ctx_get_nid(const QAT_AES_GCM_CTX *ctx) { return ctx->cipher->nid; } void qat_gcm_initctx(void *provctx, QAT_GCM_CTX *ctx, size_t keybits, size_t ivlen_min) { ctx->pad = 1; ctx->mode = EVP_CIPH_GCM_MODE; ctx->tag_len = UNINITIALISED_SIZET; ctx->tls_aad_len = UNINITIALISED_SIZET; ctx->ivlen_min = ivlen_min; ctx->iv_len = (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN); ctx->keylen = keybits / 8; ctx->libctx = prov_libctx_of(provctx); } static void *qat_aes_gcm_newctx(void *provctx, size_t keybits, int nid) { QAT_EVP_CIPHER *cipher = NULL; QAT_AES_GCM_CTX *ctx; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); cipher = OPENSSL_zalloc(sizeof(QAT_EVP_CIPHER)); cipher->nid = nid; ctx->cipher = cipher; if (ctx != NULL) qat_gcm_initctx(provctx, &ctx->base, keybits, AES_GCM_IV_MIN_SIZE); return ctx; } int qat_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) { QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; OSSL_PARAM *p; size_t sz; int ret = 1; #if defined(ENABLE_QAT_HW_GCM) || (defined(ENABLE_QAT_SW_GCM) \ && !defined(QAT_INSECURE_ALGO)) nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); # ifndef QAT_INSECURE_ALGO if (nid == NID_aes_128_gcm) goto fallback; # endif #endif p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->iv_len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); if (p != NULL) { size_t taglen = (ctx->tag_len != UNINITIALISED_SIZET) ? ctx->tag_len : GCM_TAG_MAX_SIZE; if (!OSSL_PARAM_set_size_t(p, taglen)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (ctx->iv_len > p->data_size) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->iv_len) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->iv_len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (ctx->iv_len > p->data_size) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->iv_len) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->iv_len)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { sz = p->data_size; if (sz == 0 || sz > EVP_GCM_TLS_TAG_LEN || !ctx->enc || ctx->tag_len == UNINITIALISED_SIZET) { #ifdef ENABLE_QAT_HW_GCM if (ctx->tag_set) QATerr(ERR_LIB_PROV, PROV_R_INVALID_TAG); ret = 0; ctx->tag_set = 0; goto end; #else return 0; #endif } if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } #ifdef ENABLE_QAT_HW_GCM if (!ctx->tag_set) { ctx->tag_set = 0; goto end; } ctx->tag_set = 0; #endif } return 1; #ifdef ENABLE_QAT_HW_GCM end: if (ctx->sw_ctx) { QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); ret = sw_aes_gcm_cipher.get_ctx_params(ctx->sw_ctx, params); } #endif return ret; #ifndef QAT_INSECURE_ALGO fallback: QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (ctx->sw_ctx || (ctx->sw_ctx = sw_aes_gcm_cipher.newctx(ctx))) return sw_aes_gcm_cipher.get_ctx_params(ctx->sw_ctx, params); return 0; #endif } int qat_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; const OSSL_PARAM *p; size_t sz = 0; void *vp; #if defined(ENABLE_QAT_HW_GCM) || (defined(ENABLE_QAT_SW_GCM) \ && !defined(QAT_INSECURE_ALGO)) nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); # ifndef QAT_INSECURE_ALGO if (nid == NID_aes_128_gcm) goto fallback; # endif #endif if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { vp = ctx->buf; if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (sz == 0 || ctx->enc) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_TAG); return 0; } ctx->tag_len = sz; #ifdef ENABLE_QAT_HW_GCM ctx->tag_set = 1; #endif } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &sz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } if (sz == 0 || sz > ctx->iv_len) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } ctx->iv_len = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) sz = qat_aes_gcm_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data); #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) sz = vaesgcm_ciphers_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data); #endif if (sz == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD); return 0; } ctx->tls_aad_pad_sz = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } #ifdef ENABLE_QAT_HW_GCM if (qat_aes_gcm_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, p->data_size, p->data) == 0) { #else if (vaesgcm_ciphers_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, p->data_size, p->data) == 0) { #endif ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV); if (p != NULL) { if (p->data == NULL || p->data_type != OSSL_PARAM_OCTET_STRING #ifdef ENABLE_QAT_HW_GCM || !qat_aes_gcm_ctrl(ctx, EVP_CTRL_GCM_SET_IV_INV, p->data_size, p->data)) #else || !vaesgcm_ciphers_ctrl(ctx, EVP_CTRL_GCM_SET_IV_INV, p->data_size, p->data)) #endif return 0; } #ifdef ENABLE_QAT_HW_GCM if (ctx->sw_ctx) { QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); sw_aes_gcm_cipher.set_ctx_params(ctx->sw_ctx, params); } #endif return 1; #ifndef QAT_INSECURE_ALGO fallback: if (ctx->sw_ctx) { QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); return sw_aes_gcm_cipher.set_ctx_params(ctx->sw_ctx, params); } return 0; #endif } int qat_gcm_einit(void *vctx, const unsigned char* inkey, int keylen, const unsigned char* iv, int ivlen, int enc) { int sts = 0; QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; #ifndef QAT_INSECURE_ALGO nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); if (nid == NID_aes_128_gcm) goto fallback; #endif #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) sts = qat_aes_gcm_init(ctx, inkey, keylen, iv, ivlen, 1); #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) sts = vaesgcm_ciphers_init(ctx, inkey, iv, 1); #endif return sts; # ifndef QAT_INSECURE_ALGO fallback: OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (ctx->sw_ctx || (ctx->sw_ctx = sw_aes_gcm_cipher.newctx(ctx))) return sw_aes_gcm_cipher.einit(ctx->sw_ctx, inkey, keylen, iv, ivlen, params); return 0; # endif } int qat_gcm_dinit(void *vctx, const unsigned char* inkey, int keylen, const unsigned char* iv, int ivlen, int enc) { int sts = 0; QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; #ifndef QAT_INSECURE_ALGO nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); if (nid == NID_aes_128_gcm) goto fallback; #endif #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) sts = qat_aes_gcm_init(ctx, inkey, keylen, iv, ivlen, 0); #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) sts = vaesgcm_ciphers_init(ctx, inkey, iv, 0); #endif return sts; #ifndef QAT_INSECURE_ALGO fallback: OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (!ctx->sw_ctx) ctx->sw_ctx = sw_aes_gcm_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); return sw_aes_gcm_cipher.dinit(ctx->sw_ctx, inkey, keylen, iv, ivlen, params); #endif } int qat_gcm_stream_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) int ret = 0; QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; #endif #ifndef QAT_INSECURE_ALGO nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); if (nid == NID_aes_128_gcm) { goto fallback; } #endif #ifndef ENABLE_QAT_FIPS if (inl == 0) { *outl = 0; ret = 1; goto end; } #endif if (outsize < inl) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) { if ((ret = qat_aes_gcm_cipher(ctx, out, outl, outsize, in, inl)) <= 0) { QATerr(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); goto end; } } #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) { if ((ret = vaesgcm_ciphers_do_cipher(ctx, out, outl, in, inl)) <= 0) { QATerr(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); goto end; } } #endif ret = 1; end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; #ifndef QAT_INSECURE_ALGO fallback: QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (sw_aes_gcm_cipher.cupdate == NULL) return 0; if (sw_aes_gcm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) { return 0; } return 1; #endif } int qat_gcm_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { int ret = 0; #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; #endif #ifndef QAT_INSECURE_ALGO nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); if (nid == NID_aes_128_gcm) goto fallback; #endif int i = 0; if (!qat_prov_is_running()) goto end; #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) i = qat_aes_gcm_cipher(ctx, out, outl, outsize, NULL, 0); #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) i = vaesgcm_ciphers_do_cipher(ctx, out, outl, NULL, 0); #endif if (i <= 0) goto end; *outl = 0; ret = 1; end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; #ifndef QAT_INSECURE_ALGO fallback: QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (sw_aes_gcm_cipher.cfinal == NULL) return 0; i = sw_aes_gcm_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); return i; #endif } int qat_gcm_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { int ret = 0; #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) QAT_GCM_CTX *ctx = (QAT_GCM_CTX *)vctx; #endif #ifndef QAT_INSECURE_ALGO nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); if (nid == NID_aes_128_gcm) goto fallback; #endif #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running()) goto end; if (outsize < inl) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) { if (qat_aes_gcm_cipher(ctx, out, outl, outsize, in, inl) <= 0) goto end; } #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) { if (vaesgcm_ciphers_do_cipher(ctx, out, outl, in, inl) <= 0) goto end; } #endif *outl = inl; ret = 1; end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; #ifndef QAT_INSECURE_ALGO fallback: QAT_EVP_CIPHER sw_aes_gcm_cipher = get_default_cipher_aes_gcm(nid); if (sw_aes_gcm_cipher.cupdate == NULL) return 0; if (sw_aes_gcm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) return 0; return 1; #endif } static void qat_aes_gcm_freectx(void *vctx) { QAT_AES_GCM_CTX *ctx = (QAT_AES_GCM_CTX *)vctx; if (ctx->cipher){ OPENSSL_free(ctx->cipher); ctx->cipher = NULL; } #ifdef ENABLE_QAT_HW_GCM if (qat_hw_gcm_offload) qat_aes_gcm_cleanup((QAT_GCM_CTX *)ctx); #endif #ifdef ENABLE_QAT_SW_GCM if (qat_sw_gcm_offload) vaesgcm_ciphers_cleanup((QAT_GCM_CTX *)ctx); #endif OPENSSL_clear_free(ctx, sizeof(*ctx)); } static const OSSL_PARAM qat_cipher_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_cipher_generic_gettable_params(ossl_unused void *provctx) { return qat_cipher_known_gettable_params; } int qat_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static const OSSL_PARAM qat_cipher_aead_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_cipher_aead_gettable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_cipher_aead_known_gettable_ctx_params; } static const OSSL_PARAM qat_cipher_aead_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_cipher_aead_settable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_cipher_aead_known_settable_ctx_params; } /* qat_aes128gcm_functions */ QAT_aes_gcm_cipher(qat_aes, gcm, GCM, AEAD_FLAGS, 128, 8, 96, NID_aes_128_gcm); /* qat_aes192gcm_functions */ QAT_aes_gcm_cipher(qat_aes, gcm, GCM, AEAD_FLAGS, 192, 8, 96, NID_aes_192_gcm); /* qat_aes256gcm_functions */ QAT_aes_gcm_cipher(qat_aes, gcm, GCM, AEAD_FLAGS, 256, 8, 96, NID_aes_256_gcm); #endif qatengine-1.9.0/qat_prov_ciphers.h000066400000000000000000000272621500416242000172200ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_ciphers.h * * This file provides an interface to Qat provider AES-GCM operations * *****************************************************************************/ #ifndef QAT_PROV_CIPHERS_H # define QAT_PROV_CIPHERS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "e_qat.h" #ifdef ENABLE_QAT_HW_GCM # include "cpa.h" # include "cpa_types.h" # include "cpa_cy_sym.h" # include "cpa_cy_drbg.h" #endif # ifdef ENABLE_QAT_SW_GCM # include #endif #define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ #define GCM_TAG_MAX_SIZE 16 #define PROV_CIPHER_FLAG_AEAD 0x0001 #define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 #define PROV_CIPHER_FLAG_CTS 0x0004 #define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 #define PROV_CIPHER_FLAG_RAND_KEY 0x0010 #define GCM_IV_MAX_SIZE (1024 / 8) #define QAT_AES_BLOCK_SIZE 16 typedef struct qat_evp_aes_cbc_cipher_st { int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup) (EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; # endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; }QAT_EVP_CIPHER; # pragma pack(push, 16) typedef struct qat_gcm_ctx_st { #ifdef ENABLE_QAT_SW_GCM /* gcm_key_data to be at the top for 64 byte alignment * needed by IPsec_mb library */ struct gcm_key_data key_data; struct gcm_context_data gcm_ctx; int init_flags; unsigned int ckey_set; unsigned char* tls_aad; unsigned int tls_aad_set; unsigned char* tag; unsigned char* calculated_tag; unsigned int tag_calculated; #endif #ifdef ENABLE_QAT_HW_GCM int inst_num; CpaCySymSessionSetupData* session_data; CpaCySymSessionCtx qat_ctx; int init_params_set; /* This flag is set to 1 when the session has been initialized */ int is_session_init; /* QAT Op Params */ CpaCySymOpData OpData; /* TODO Both buffer point to the same area of memory * and the operation is done in place. * Why am I using 2 separate buffers instead of one like in GCM sample? * Do I need to allocate and use separate metadata? */ CpaBufferList srcBufferList; CpaBufferList dstBufferList; CpaFlatBuffer srcFlatBuffer; CpaFlatBuffer dstFlatBuffer; /* -- Crypto -- */ /* Pointer to AAD. * In the TLS case this will contain the TLS header */ Cpa8U *aad; /* Size of the meta data for the driver * It cannot allocate memory so this must be done by the user application */ unsigned int meta_size; /* Pointer to pCipherKey */ Cpa8U *cipher_key; /* Flag to keep track of key passed */ int key_set; int qat_svm; int fallback; #endif EVP_CIPHER_CTX *sw_ctx; int sw_tls_ctrl; int tls_aad_len; int tag_len; int iv_len; unsigned int iv_set; unsigned int tag_set; int iv_gen; unsigned char* next_iv; unsigned char* iv; unsigned int mode; /* The mode that we are using */ size_t keylen; size_t ivlen_min; size_t tls_aad_pad_sz; uint64_t tls_enc_records; /* Number of TLS records encrypted */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ size_t num; size_t bufsz; /* Number of bytes in buf */ unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */ unsigned int pad:1; /* Whether padding should be used or not */ unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ unsigned char buf[QAT_AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ OSSL_LIB_CTX *libctx; /* needed for rand calls */ ctr128_f ctr; } __attribute__((aligned(64))) QAT_GCM_CTX; # pragma pack(pop) typedef struct qat_aes_gcm_ctx_st { QAT_GCM_CTX base; QAT_EVP_CIPHER *cipher; }QAT_AES_GCM_CTX; int qat_aes_gcm_ctx_get_nid(const QAT_AES_GCM_CTX *ctx); void qat_gcm_initctx(void *provctx, QAT_GCM_CTX *ctx, size_t keybits, size_t ivlen_min); int qat_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]); int qat_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]); int qat_gcm_einit(void *ctx, const unsigned char* inkey, int keylen, const unsigned char* iv, int ivlen, int enc); int qat_gcm_dinit(void *ctx, const unsigned char* inkey, int keylen, const unsigned char* iv, int ivlen, int enc); int qat_gcm_stream_update(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); int qat_gcm_stream_final(void *ctx, unsigned char *out, size_t *outl, size_t outsize); int qat_gcm_cipher(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); QAT_EVP_CIPHER get_default_cipher_aes_gcm(int nid); #define QAT_aes_gcm_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits,nid) \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ return qat_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits,nid); \ } \ const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))qat_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))qat_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))qat_##lc##_stream_update }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))qat_##lc##_stream_final }, \ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))qat_##lc##_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void)) qat_##lc##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void)) qat_##lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))qat_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))qat_cipher_aead_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))qat_cipher_aead_settable_ctx_params }, \ { 0, NULL } \ } #endif /* QAT_PROV_CIPHERS_H */ qatengine-1.9.0/qat_prov_cmvp.c000066400000000000000000000247211500416242000165200ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_cmvp.c * * This file contains the qatprovider FIPs CMVP features implementation * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifdef QAT_HW # define NID_dh2048 1126 # define NID_dh3072 1127 # define NID_dh4096 1128 # define NID_dh8192 1130 # define MAX_DH_SIZE 1024 #endif #include "qat_prov_cmvp.h" #ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; int qat_fips_service_indicator = 0; int qat_provider_info(void) { INFO("Module Info\n"); INFO("\tName: %s\n", QAT_FIPS_PROVIDER_NAME); INFO("\tID: %s\n", QAT_FIPS_PROVIDER_ID); INFO("\tVersion: %s\n", QAT_FIPS_PROVIDER_VERSION); # ifdef QAT_HW INFO("\tQAT_HW Driver version: %s\n", QAT_HW_DRIVER_version); # endif # ifdef QAT_SW INFO("\tIPSec-mb version: %s\n", QAT_FIPS_IPSec_mb_QAT_SW_VERSION); INFO("\tIPP-crypto version: %s\n\n", QAT_FIPS_IPP_crypto_QAT_SW_VERSION); # endif return 0; } # ifdef QAT_HW /* * DSA FIPS range Supported in QAT {L,N} = {2048, 224}, {2048, 256}, {3072, 256} */ int dsa_fips_range[3][2] = { {2048, 224}, {2048, 256}, {3072, 256} }; /* * DSA FIPS range check is performed so that if the sizes of P and Q are not in * the range supported by QAT engine then fall back to software */ int dsa_fips_range_check(int plen, int qlen) { int i, j, range = 0; for (i = 0, j = 0; i < 3; i++) { if ((plen == dsa_fips_range[i][j]) && (qlen == dsa_fips_range[i][j + 1])) { range = 1; break; } } return range; } # endif char *qat_fips_ec_non_approved_curve(int nid) { switch (nid) { case NID_X9_62_prime192v1: return "Prime-Curve P-192"; case NID_sect163r2: return "Binary-Curve B-163"; case NID_sect163k1: return "Binary-Curve K-163"; # ifdef QAT_SW case NID_secp224r1: return "Prime-Curve P-224"; case NID_secp521r1: return "Prime-Curve P-521"; case NID_sect233k1: return "Binary-Curve K-233"; case NID_sect283k1: return "Binary-Curve K-283"; case NID_sect409k1: return "Binary-Curve K-409"; case NID_sect571k1: return "Binary-Curve K-571"; case NID_sect233r1: return "Binary-Curve B-233"; case NID_sect283r1: return "Binary-Curve B-283"; case NID_sect409r1: return "Binary-Curve B-409"; case NID_sect571r1: return "Binary-Curve B-571"; # endif default: INFO("Unsupported EC Curve\n"); return NULL; } } int qat_fips_ec_check_approved_curve(const EC_KEY *eckey) { const EC_GROUP *group; int curve_name; group = EC_KEY_get0_group(eckey); curve_name = EC_GROUP_get_curve_name(group); switch (curve_name) { case NID_X9_62_prime256v1: case NID_secp384r1: # ifdef QAT_HW case NID_secp224r1: case NID_secp521r1: case NID_sect233k1: case NID_sect283k1: case NID_sect409k1: case NID_sect571k1: case NID_sect233r1: case NID_sect283r1: case NID_sect409r1: case NID_sect571r1: # endif return 1; default: if (qat_fips_ec_non_approved_curve(curve_name) != NULL) { INFO("%s is FIPS non approved curve\n", qat_fips_ec_non_approved_curve(curve_name)); } return 0; } } # ifdef QAT_HW static unsigned int get_dh_nid(int size) { switch (size) { case 2048: return NID_dh2048; case 3072: return NID_dh3072; case 4096: return NID_dh4096; case 8192: return NID_dh8192; default: return 0; } } int qat_fips_dh_safe_group(const DH *dh) { int nid, plen; const BIGNUM *p = NULL; p = DH_get0_p(dh); plen = BN_num_bits(p); nid = get_dh_nid(plen); switch (nid) { case NID_ffdhe2048: case NID_ffdhe3072: case NID_ffdhe4096: case NID_ffdhe8192: return plen; default: INFO("%d is FIPS non approved size\n", plen); return 0; } } # endif int qat_fips_ec_key_private_check(const EC_KEY *eckey) { if (eckey == NULL || eckey->group == NULL || eckey->priv_key == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (BN_cmp(eckey->priv_key, BN_value_one()) < 0 || BN_cmp(eckey->priv_key, eckey->group->order) >= 0) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); return 0; } return 1; } int qat_fips_ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx) { int ret = 0; EC_POINT *point = NULL; if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL || eckey->priv_key == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } point = EC_POINT_new(eckey->group); if (point == NULL) goto err; if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) { ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); goto err; } ret = 1; err: EC_POINT_free(point); return ret; } int qat_fips_ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key) { int ret = 0; BIGNUM *x, *y; BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); if (y == NULL) goto err; if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx)) goto err; if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) { if (BN_is_negative(x) || BN_cmp(x, key->group->field) >= 0 || BN_is_negative(y) || BN_cmp(y, key->group->field) >= 0) { goto err; } } else { int m = EC_GROUP_get_degree(key->group); if (BN_num_bits(x) > m || BN_num_bits(y) > m) { goto err; } } ret = 1; err: BN_CTX_end(ctx); return ret; } int qat_fips_ec_key_public_check_quick(const EC_KEY *eckey, BN_CTX *ctx) { if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } /* Test Q != infinity */ if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY); return 0; } /* Test if the public key is in range */ if (!qat_fips_ec_key_public_range_check(ctx, eckey)) { ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE); return 0; } /* Test is the pub_key on the elliptic curve */ if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE); return 0; } return 1; } int qat_fips_ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx) { int ret = 0; EC_POINT *point = NULL; const BIGNUM *order = NULL; if (!qat_fips_ec_key_public_check_quick(eckey, ctx)) return 0; point = EC_POINT_new(eckey->group); if (point == NULL) return 0; order = eckey->group->order; if (BN_is_zero(order)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } /* Test pub_key * order is the point at infinity. */ if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } if (!EC_POINT_is_at_infinity(eckey->group, point)) { ERR_raise(ERR_LIB_EC, EC_R_WRONG_ORDER); goto err; } ret = 1; err: EC_POINT_free(point); return ret; } int qat_fips_ec_key_simple_check_key(const EC_KEY *eckey) { int ok = 0; BN_CTX *ctx = NULL; if (eckey == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) return 0; if (!qat_fips_ec_key_public_check(eckey, ctx)) goto err; if (eckey->priv_key != NULL) { if (!qat_fips_ec_key_private_check(eckey) || !qat_fips_ec_key_pairwise_check(eckey, ctx)) goto err; } ok = 1; err: BN_CTX_free(ctx); return ok; } int qat_fips_get_key_zeroize_status(void) { if (qat_fips_key_zeroize == 1) DEBUG("zeroization done successfully!!..\n"); else INFO("zeroization failure!!..\n"); return qat_fips_key_zeroize; } int qat_fips_get_approved_status(void) { if (qat_fips_service_indicator) { DEBUG("Running FIPS approved service.\n"); return 1; } else { INFO("Requested service is not a FIPS approved service.\n"); return 0; } } #endif qatengine-1.9.0/qat_prov_cmvp.h000066400000000000000000000062061500416242000165230ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_cmvp.h * * This file provides an interface to qatprovider FIPs CMVP features. * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #include "qat_utils.h" #include "qat_prov_ec.h" #include "qat_fips.h" #define QAT_FIPS_PROVIDER_NAME "QAT Provider FIPS" #define QAT_FIPS_PROVIDER_ID "qatprovider" #define QAT_FIPS_PROVIDER_VERSION "QAT Engine v1.3.1" #ifdef QAT_HW #define QAT_HW_DRIVER_version "QAT20.l.1.0.40-00004" #endif #ifdef QAT_SW #define QAT_FIPS_IPSec_mb_QAT_SW_VERSION "v1.3" #define QAT_FIPS_IPP_crypto_QAT_SW_VERSION "ippcp_2021.7.1" #endif #define FIPS_RSA_SIGN_MIN_SIZE 2048 #define FIPS_RSA_VER_MIN_SIZE 1024 #define FIPS_RSA_MAX_SIZE 4096 #define FIPS_DSA_VER_MIN_SIZE 1024 extern int qat_provider_info(void); int qat_fips_ec_check_approved_curve(const EC_KEY *eckey); #ifdef QAT_HW int qat_fips_dh_safe_group(const DH *dh); #endif int qat_fips_ec_key_simple_check_key(const EC_KEY *eckey); int qat_fips_get_key_zeroize_status(void); int qat_fips_get_approved_status(void); #ifdef QAT_HW int dsa_fips_range_check(int plen, int qlen); #endif qatengine-1.9.0/qat_prov_dh.c000066400000000000000000000506241500416242000161470ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_dh.c * * This file contains the Qat Provider implementation for DH operations * *****************************************************************************/ #include "e_qat.h" #include "qat_utils.h" #include "qat_hw_dh.h" #include "qat_provider.h" #include "qat_prov_dh.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #define QAT_FIPS_DH_MIN_RANGE 2048 #ifdef ENABLE_QAT_HW_DH # ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; # endif static OSSL_FUNC_keyexch_newctx_fn qat_dh_newctx; static OSSL_FUNC_keyexch_init_fn qat_dh_init; static OSSL_FUNC_keyexch_set_peer_fn qat_dh_set_peer; static OSSL_FUNC_keyexch_derive_fn qat_dh_derive; static OSSL_FUNC_keyexch_freectx_fn qat_dh_freectx; static OSSL_FUNC_keyexch_dupctx_fn qat_dh_dupctx; static OSSL_FUNC_keyexch_set_ctx_params_fn qat_dh_set_ctx_params; static OSSL_FUNC_keyexch_settable_ctx_params_fn qat_dh_settable_ctx_params; static OSSL_FUNC_keyexch_get_ctx_params_fn qat_dh_get_ctx_params; static OSSL_FUNC_keyexch_gettable_ctx_params_fn qat_dh_gettable_ctx_params; static int qat_DH_up_ref(DH *r) { int i; # if OPENSSL_VERSION_NUMBER < 0x30200000 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) return 0; # else if (QAT_CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; # endif if (i < 2) { WARN("refcount error.\n"); return 0; } return ((i > 1) ? 1 : 0); } static void qat_ffc_params_init(FFC_PARAMS *params) { memset(params, 0, sizeof(*params)); params->pcounter = -1; params->gindex = FFC_UNVERIFIABLE_GINDEX; params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; } static void qat_ffc_params_cleanup(FFC_PARAMS *params) { BN_free(params->p); BN_free(params->q); BN_free(params->g); BN_free(params->j); OPENSSL_free(params->seed); qat_ffc_params_init(params); } void qat_DH_free(DH *r) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif int i; if (r == NULL) return; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_DOWN_REF(&r->references, &i, r->lock); # else QAT_CRYPTO_DOWN_REF(&r->references, &i); # endif if (i > 0) return; if (i < 0) { WARN("refcount error.\n"); } if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(r->lock); # endif qat_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } static int qat_DH_size(const DH *dh) { if (dh->params.p != NULL) return BN_num_bytes(dh->params.p); return -1; } static void qat_DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) { if (pub_key != NULL) *pub_key = dh->pub_key; if (priv_key != NULL) *priv_key = dh->priv_key; } FFC_PARAMS *qat_dh_get0_params(DH *dh) { return &dh->params; } int qat_dh_get0_nid(const DH *dh) { return dh->params.nid; } int qat_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) { return BN_cmp(a->p, b->p) == 0 && BN_cmp(a->g, b->g) == 0 && (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ } int qat_dh_check_key(OSSL_LIB_CTX *ctx, const DH *dh) { #ifdef ENABLE_QAT_FIPS if (!qat_fips_dh_safe_group(dh)) { WARN("Invalid DH group.\n"); return 0; } #endif #if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) if (qat_securitycheck_enabled(ctx)) { size_t L, N; const BIGNUM *p, *q; if (dh == NULL) return 0; p = DH_get0_p(dh); q = DH_get0_q(dh); if (p == NULL || q == NULL) return 0; L = BN_num_bits(p); if (L < 2048) return 0; /* If it is a safe prime group then it is ok */ if (DH_get_nid(dh)) return 1; /* If not then it must be FFC, which only allows certain sizes. */ N = BN_num_bits(q); return (L == 2048 && (N == 224 || N == 256)); } #endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ return 1; } static void *qat_dh_newctx(void *provctx) { QAT_PROV_DH_CTX *pdhctx; if (!qat_prov_is_running()) return NULL; pdhctx = OPENSSL_zalloc(sizeof(QAT_PROV_DH_CTX)); if (pdhctx == NULL) return NULL; pdhctx->libctx = prov_libctx_of(provctx); pdhctx->kdf_type = PROV_DH_KDF_NONE; return pdhctx; } static int qat_dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[]) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; if (!qat_prov_is_running() || pdhctx == NULL || vdh == NULL || !qat_DH_up_ref(vdh)) return 0; qat_DH_free(pdhctx->dh); pdhctx->dh = vdh; pdhctx->kdf_type = PROV_DH_KDF_NONE; return qat_dh_set_ctx_params(pdhctx, params) && qat_dh_check_key(pdhctx->libctx, vdh); } /* The 2 parties must share the same domain parameters */ static int qat_dh_match_params(DH *priv, DH *peer) { int ret; FFC_PARAMS *dhparams_priv = qat_dh_get0_params(priv); FFC_PARAMS *dhparams_peer = qat_dh_get0_params(peer); ret = dhparams_priv != NULL && dhparams_peer != NULL && qat_ffc_params_cmp(dhparams_priv, dhparams_peer, 1); if (!ret) QATerr(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS); return ret; } static int qat_dh_set_peer(void *vpdhctx, void *vdh) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; if (!qat_prov_is_running() || pdhctx == NULL || vdh == NULL || !qat_dh_match_params(vdh, pdhctx->dh) || !qat_DH_up_ref(vdh)) return 0; qat_DH_free(pdhctx->dhpeer); pdhctx->dhpeer = vdh; return 1; } static int qat_dh_plain_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen, size_t outlen) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; int ret; size_t dhsize; const BIGNUM *pub_key = NULL; if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_KEY); return 0; } dhsize = (size_t)qat_DH_size(pdhctx->dh); if (secret == NULL) { *secretlen = dhsize; return 1; } if (outlen < dhsize) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } qat_DH_get0_key(pdhctx->dhpeer, &pub_key, NULL); ret = qat_dh_compute_key(secret, pub_key, pdhctx->dh); if (ret <= 0) return 0; *secretlen = ret; return 1; } int qat_dh_kdf_X9_42_asn1(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const char *cek_alg, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md, OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; EVP_KDF_CTX *kctx = NULL; EVP_KDF *kdf = NULL; OSSL_PARAM params[5], *p = params; const char *mdname = EVP_MD_get0_name(md); kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X942KDF_ASN1, propq); kctx = EVP_KDF_CTX_new(kdf); if (kctx == NULL) goto err; *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (unsigned char *)Z, Zlen); if (ukm != NULL) *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, (unsigned char *)ukm, ukmlen); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, (char *)cek_alg, 0); *p = OSSL_PARAM_construct_end(); ret = EVP_KDF_derive(kctx, out, outlen, params) > 0; err: EVP_KDF_CTX_free(kctx); EVP_KDF_free(kdf); return ret; } static int qat_dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen, size_t outlen) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; unsigned char *stmp = NULL; size_t stmplen; int ret = 0; if (secret == NULL) { *secretlen = pdhctx->kdf_outlen; return 1; } if (pdhctx->kdf_outlen > outlen) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!qat_dh_plain_derive(pdhctx, NULL, &stmplen, 0)) return 0; if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return 0; } if (!qat_dh_plain_derive(pdhctx, stmp, &stmplen, stmplen)) goto err; /* Do KDF stuff */ if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) { if (!qat_dh_kdf_X9_42_asn1(secret, pdhctx->kdf_outlen, stmp, stmplen, pdhctx->kdf_cekalg, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen, pdhctx->kdf_md, pdhctx->libctx, NULL)) goto err; } *secretlen = pdhctx->kdf_outlen; ret = 1; err: OPENSSL_secure_clear_free(stmp, stmplen); return ret; } static int qat_dh_derive(void *vpdhctx, unsigned char *secret, size_t *psecretlen, size_t outlen) { int ret = 0; QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; #ifdef ENABLE_QAT_FIPS const BIGNUM *p = DH_get0_p(pdhctx->dh); int plen = BN_num_bits(p); if(plen < QAT_FIPS_DH_MIN_RANGE) { INFO("%d is FIPS non approved key size\n", plen); goto end; } qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running()) goto end; switch (pdhctx->kdf_type) { case PROV_DH_KDF_NONE: ret = qat_dh_plain_derive(pdhctx, secret, psecretlen, outlen); goto end; case PROV_DH_KDF_X9_42_ASN1: ret = qat_dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen); goto end; default: break; } end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static void qat_dh_freectx(void *vpdhctx) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; OPENSSL_free(pdhctx->kdf_cekalg); qat_DH_free(pdhctx->dh); qat_DH_free(pdhctx->dhpeer); EVP_MD_free(pdhctx->kdf_md); OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen); OPENSSL_free(pdhctx); } static void *qat_dh_dupctx(void *vpdhctx) { QAT_PROV_DH_CTX *srcctx = (QAT_PROV_DH_CTX *)vpdhctx; QAT_PROV_DH_CTX *dstctx; if (!qat_prov_is_running()) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; *dstctx = *srcctx; dstctx->dh = NULL; dstctx->dhpeer = NULL; dstctx->kdf_md = NULL; dstctx->kdf_ukm = NULL; dstctx->kdf_cekalg = NULL; if (srcctx->dh != NULL && !qat_DH_up_ref(srcctx->dh)) goto err; else dstctx->dh = srcctx->dh; if (srcctx->dhpeer != NULL && !qat_DH_up_ref(srcctx->dhpeer)) goto err; else dstctx->dhpeer = srcctx->dhpeer; if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md)) goto err; else dstctx->kdf_md = srcctx->kdf_md; /* Duplicate UKM data if present */ if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) { dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, srcctx->kdf_ukmlen); if (dstctx->kdf_ukm == NULL) goto err; } if (srcctx->kdf_cekalg != NULL) { dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg); if (dstctx->kdf_cekalg == NULL) goto err; } return dstctx; err: qat_dh_freectx(dstctx); return NULL; } static int qat_dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[]) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; const OSSL_PARAM *p; unsigned int pad; char name[80] = {'\0'}; /* should be big enough */ char *str = NULL; if (pdhctx == NULL) return 0; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); if (p != NULL) { str = name; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) return 0; if (name[0] == '\0') pdhctx->kdf_type = PROV_DH_KDF_NONE; else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0) pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1; else return 0; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); if (p != NULL) { char mdprops[80] = {'\0'}; /* should be big enough */ str = name; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) return 0; str = mdprops; p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); if (p != NULL) { if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) return 0; } EVP_MD_free(pdhctx->kdf_md); pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); if (pdhctx->kdf_md == NULL) return 0; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); if (p != NULL) { size_t outlen; if (!OSSL_PARAM_get_size_t(p, &outlen)) return 0; pdhctx->kdf_outlen = outlen; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); if (p != NULL) { void *tmp_ukm = NULL; size_t tmp_ukmlen; OPENSSL_free(pdhctx->kdf_ukm); pdhctx->kdf_ukm = NULL; pdhctx->kdf_ukmlen = 0; /* ukm is an optional field so it can be NULL */ if (p->data != NULL && p->data_size != 0) { if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) return 0; pdhctx->kdf_ukm = tmp_ukm; pdhctx->kdf_ukmlen = tmp_ukmlen; } } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); if (p != NULL) { if (!OSSL_PARAM_get_uint(p, &pad)) return 0; pdhctx->pad = pad ? 1 : 0; } p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG); if (p != NULL) { str = name; OPENSSL_free(pdhctx->kdf_cekalg); pdhctx->kdf_cekalg = NULL; if (p->data != NULL && p->data_size != 0) { if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) return 0; pdhctx->kdf_cekalg = OPENSSL_strdup(name); if (pdhctx->kdf_cekalg == NULL) return 0; } } return 1; } static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), OSSL_PARAM_END}; static const OSSL_PARAM *qat_dh_settable_ctx_params(ossl_unused void *vpdhctx, ossl_unused void *provctx) { return known_settable_ctx_params; } static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL, 0), OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), OSSL_PARAM_END}; static const OSSL_PARAM *qat_dh_gettable_ctx_params(ossl_unused void *vpdhctx, ossl_unused void *provctx) { return known_gettable_ctx_params; } static int qat_dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) { QAT_PROV_DH_CTX *pdhctx = (QAT_PROV_DH_CTX *)vpdhctx; OSSL_PARAM *p; if (pdhctx == NULL) return 0; p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); if (p != NULL) { const char *kdf_type = NULL; switch (pdhctx->kdf_type) { case PROV_DH_KDF_NONE: kdf_type = ""; break; case PROV_DH_KDF_X9_42_ASN1: kdf_type = OSSL_KDF_NAME_X942KDF_ASN1; break; default: return 0; } if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) return 0; } p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL ? "" : EVP_MD_get0_name(pdhctx->kdf_md))) { return 0; } p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen)) return 0; p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen)) return 0; p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL ? "" : pdhctx->kdf_cekalg)) return 0; return 1; } const OSSL_DISPATCH qat_dh_keyexch_functions[] = { {OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))qat_dh_newctx}, {OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))qat_dh_init}, {OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))qat_dh_derive}, {OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))qat_dh_set_peer}, {OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))qat_dh_freectx}, {OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))qat_dh_dupctx}, {OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))qat_dh_set_ctx_params}, {OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, (void (*)(void))qat_dh_settable_ctx_params}, {OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))qat_dh_get_ctx_params}, {OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, (void (*)(void))qat_dh_gettable_ctx_params}, {0, NULL}}; #endif /* ENABLE_QAT_HW_DH */ qatengine-1.9.0/qat_prov_dh.h000066400000000000000000000144251500416242000161530ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_dh.h * * This file provides an interface to Qat Provider DH operations * *****************************************************************************/ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifndef __USE_GNU #define __USE_GNU #endif #ifndef QAT_PROV_DH_H #define QAT_PROV_DH_H #include #include #include #include #include #include #include #include #include #include #include #include "e_qat.h" #define FFC_UNVERIFIABLE_GINDEX -1 #define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 #define FFC_PARAM_FLAG_VALIDATE_G 0x02 #define FFC_PARAM_FLAG_VALIDATE_PQG \ (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G) typedef struct ffc_params_st { /* Primes */ BIGNUM *p; BIGNUM *q; /* Generator */ BIGNUM *g; /* DH X9.42 Optional Subgroup factor j >= 2 where p = j * q + 1 */ BIGNUM *j; /* Required for FIPS186_4 validation of p, q and optionally canonical g */ unsigned char *seed; /* If this value is zero the hash size is used as the seed length */ size_t seedlen; /* Required for FIPS186_4 validation of p and q */ int pcounter; int nid; /* The identity of a named group */ /* * Required for FIPS186_4 generation & validation of canonical g. * It uses unverifiable g if this value is -1. */ int gindex; int h; /* loop counter for unverifiable g */ unsigned int flags; /* * The digest to use for generation or validation. If this value is NULL, * then the digest is chosen using the value of N. */ const char *mdname; const char *mdprops; #if OPENSSL_VERSION_NUMBER >= 0x30000060 /* Default key length for known named groups according to RFC7919 */ int keylength; #endif } FFC_PARAMS; struct dh_st { /* * This first argument is used to pick up errors when a DH is passed * instead of a EVP_PKEY */ int pad; int version; FFC_PARAMS params; /* max generated private key length (can be less than len(q)) */ int32_t length; BIGNUM *pub_key; /* g^x % p */ BIGNUM *priv_key; /* x */ int flags; BN_MONT_CTX *method_mont_p; CRYPTO_REF_COUNT references; #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; ENGINE *engine; #endif OSSL_LIB_CTX *libctx; const DH_METHOD *meth; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif /* Provider data */ size_t dirty_cnt; /* If any key material changes, increment this */ }; struct dh_method { char *name; /* Methods here */ int (*generate_key)(DH *dh); int (*compute_key)(unsigned char *key, const BIGNUM *pub_key, DH *dh); /* Can be null */ int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); int (*init)(DH *dh); int (*finish)(DH *dh); int flags; char *app_data; /* If this is non-NULL, it will be used to generate parameters */ int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb); }; /* * This type is only really used to handle some legacy related functionality. * If you need to use other KDF's (such as SSKDF) just use PROV_DH_KDF_NONE * here and then create and run a KDF after the key is derived. * Note that X942 has 2 variants of key derivation: * (1) DH_KDF_X9_42_ASN1 - which contains an ANS1 encoded object that has * the counter embedded in it. * (2) DH_KDF_X941_CONCAT - which is the same as ECDH_X963_KDF (which can be * done by creating a "X963KDF". */ enum kdf_type { PROV_DH_KDF_NONE = 0, PROV_DH_KDF_X9_42_ASN1 }; /* * What's passed as an actual key is defined by the KEYMGMT interface. * We happen to know that our KEYMGMT simply passes DH structures, so * we use that here too. */ typedef struct { OSSL_LIB_CTX *libctx; DH *dh; DH *dhpeer; unsigned int pad : 1; /* DH KDF */ /* KDF (if any) to use for DH */ enum kdf_type kdf_type; /* Message digest to use for key derivation */ EVP_MD *kdf_md; /* User key material */ unsigned char *kdf_ukm; size_t kdf_ukmlen; /* KDF output length */ size_t kdf_outlen; char *kdf_cekalg; } QAT_PROV_DH_CTX; void qat_DH_free(DH *r); #endif /* QAT_PROVIDER_DH_H */ qatengine-1.9.0/qat_prov_dsa.c000066400000000000000000000631751500416242000163300ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_dsa.c * * This file contains the Qat Provider implementation for DSA operations * *****************************************************************************/ #include "e_qat.h" #include "qat_evp.h" #include "qat_utils.h" #include "qat_hw_dsa.h" #include "qat_provider.h" #include "qat_prov_dsa.h" #ifdef ENABLE_QAT_HW_DSA #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif # ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; # endif static OSSL_FUNC_signature_newctx_fn qat_dsa_newctx; static OSSL_FUNC_signature_sign_init_fn qat_dsa_sign_init; static OSSL_FUNC_signature_verify_init_fn qat_dsa_verify_init; static OSSL_FUNC_signature_sign_fn qat_dsa_sign; static OSSL_FUNC_signature_verify_fn qat_dsa_verify; static OSSL_FUNC_signature_freectx_fn qat_dsa_freectx; static OSSL_FUNC_signature_set_ctx_params_fn qat_dsa_set_ctx_params; static OSSL_FUNC_signature_settable_ctx_params_fn qat_dsa_settable_ctx_params; struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; OSSL_FUNC_signature_sign_fn *sign; OSSL_FUNC_signature_verify_init_fn *verify_init; OSSL_FUNC_signature_verify_fn *verify; OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; OSSL_FUNC_signature_verify_recover_fn *verify_recover; OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; OSSL_FUNC_signature_digest_sign_fn *digest_sign; OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; OSSL_FUNC_signature_digest_verify_fn *digest_verify; OSSL_FUNC_signature_freectx_fn *freectx; OSSL_FUNC_signature_dupctx_fn *dupctx; OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } /* EVP_SIGNATURE */; static EVP_SIGNATURE get_default_dsa_signature() { static EVP_SIGNATURE s_signature; static int initialized = 0; if (!initialized) { EVP_SIGNATURE *signature = (EVP_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "DSA", "provider=default"); if (signature) { s_signature = *signature; EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); initialized = 1; } else { WARN("EVP_SIGNATURE_fetch from default provider failed"); } } return s_signature; } static void qat_ffc_params_init(FFC_PARAMS *params) { memset(params, 0, sizeof(*params)); params->pcounter = -1; params->gindex = FFC_UNVERIFIABLE_GINDEX; params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; } static void qat_ffc_params_cleanup(FFC_PARAMS *params) { BN_free(params->p); BN_free(params->q); BN_free(params->g); BN_free(params->j); OPENSSL_free(params->seed); qat_ffc_params_init(params); } static int qat_DSA_up_ref(DSA *r) { int i; # if OPENSSL_VERSION_NUMBER < 0x30200000 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) return 0; # else if (QAT_CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; # endif if (i < 2) { WARN("refcount error.\n"); return 0; } return ((i > 1) ? 1 : 0); } void qat_DSA_free(DSA *r) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif int i; if (r == NULL) return; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_DOWN_REF(&r->references, &i, r->lock); # else QAT_CRYPTO_DOWN_REF(&r->references, &i); # endif if (i > 0) return; if (i < 0) { WARN("refcount error.\n"); } if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(r->lock); # endif qat_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } static int qat_DSA_size(const DSA *dsa) { int ret = -1; DSA_SIG sig; if (dsa->params.q != NULL) { sig.r = sig.s = dsa->params.q; ret = i2d_DSA_SIG(&sig, NULL); if (ret < 0) ret = 0; } return ret; } static int qat_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign) { #if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) if (qat_securitycheck_enabled(ctx)) { size_t L, N; const BIGNUM *p, *q; if (dsa == NULL) return 0; p = DSA_get0_p(dsa); q = DSA_get0_q(dsa); if (p == NULL || q == NULL) return 0; L = BN_num_bits(p); N = BN_num_bits(q); /* * For Digital signature verification DSA keys with < 112 bits of * security strength (i.e L < 2048 bits), are still allowed for legacy * use. The bounds given in SP800 131Ar2 - Table 2 are * (512 <= L < 2048 and 160 <= N < 224) */ if (!sign && L < 2048) return (L >= 512 && N >= 160 && N < 224); /* Valid sizes for both sign and verify */ if (L == 2048 && (N == 224 || N == 256)) return 1; return (L == 3072 && N == 256); } #endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ return 1; } static int qat_digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len) { size_t i; if (md == NULL) return NID_undef; for (i = 0; i < it_len; i++) if (EVP_MD_is_a(md, it[i].ptr)) return (int)it[i].id; return NID_undef; } /* * Retrieve one of the FIPS approved hash algorithms by nid. * See FIPS 180-4 "Secure Hash Standard" and FIPS 202 - SHA-3. */ static int qat_digest_get_approved_nid(const EVP_MD *md) { static const OSSL_ITEM name_to_nid[] = { {NID_sha1, OSSL_DIGEST_NAME_SHA1}, {NID_sha224, OSSL_DIGEST_NAME_SHA2_224}, {NID_sha256, OSSL_DIGEST_NAME_SHA2_256}, {NID_sha384, OSSL_DIGEST_NAME_SHA2_384}, {NID_sha512, OSSL_DIGEST_NAME_SHA2_512}, {NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224}, {NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256}, {NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224}, {NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256}, {NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384}, {NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512}, }; return qat_digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid)); } static int qat_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md, int sha1_allowed) { int mdnid = qat_digest_get_approved_nid(md); return mdnid; } static size_t dsa_get_md_size(const QAT_PROV_DSA_CTX *pdsactx) { if (pdsactx->md != NULL) return EVP_MD_get_size(pdsactx->md); return 0; } static void *qat_dsa_newctx(void *provctx, const char *propq) { QAT_PROV_DSA_CTX *pdsactx; DEBUG("qat_dsa_newctx\n"); if (!qat_prov_is_running()) return NULL; pdsactx = OPENSSL_zalloc(sizeof(QAT_PROV_DSA_CTX)); if (pdsactx == NULL) return NULL; pdsactx->libctx = prov_libctx_of(provctx); pdsactx->flag_allow_md = 1; if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(pdsactx); pdsactx = NULL; QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); } return pdsactx; } static int dsa_setup_md(QAT_PROV_DSA_CTX *ctx, const char *mdname, const char *mdprops) { if (mdprops == NULL) mdprops = ctx->propq; if (mdname != NULL) { int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int md_nid = qat_digest_get_approved_nid_with_sha1(ctx->libctx, md, sha1_allowed); size_t mdname_len = strlen(mdname); if (md == NULL || md_nid < 0) { if (md == NULL) ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s could not be fetched", mdname); if (md_nid < 0) ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest=%s", mdname); if (mdname_len >= sizeof(ctx->mdname)) ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s exceeds name buffer length", mdname); EVP_MD_free(md); return 0; } if (!ctx->flag_allow_md) { if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest %s != %s", mdname, ctx->mdname); EVP_MD_free(md); return 0; } EVP_MD_free(md); return 1; } EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); /* * We do not care about DER writing errors. * All it really means is that for some reason, there's no * AlgorithmIdentifier to be had, but the operation itself is * still valid, just as long as it's not used to construct * anything that needs an AlgorithmIdentifier. */ ctx->aid_len = 0; ctx->mdctx = NULL; ctx->md = md; OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); } return 1; } static int dsa_signverify_init(void *vpdsactx, void *vdsa, const OSSL_PARAM params[], int operation) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; if (!qat_prov_is_running() || pdsactx == NULL) return 0; if (vdsa == NULL && pdsactx->dsa == NULL) { QATerr(ERR_LIB_PROV, PROV_R_NO_KEY_SET); return 0; } if (vdsa != NULL) { if (!qat_dsa_check_key(pdsactx->libctx, vdsa, operation == EVP_PKEY_OP_SIGN)) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; } if (!qat_DSA_up_ref(vdsa)) return 0; qat_DSA_free(pdsactx->dsa); pdsactx->dsa = vdsa; } pdsactx->operation = operation; if (!qat_dsa_set_ctx_params(pdsactx, params)) return 0; return 1; } static int qat_dsa_sign_int(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) { DSA_SIG *s; /* We use the dsa methods provided by qat */ dsa->meth = qat_get_DSA_methods(); s = qat_dsa_do_sign(dgst, dlen, dsa); if (s == NULL) { *siglen = 0; return 0; } *siglen = i2d_DSA_SIG(s, &sig); DSA_SIG_free(s); return 1; } static int qat_dsa_sign_init(void *vpdsactx, void *vdsa, const OSSL_PARAM params[]) { return dsa_signverify_init(vpdsactx, vdsa, params, EVP_PKEY_OP_SIGN); } static int qat_dsa_verify_init(void *vpdsactx, void *vdsa, const OSSL_PARAM params[]) { return dsa_signverify_init(vpdsactx, vdsa, params, EVP_PKEY_OP_VERIFY); } static int qat_dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; int ret = 0; unsigned int sltmp; size_t dsasize = qat_DSA_size(pdsactx->dsa); size_t mdsize = dsa_get_md_size(pdsactx); #ifdef ENABLE_QAT_FIPS int range_status = 0; const BIGNUM *p = DSA_get0_p(pdsactx->dsa); const BIGNUM *q = DSA_get0_q(pdsactx->dsa); int plen = BN_num_bits(p); int qlen = BN_num_bits(q); range_status = dsa_fips_range_check(plen, qlen); if (!range_status) { INFO("Given Key P&Q len {%d, %d} is not in FIPS approved range.\n", plen, qlen); INFO("FIPS approved P&Q len {2048, 224}, {2048, 256} & {3072, 256}.\n"); goto end; } qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running()) goto end; if (sig == NULL) { *siglen = dsasize; ret = 1; goto end; } if (sigsize < (size_t)dsasize) goto end; if (mdsize != 0 && tbslen != mdsize) goto end; ret = qat_dsa_sign_int(0, tbs, tbslen, sig, &sltmp, pdsactx->dsa); if (ret <= 0) goto end; *siglen = sltmp; ret = 1; end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static int qat_DSA_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int siglen, DSA *dsa) { DSA_SIG *s; const unsigned char *p = sigbuf; unsigned char *der = NULL; int derlen = -1; int ret = -1; #ifdef ENABLE_QAT_FIPS int range_status = 0; const BIGNUM *pdata = DSA_get0_p(dsa); const BIGNUM *qdata = DSA_get0_q(dsa); int plen = BN_num_bits(pdata); int qlen = BN_num_bits(qdata); range_status = dsa_fips_range_check(plen, qlen); if (plen != FIPS_DSA_VER_MIN_SIZE) { if (!range_status) { INFO("Given Key P&Q len {%d, %d} is not in FIPS approved range.\n", plen, qlen); INFO("FIPS approved P&Q len {2048, 224}, {2048, 256} & {3072, 256}.\n"); goto err; } qat_fips_service_indicator = 1; } else { INFO("Given Key size %d is Allowed. But, FIPS non-approved size\n", FIPS_DSA_VER_MIN_SIZE); } #endif s = DSA_SIG_new(); if (s == NULL) goto err; if (d2i_DSA_SIG(&s, &p, siglen) == NULL) goto err; /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_DSA_SIG(s, &der); if (derlen != siglen || memcmp(sigbuf, der, derlen)) goto err; ret = qat_dsa_do_verify(dgst, dgst_len, s, dsa); err: OPENSSL_clear_free(der, derlen); if (s != NULL) DSA_SIG_free(s); #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static int qat_dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; size_t mdsize = dsa_get_md_size(pdsactx); if (!qat_prov_is_running() || (mdsize != 0 && tbslen != mdsize)) return 0; return qat_DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa); } static void qat_dsa_freectx(void *vpdsactx) { QAT_PROV_DSA_CTX *ctx = (QAT_PROV_DSA_CTX *)vpdsactx; OPENSSL_free(ctx->propq); EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); ctx->propq = NULL; ctx->mdctx = NULL; ctx->md = NULL; qat_DSA_free(ctx->dsa); OPENSSL_free(ctx); } static int qat_dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[]) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; const OSSL_PARAM *p; if (pdsactx == NULL) return 0; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); if (p != NULL) { char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; const OSSL_PARAM *propsp = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PROPERTIES); if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) return 0; if (propsp != NULL && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) return 0; if (!dsa_setup_md(pdsactx, mdname, mdprops)) return 0; } return 1; } static const OSSL_PARAM settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END}; static const OSSL_PARAM settable_ctx_params_no_digest[] = { OSSL_PARAM_END}; static const OSSL_PARAM *qat_dsa_settable_ctx_params(void *vpdsactx, ossl_unused void *provctx) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; if (pdsactx != NULL && !pdsactx->flag_allow_md) return settable_ctx_params_no_digest; return settable_ctx_params; } static int qat_dsa_digest_sign_init(void *vpdsactx, const char *mdname, void *vdsa, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *vpdsactx, const char *mdname, void *vdsa, const OSSL_PARAM params[]); fun_ptr fun = get_default_dsa_signature().digest_sign_init; if (!fun) return 0; return fun(vpdsactx, mdname, vdsa, params); } int qat_dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data, size_t datalen) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; if (pdsactx == NULL || pdsactx->mdctx == NULL) return 0; return EVP_DigestUpdate(pdsactx->mdctx, data, datalen); } int qat_dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen, size_t sigsize) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (!qat_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) return 0; /* * If sig is NULL then we're just finding out the sig size. Other fields * are ignored. Defer to dsa_sign. */ if (sig != NULL) { /* * There is the possibility that some externally provided * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - * but that problem is much larger than just in DSA. */ if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen)) return 0; } pdsactx->flag_allow_md = 1; return qat_dsa_sign(vpdsactx, sig, siglen, sigsize, digest, (size_t)dlen); } static int qat_dsa_digest_verify_init(void *vpdsactx, const char *mdname, void *vdsa, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *vpdsactx, const char *mdname, void *vdsa, const OSSL_PARAM params[]); fun_ptr fun = get_default_dsa_signature().digest_verify_init; if (!fun) return 0; return fun(vpdsactx, mdname, vdsa, params); } int qat_dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig, size_t siglen) { QAT_PROV_DSA_CTX *pdsactx = (QAT_PROV_DSA_CTX *)vpdsactx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (!qat_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) return 0; /* * There is the possibility that some externally provided * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - * but that problem is much larger than just in DSA. */ if (!EVP_DigestFinal_ex(pdsactx->mdctx, digest, &dlen)) return 0; pdsactx->flag_allow_md = 1; return qat_dsa_verify(vpdsactx, sig, siglen, digest, (size_t)dlen); } static void *qat_dsa_dupctx(void *vpdsactx) { typedef void * (*fun_ptr)(void *vpdsactx); fun_ptr fun = get_default_dsa_signature().dupctx; if (!fun) return NULL; return fun(vpdsactx); } static int qat_dsa_get_ctx_params(void *vpdsactx, OSSL_PARAM *params) { typedef int (*fun_ptr)(void *vpdsactx, OSSL_PARAM *params); fun_ptr fun = get_default_dsa_signature().get_ctx_params; if (!fun) return 0; return fun(vpdsactx, params); } static const OSSL_PARAM *qat_dsa_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(ossl_unused void *ctx, ossl_unused void *provctx); fun_ptr fun = get_default_dsa_signature().gettable_ctx_params; if (!fun) return NULL; return fun(ctx, provctx); } static int qat_dsa_get_ctx_md_params(void *vpdsactx, OSSL_PARAM *params) { typedef int (*fun_ptr)(void *vpdsactx, OSSL_PARAM *params); fun_ptr fun = get_default_dsa_signature().get_ctx_md_params; if (!fun) return 0; return fun(vpdsactx, params); } static const OSSL_PARAM *qat_dsa_gettable_ctx_md_params(void *vpdsactx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vpdsactx); fun_ptr fun = get_default_dsa_signature().gettable_ctx_md_params; if (!fun) return NULL; return fun(vpdsactx); } static int qat_dsa_set_ctx_md_params(void *vpdsactx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *vpdsactx, const OSSL_PARAM params[]); fun_ptr fun = get_default_dsa_signature().set_ctx_md_params; if (!fun) return 0; return fun(vpdsactx, params); } static const OSSL_PARAM *qat_dsa_settable_ctx_md_params(void *vpdsactx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vpdsactx); fun_ptr fun = get_default_dsa_signature().settable_ctx_md_params; if (!fun) return NULL; return fun(vpdsactx); } const OSSL_DISPATCH qat_dsa_signature_functions[] = { {OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))qat_dsa_newctx}, {OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))qat_dsa_sign_init}, {OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))qat_dsa_sign}, {OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))qat_dsa_verify_init}, {OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))qat_dsa_verify}, {OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))qat_dsa_freectx}, {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))qat_dsa_set_ctx_params}, {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))qat_dsa_settable_ctx_params}, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))qat_dsa_digest_sign_init }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, (void (*)(void))qat_dsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))qat_dsa_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))qat_dsa_digest_verify_init }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, (void (*)(void))qat_dsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, (void (*)(void))qat_dsa_digest_verify_final }, { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))qat_dsa_dupctx }, { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))qat_dsa_get_ctx_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))qat_dsa_gettable_ctx_params }, { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, (void (*)(void))qat_dsa_get_ctx_md_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_dsa_gettable_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, (void (*)(void))qat_dsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_dsa_settable_ctx_md_params }, {0, NULL}}; #endif qatengine-1.9.0/qat_prov_dsa.h000066400000000000000000000151511500416242000163240ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_dsa.h * * This file provides an interface to Qat Provider DSA operations * *****************************************************************************/ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifndef __USE_GNU #define __USE_GNU #endif #ifndef QAT_PROV_DSA_H #define QAT_PROV_DSA_H #include #include #include #include #include #include #include #include #include #include "e_qat.h" #define OSSL_MAX_NAME_SIZE 50 /* Algorithm name */ #define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ #define OSSL_MAX_ALGORITHM_ID_SIZE 256 /* AlgorithmIdentifier DER */ #define FFC_UNVERIFIABLE_GINDEX -1 #define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 #define FFC_PARAM_FLAG_VALIDATE_G 0x02 #define FFC_PARAM_FLAG_VALIDATE_PQG \ (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G) struct DSA_SIG_st { BIGNUM *r; BIGNUM *s; }; typedef struct ffc_params_st { /* Primes */ BIGNUM *p; BIGNUM *q; /* Generator */ BIGNUM *g; /* DH X9.42 Optional Subgroup factor j >= 2 where p = j * q + 1 */ BIGNUM *j; /* Required for FIPS186_4 validation of p, q and optionally canonical g */ unsigned char *seed; /* If this value is zero the hash size is used as the seed length */ size_t seedlen; /* Required for FIPS186_4 validation of p and q */ int pcounter; int nid; /* The identity of a named group */ /* * Required for FIPS186_4 generation & validation of canonical g. * It uses unverifiable g if this value is -1. */ int gindex; int h; /* loop counter for unverifiable g */ unsigned int flags; /* * The digest to use for generation or validation. If this value is NULL, * then the digest is chosen using the value of N. */ const char *mdname; const char *mdprops; #if OPENSSL_VERSION_NUMBER >= 0x30000060 /* Default key length for known named groups according to RFC7919 */ int keylength; #endif } FFC_PARAMS; struct dsa_st { /* * This first variable is used to pick up errors where a DSA is passed * instead of of a EVP_PKEY */ int pad; int32_t version; FFC_PARAMS params; BIGNUM *pub_key; /* y public key */ BIGNUM *priv_key; /* x private key */ int flags; /* Normally used to cache montgomery values */ BN_MONT_CTX *method_mont_p; CRYPTO_REF_COUNT references; #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; #endif const DSA_METHOD *meth; /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_LIB_CTX *libctx; /* Provider data */ size_t dirty_cnt; /* If any key material changes, increment this */ }; typedef struct { OSSL_LIB_CTX *libctx; char *propq; DSA *dsa; /* * Flag to determine if the hash function can be changed (1) or not (0) * Because it's dangerous to change during a DigestSign or DigestVerify * operation, this flag is cleared by their Init function, and set again * by their Final function. */ unsigned int flag_allow_md : 1; char mdname[OSSL_MAX_NAME_SIZE]; /* The Algorithm Identifier of the combined signature algorithm */ unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; unsigned char *aid; size_t aid_len; /* main digest */ EVP_MD *md; EVP_MD_CTX *mdctx; int operation; } QAT_PROV_DSA_CTX; struct dsa_method { char *name; DSA_SIG *(*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa); int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont); /* Can be null */ int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); int (*init)(DSA *dsa); int (*finish)(DSA *dsa); int flags; void *app_data; /* If this is non-NULL, it is used to generate DSA parameters */ int (*dsa_paramgen)(DSA *dsa, int bits, const unsigned char *seed, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); /* If this is non-NULL, it is used to generate DSA keys */ int (*dsa_keygen)(DSA *dsa); }; void qat_DSA_free(DSA *r); #endif /* QAT_PROVIDER_DSA_H */ qatengine-1.9.0/qat_prov_ec.h000066400000000000000000000464211500416242000161500ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_ec.h * * This file provides an interface to qatprovider ECDSA & ECDH operations * *****************************************************************************/ #ifndef QAT_PROV_EC_H # define QAT_PROV_EC_H #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "e_qat.h" # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) # define OSSL_MAX_NAME_SIZE 50 /* Algorithm name */ # define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ # define OSSL_MAX_ALGORITHM_ID_SIZE 256 /* AlgorithmIdentifier DER */ typedef struct wpacket_sub WPACKET_SUB; struct wpacket_sub { /* The parent WPACKET_SUB if we have one or NULL otherwise */ WPACKET_SUB *parent; /* * Offset into the buffer where the length of this WPACKET goes. We use an * offset in case the buffer grows and gets reallocated. */ size_t packet_len; /* Number of bytes in the packet_len or 0 if we don't write the length */ size_t lenbytes; /* Number of bytes written to the buf prior to this packet starting */ size_t pwritten; /* Flags for this sub-packet */ unsigned int flags; }; typedef struct wpacket_st WPACKET; struct wpacket_st { /* The buffer where we store the output data */ BUF_MEM *buf; /* Fixed sized buffer which can be used as an alternative to buf */ unsigned char *staticbuf; /* * Offset into the buffer where we are currently writing. We use an offset * in case the buffer grows and gets reallocated. */ size_t curr; /* Number of bytes written so far */ size_t written; /* Maximum number of bytes we will allow to be written to this WPACKET */ size_t maxsize; /* Our sub-packets (always at least one if not finished) */ WPACKET_SUB *subs; /* Writing from the end first? */ unsigned int endfirst : 1; }; /* Types and functions to manipulate pre-computed values.*/ typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP; typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP; typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP; typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP; typedef struct ec_pre_comp_st EC_PRE_COMP; struct ec_key_method_st { const char *name; int32_t flags; int (*init)(EC_KEY *key); void (*finish)(EC_KEY *key); int (*copy)(EC_KEY *dest, const EC_KEY *src); int (*set_group)(EC_KEY *key, const EC_GROUP *grp); int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); int (*keygen)(EC_KEY *key); int (*compute_key)(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh); int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey); int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); int (*verify)(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); int (*verify_sig)(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); }; typedef struct ec_key_method_st EC_KEY_METHOD; struct ec_method_st { /* Various method flags */ int flags; /* used by EC_METHOD_get_field_type: */ int field_type; /* a NID */ /* * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, * EC_GROUP_copy: */ int (*group_init) (EC_GROUP *); void (*group_finish) (EC_GROUP *); void (*group_clear_finish) (EC_GROUP *); int (*group_copy) (EC_GROUP *, const EC_GROUP *); /* used by EC_GROUP_set_curve, EC_GROUP_get_curve: */ int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); /* used by EC_GROUP_get_degree: */ int (*group_get_degree) (const EC_GROUP *); int (*group_order_bits) (const EC_GROUP *); /* used by EC_GROUP_check: */ int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *); /* * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, * EC_POINT_copy: */ int (*point_init) (EC_POINT *); void (*point_finish) (EC_POINT *); void (*point_clear_finish) (EC_POINT *); int (*point_copy) (EC_POINT *, const EC_POINT *); /*- * used by EC_POINT_set_to_infinity, * EC_POINT_set_Jprojective_coordinates_GFp, * EC_POINT_get_Jprojective_coordinates_GFp, * EC_POINT_set_affine_coordinates, * EC_POINT_get_affine_coordinates, * EC_POINT_set_compressed_coordinates: */ int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *); int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *, const BIGNUM *x, const BIGNUM *y, BN_CTX *); int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *, BIGNUM *x, BIGNUM *y, BN_CTX *); int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *, const BIGNUM *x, int y_bit, BN_CTX *); /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ size_t (*point2oct) (const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX *); int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf, size_t len, BN_CTX *); /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */ int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *); /* * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */ int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *); int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *); int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */ int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *); int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); /* * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, * EC_POINT_have_precompute_mult (default implementations are used if the * 'mul' pointer is 0): */ /*- * mul() calculates the value * * r := generator * scalar * + points[0] * scalars[0] * + ... * + points[num-1] * scalars[num-1]. * * For a fixed point multiplication (scalar != NULL, num == 0) * or a variable point multiplication (scalar == NULL, num == 1), * mul() must use a constant time algorithm: in both cases callers * should provide an input scalar (either scalar or scalars[0]) * in the range [0, ec_group_order); for robustness, implementers * should handle the case when the scalar has not been reduced, but * may treat it as an unusual input, without any constant-timeness * guarantee. */ int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *); int (*precompute_mult) (EC_GROUP *group, BN_CTX *); int (*have_precompute_mult) (const EC_GROUP *group); /* internal functions */ /* * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and * 'dbl' so that the same implementations of point operations can be used * with different optimized implementations of expensive field * operations: */ int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); /*- * 'field_inv' computes the multiplicative inverse of a in the field, * storing the result in r. * * If 'a' is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error. */ int (*field_inv) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */ int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */ int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *); /* private key operations */ size_t (*priv2oct)(const EC_KEY *eckey, unsigned char *buf, size_t len); int (*oct2priv)(EC_KEY *eckey, const unsigned char *buf, size_t len); int (*set_private)(EC_KEY *eckey, const BIGNUM *priv_key); int (*keygen)(EC_KEY *eckey); int (*keycheck)(const EC_KEY *eckey); int (*keygenpub)(EC_KEY *eckey); int (*keycopy)(EC_KEY *dst, const EC_KEY *src); void (*keyfinish)(EC_KEY *eckey); /* custom ECDH operation */ int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen, const EC_POINT *pub_key, const EC_KEY *ecdh); /* custom ECDSA */ int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinvp, BIGNUM **rp); ECDSA_SIG *(*ecdsa_sign_sig)(const unsigned char *dgst, int dgstlen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey); int (*ecdsa_verify_sig)(const unsigned char *dgst, int dgstlen, const ECDSA_SIG *sig, EC_KEY *eckey); /* Inverse modulo order */ int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r, const BIGNUM *x, BN_CTX *); int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx); int (*ladder_pre)(const EC_GROUP *group, EC_POINT *r, EC_POINT *s, EC_POINT *p, BN_CTX *ctx); int (*ladder_step)(const EC_GROUP *group, EC_POINT *r, EC_POINT *s, EC_POINT *p, BN_CTX *ctx); int (*ladder_post)(const EC_GROUP *group, EC_POINT *r, EC_POINT *s, EC_POINT *p, BN_CTX *ctx); }; typedef struct ec_method_st EC_METHOD; struct ec_group_st { const EC_METHOD *meth; EC_POINT *generator; /* optional */ BIGNUM *order, *cofactor; int curve_name; /* optional NID for named curve */ int asn1_flag; /* flag to control the asn1 encoding */ int decoded_from_explicit_params; /* set if decoded from explicit * curve parameters encoding */ point_conversion_form_t asn1_form; unsigned char *seed; /* optional seed for parameters (appears in * ASN1) */ size_t seed_len; /* * The following members are handled by the method functions, even if * they appear generic */ /* * Field specification. For curves over GF(p), this is the modulus; for * curves over GF(2^m), this is the irreducible polynomial defining the * field. */ BIGNUM *field; /* * Field specification for curves over GF(2^m). The irreducible f(t) is * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m = * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero * terms. */ int poly[6]; /* * Curve coefficients. (Here the assumption is that BIGNUMs can be used * or abused for all kinds of fields, not just GF(p).) For characteristic * > 3, the curve is defined by a Weierstrass equation of the form y^2 = * x^3 + a*x + b. For characteristic 2, the curve is defined by an * equation of the form y^2 + x*y = x^3 + a*x^2 + b. */ BIGNUM *a, *b; /* enable optimized point arithmetic for special case */ int a_is_minus3; /* method-specific (e.g., Montgomery structure) */ void *field_data1; /* method-specific */ void *field_data2; /* method-specific */ int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* data for ECDSA inverse */ BN_MONT_CTX *mont_data; /* * Precomputed values for speed. The PCT_xxx names match the * pre_comp.xxx union names; see the SETPRECOMP and HAVEPRECOMP * macros, below. */ enum { PCT_none, PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256, PCT_ec } pre_comp_type; union { NISTP224_PRE_COMP *nistp224; NISTP256_PRE_COMP *nistp256; NISTP521_PRE_COMP *nistp521; NISTZ256_PRE_COMP *nistz256; EC_PRE_COMP *ec; } pre_comp; OSSL_LIB_CTX *libctx; char *propq; }; typedef struct ec_group_st EC_GROUP; struct ec_key_st { const EC_KEY_METHOD *meth; ENGINE *engine; int version; EC_GROUP *group; EC_POINT *pub_key; BIGNUM *priv_key; unsigned int enc_flag; point_conversion_form_t conv_form; CRYPTO_REF_COUNT references; /*CRYPTO_REF_COUNT references;*/ int flags; # ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; # endif # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; # endif OSSL_LIB_CTX *libctx; char *propq; /* Provider data */ size_t dirty_cnt; /* If any key material changes, increment this */ }; typedef struct ec_key_st EC_KEY; typedef struct { OSSL_LIB_CTX *libctx; char *propq; EC_KEY *ec; char mdname[OSSL_MAX_NAME_SIZE]; /* * Flag to determine if the hash function can be changed (1) or not (0) * Because it's dangerous to change during a DigestSign or DigestVerify * operation, this flag is cleared by their Init function, and set again * by their Final function. */ unsigned int flag_allow_md : 1; /* The Algorithm Identifier of the combined signature algorithm */ unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; unsigned char *aid; size_t aid_len; size_t mdsize; int operation; EVP_MD *md; EVP_MD_CTX *mdctx; /* * Internally used to cache the results of calling the EC group * sign_setup() methods which are then passed to the sign operation. * This is used by CAVS failure tests to terminate a loop if the signature * is not valid. * This could of also been done with a simple flag. */ BIGNUM *kinv; BIGNUM *r; # if !defined(OPENSSL_NO_ACVP_TESTS) /* * This indicates that KAT (CAVS) test is running. Externally an app will * override the random callback such that the generated private key and k * are known. * Normal operation will loop to choose a new k if the signature is not * valid - but for this mode of operation it forces a failure instead. */ unsigned int kattest; # endif /* If this is set then the generated k is not random */ unsigned int nonce_type; } QAT_PROV_ECDSA_CTX; typedef struct qat_evp_keyexch_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_keyexch_newctx_fn *newctx; OSSL_FUNC_keyexch_init_fn *init; OSSL_FUNC_keyexch_set_peer_fn *set_peer; OSSL_FUNC_keyexch_derive_fn *derive; OSSL_FUNC_keyexch_freectx_fn *freectx; OSSL_FUNC_keyexch_dupctx_fn *dupctx; OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; } QAT_EVP_ECDH_KEYEXCH; int QAT_EC_KEY_up_ref(EC_KEY *r); void QAT_EC_KEY_free(EC_KEY *r); /* With security check enabled it can return -1 to indicate disallowed md */ int qat_digest_ecdsa_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md, int sha1_allowed); int qat_digest_ecdsa_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len); int qat_digest_ecdsa_get_approved_nid(const EVP_MD *md); int qat_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect); OSSL_LIB_CTX *qat_ec_key_get_libctx(const EC_KEY *key); #endif /* QAT_PROV_EC_H */ qatengine-1.9.0/qat_prov_ecdh.c000066400000000000000000000610651500416242000164600ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_ecdh.c * * This file contains the qatprovider implementation for QAT_HW & QAT_SW * ECDH operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include "qat_provider.h" #include "qat_prov_ec.h" #include "qat_utils.h" #include "qat_evp.h" #include "e_qat.h" #ifdef ENABLE_QAT_HW_ECDH # include "qat_hw_ec.h" #endif #ifdef ENABLE_QAT_SW_ECDH # include "qat_sw_ec.h" #endif #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #if defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) enum kdf_type { PROV_ECDH_KDF_NONE = 0, PROV_ECDH_KDF_X9_63 }; /* * What's passed as an actual key is defined by the KEYMGMT interface. * We happen to know that our KEYMGMT simply passes EC_KEY structures, so * we use that here too. */ typedef struct { OSSL_LIB_CTX *libctx; EC_KEY *k; EC_KEY *peerk; /* * ECDH cofactor mode: * * . 0 disabled * . 1 enabled * . -1 use cofactor mode set for k */ int cofactor_mode; /************ * ECDH KDF * ************/ /* KDF (if any) to use for ECDH */ enum kdf_type kdf_type; /* Message digest to use for key derivation */ EVP_MD *kdf_md; /* User key material */ unsigned char *kdf_ukm; size_t kdf_ukmlen; /* KDF output length */ size_t kdf_outlen; } QAT_PROV_ECDH_CTX; static OSSL_FUNC_keyexch_newctx_fn qat_keyexch_ecdh_newctx; static OSSL_FUNC_keyexch_init_fn qat_keyexch_ecdh_init; static OSSL_FUNC_keyexch_set_peer_fn qat_keyexch_ecdh_set_peer; static OSSL_FUNC_keyexch_derive_fn qat_keyexch_ecdh_derive; static OSSL_FUNC_keyexch_freectx_fn qat_keyexch_ecdh_freectx; static OSSL_FUNC_keyexch_set_ctx_params_fn qat_keyexch_ecdh_set_ctx_params; static OSSL_FUNC_keyexch_settable_ctx_params_fn qat_keyexch_ecdh_settable_ctx_params; static OSSL_FUNC_keyexch_get_ctx_params_fn qat_keyexch_ecdh_get_ctx_params; static OSSL_FUNC_keyexch_gettable_ctx_params_fn qat_keyexch_ecdh_gettable_ctx_params; QAT_EVP_ECDH_KEYEXCH get_default_ecdh_keyexch() { static QAT_EVP_ECDH_KEYEXCH s_keyexch; static int initialized = 0; if (!initialized) { QAT_EVP_ECDH_KEYEXCH *keyexch = (QAT_EVP_ECDH_KEYEXCH *)EVP_KEYEXCH_fetch(NULL,"ECDH","provider=default"); if (keyexch) { s_keyexch = *keyexch; EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); initialized = 1; } else { WARN("EVP_KEYEXCH_fetch from default provider failed"); } } return s_keyexch; } static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, NULL), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), OSSL_PARAM_END }; static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, NULL), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL, 0), OSSL_PARAM_END }; static int QAT_ECDH_KEY_up_ref(EC_KEY *r) { int i; # if OPENSSL_VERSION_NUMBER < 0x30200000 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) return 0; # else if (QAT_CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; # endif if(i < 2){ WARN("refcount error"); return 0; } return i > 1 ? 1 : 0; } static void QAT_ECDH_KEY_free(EC_KEY *r) { int i; if (r == NULL) return; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_DOWN_REF(&r->references, &i, r->lock); # else QAT_CRYPTO_DOWN_REF(&r->references, &i); # endif if (i > 0) return; if(i < 0){ WARN("refcount error"); return; } if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); if (r->group && r->group->meth->keyfinish) r->group->meth->keyfinish(r); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(r->lock); # endif EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r->propq); OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); } static int qat_ecdh_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) { # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) if (qat_securitycheck_enabled(ctx)) { int nid, strength; const char *curve_name; const EC_GROUP *group = EC_KEY_get0_group(ec); if (group == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group"); return 0; } nid = EC_GROUP_get_curve_name(group); if (nid == NID_undef) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "Explicit curves are not allowed in fips mode"); return 0; } curve_name = EC_curve_nid2nist(nid); if (curve_name == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "Curve %s is not approved in FIPS mode", curve_name); return 0; } /* * For EC the security strength is the (order_bits / 2) * e.g. P-224 is 112 bits. */ strength = EC_GROUP_order_bits(group) / 2; /* The min security strength allowed for legacy verification is 80 bits */ if (strength < 80) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); return 0; } /* * For signing or key agreement only allow curves with at least 112 bits of * security strength */ if (protect && strength < 112) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "Curve %s cannot be used for signing", curve_name); return 0; } } # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ return 1; } static void *qat_keyexch_ecdh_newctx(void *provctx) { QAT_PROV_ECDH_CTX *pectx; if (!qat_prov_is_running()) return NULL; pectx = OPENSSL_zalloc(sizeof(*pectx)); if (pectx == NULL) return NULL; pectx->libctx = prov_libctx_of(provctx); pectx->cofactor_mode = -1; pectx->kdf_type = PROV_ECDH_KDF_NONE; return (void *)pectx; } static int qat_keyexch_ecdh_init(void *vpecdhctx, void *vecdh, const OSSL_PARAM params[]) { QAT_PROV_ECDH_CTX *pecdhctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; if (!qat_prov_is_running() || pecdhctx == NULL || vecdh == NULL || !QAT_ECDH_KEY_up_ref(vecdh)) return 0; QAT_ECDH_KEY_free(pecdhctx->k); pecdhctx->k = vecdh; pecdhctx->cofactor_mode = -1; pecdhctx->kdf_type = PROV_ECDH_KDF_NONE; return qat_keyexch_ecdh_set_ctx_params(pecdhctx, params) && qat_ecdh_check_key(pecdhctx->libctx, vecdh, 1); } OSSL_LIB_CTX *qat_ec_key_get_libctx(const EC_KEY *key) { return key->libctx; } static int qat_keyexch_ecdh_match_params(const EC_KEY *priv, const EC_KEY *peer) { int ret; BN_CTX *ctx = NULL; const EC_GROUP *group_priv = EC_KEY_get0_group(priv); const EC_GROUP *group_peer = EC_KEY_get0_group(peer); ctx = BN_CTX_new_ex(qat_ec_key_get_libctx(priv)); if (ctx == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return 0; } ret = group_priv != NULL && group_peer != NULL && EC_GROUP_cmp(group_priv, group_peer, ctx) == 0; if (!ret) QATerr(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS); BN_CTX_free(ctx); return ret; } static int qat_keyexch_ecdh_set_peer(void *vpecdhctx, void *vecdh) { QAT_PROV_ECDH_CTX *pecdhctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; if (!qat_prov_is_running() || pecdhctx == NULL || vecdh == NULL || !qat_keyexch_ecdh_match_params(pecdhctx->k, vecdh) || !qat_ecdh_check_key(pecdhctx->libctx, vecdh, 1) || !QAT_ECDH_KEY_up_ref(vecdh)) return 0; QAT_ECDH_KEY_free(pecdhctx->peerk); pecdhctx->peerk = vecdh; return 1; } static void qat_keyexch_ecdh_freectx(void *vpecdhctx) { QAT_PROV_ECDH_CTX *pecdhctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; QAT_ECDH_KEY_free(pecdhctx->k); QAT_ECDH_KEY_free(pecdhctx->peerk); EVP_MD_free(pecdhctx->kdf_md); OPENSSL_clear_free(pecdhctx->kdf_ukm, pecdhctx->kdf_ukmlen); OPENSSL_free(pecdhctx); } static void *qat_keyexch_ecdh_dupctx(void *vpecdhctx) { QAT_PROV_ECDH_CTX *srcctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; QAT_PROV_ECDH_CTX *dstctx; if (!qat_prov_is_running()) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; *dstctx = *srcctx; /* clear all pointers */ dstctx->k = NULL; dstctx->peerk = NULL; dstctx->kdf_md = NULL; dstctx->kdf_ukm = NULL; /* up-ref all ref-counted objects referenced in dstctx */ if (srcctx->k != NULL && !QAT_ECDH_KEY_up_ref(srcctx->k)) goto err; else dstctx->k = srcctx->k; if (srcctx->peerk != NULL && !QAT_ECDH_KEY_up_ref(srcctx->peerk)) goto err; else dstctx->peerk = srcctx->peerk; if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md)) goto err; else dstctx->kdf_md = srcctx->kdf_md; /* Duplicate UKM data if present */ if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) { dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, srcctx->kdf_ukmlen); if (dstctx->kdf_ukm == NULL) goto err; } return dstctx; err: qat_keyexch_ecdh_freectx(dstctx); return NULL; } static int qat_keyexch_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md) { return 1; } static int qat_keyexch_ecdh_set_ctx_params(void *vpecdhctx, const OSSL_PARAM params[]) { char name[80] = { '\0' }; /* should be big enough */ char *str = NULL; QAT_PROV_ECDH_CTX *pectx = (QAT_PROV_ECDH_CTX *)vpecdhctx; const OSSL_PARAM *p; if (pectx == NULL) return 0; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE); if (p != NULL) { int mode; if (!OSSL_PARAM_get_int(p, &mode)) return 0; if (mode < -1 || mode > 1) return 0; pectx->cofactor_mode = mode; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); if (p != NULL) { str = name; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) return 0; if (name[0] == '\0') pectx->kdf_type = PROV_ECDH_KDF_NONE; else if (strcmp(name, OSSL_KDF_NAME_X963KDF) == 0) pectx->kdf_type = PROV_ECDH_KDF_X9_63; else return 0; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); if (p != NULL) { char mdprops[80] = { '\0' }; /* should be big enough */ str = name; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) return 0; str = mdprops; p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); if (p != NULL) { if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) return 0; } EVP_MD_free(pectx->kdf_md); pectx->kdf_md = EVP_MD_fetch(pectx->libctx, name, mdprops); if (!qat_keyexch_digest_is_allowed(pectx->libctx, pectx->kdf_md)) { EVP_MD_free(pectx->kdf_md); pectx->kdf_md = NULL; } if (pectx->kdf_md == NULL) return 0; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); if (p != NULL) { size_t outlen; if (!OSSL_PARAM_get_size_t(p, &outlen)) return 0; pectx->kdf_outlen = outlen; } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); if (p != NULL) { void *tmp_ukm = NULL; size_t tmp_ukmlen; if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) return 0; OPENSSL_free(pectx->kdf_ukm); pectx->kdf_ukm = tmp_ukm; pectx->kdf_ukmlen = tmp_ukmlen; } return 1; } static const OSSL_PARAM *qat_keyexch_ecdh_settable_ctx_params( ossl_unused void *vpecdhctx, ossl_unused void *provctx) { return known_settable_ctx_params; } static int qat_keyexch_ecdh_get_ctx_params(void *vpecdhctx, OSSL_PARAM params[]) { QAT_PROV_ECDH_CTX *pectx = (QAT_PROV_ECDH_CTX *)vpecdhctx; OSSL_PARAM *p; if (pectx == NULL) return 0; p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE); if (p != NULL) { int mode = pectx->cofactor_mode; if (mode == -1) { /* check what is the default for pecdhctx->k */ mode = EC_KEY_get_flags(pectx->k) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; } if (!OSSL_PARAM_set_int(p, mode)) return 0; } p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); if (p != NULL) { const char *kdf_type = NULL; switch (pectx->kdf_type) { case PROV_ECDH_KDF_NONE: kdf_type = ""; break; case PROV_ECDH_KDF_X9_63: kdf_type = OSSL_KDF_NAME_X963KDF; break; default: return 0; } if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) return 0; } p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pectx->kdf_md == NULL ? "" : EVP_MD_get0_name(pectx->kdf_md))){ return 0; } p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, pectx->kdf_outlen)) return 0; p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pectx->kdf_ukm, pectx->kdf_ukmlen)) return 0; return 1; } static const OSSL_PARAM *qat_keyexch_ecdh_gettable_ctx_params( ossl_unused void *vpecdhctx, ossl_unused void *provctx) { return known_gettable_ctx_params; } size_t qat_keyexch_ecdh_size(const EC_KEY *k) { size_t degree = 0; const EC_GROUP *group; if (k == NULL || (group = EC_KEY_get0_group(k)) == NULL) return 0; degree = EC_GROUP_get_degree(group); return (degree + 7) / 8; } int QAT_ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen)) { unsigned char *sec = NULL; size_t seclen; if (eckey->meth->compute_key == NULL) { QATerr(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED); return 0; } if (outlen > INT_MAX) { QATerr(ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH); return 0; } #ifdef ENABLE_QAT_HW_ECDH if (qat_hw_ecdh_offload) { if(!qat_engine_ecdh_compute_key(&sec, &seclen, pub_key, eckey)) return 0; } #endif #ifdef ENABLE_QAT_SW_ECDH if (qat_sw_ecdh_offload) { if(!mb_ecdh_compute_key(&sec, &seclen, pub_key, eckey)) return 0; } #endif if (KDF != NULL) { KDF(sec, seclen, out, &outlen); } else { if (outlen > seclen) outlen = seclen; memcpy(out, sec, outlen); } OPENSSL_clear_free(sec, seclen); return outlen; } static ossl_inline int qat_keyexch_ecdh_plain_derive(void *vpecdhctx, unsigned char *secret, size_t *psecretlen, size_t outlen) { QAT_PROV_ECDH_CTX *pecdhctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; int retlen, ret = 0; size_t ecdhsize, size; const EC_POINT *ppubkey = NULL; EC_KEY *privk = NULL; const EC_GROUP *group; const BIGNUM *cofactor; int key_cofactor_mode; if (pecdhctx->k == NULL || pecdhctx->peerk == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_KEY); return 0; } ecdhsize = qat_keyexch_ecdh_size(pecdhctx->k); if (secret == NULL) { *psecretlen = ecdhsize; return 1; } if ((group = EC_KEY_get0_group(pecdhctx->k)) == NULL || (cofactor = EC_GROUP_get0_cofactor(group)) == NULL ) return 0; /* * NB: unlike PKCS#3 DH, if outlen is less than maximum size this is not * an error, the result is truncated. */ size = outlen < ecdhsize ? outlen : ecdhsize; /* * The ctx->cofactor_mode flag has precedence over the * cofactor_mode flag set on ctx->k. * * - if ctx->cofactor_mode == -1, use ctx->k directly * - if ctx->cofactor_mode == key_cofactor_mode, use ctx->k directly * - if ctx->cofactor_mode != key_cofactor_mode: * - if ctx->k->cofactor == 1, the cofactor_mode flag is irrelevant, use * ctx->k directly * - if ctx->k->cofactor != 1, use a duplicate of ctx->k with the flag * set to ctx->cofactor_mode */ key_cofactor_mode = (EC_KEY_get_flags(pecdhctx->k) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; if (pecdhctx->cofactor_mode != -1 && pecdhctx->cofactor_mode != key_cofactor_mode && !BN_is_one(cofactor)) { if ((privk = EC_KEY_dup(pecdhctx->k)) == NULL) return 0; if (pecdhctx->cofactor_mode == 1) EC_KEY_set_flags(privk, EC_FLAG_COFACTOR_ECDH); else EC_KEY_clear_flags(privk, EC_FLAG_COFACTOR_ECDH); } else { privk = pecdhctx->k; } ppubkey = EC_KEY_get0_public_key(pecdhctx->peerk); retlen = QAT_ECDH_compute_key(secret, size, ppubkey, privk, NULL); if (retlen <= 0) goto end; *psecretlen = retlen; ret = 1; end: if (privk != pecdhctx->k) EC_KEY_free(privk); return ret; } /* Key derivation function from X9.63/SECG */ static int qat_keyexch_ecdh_kdf_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md, OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; EVP_KDF_CTX *kctx = NULL; OSSL_PARAM params[4], *p = params; const char *mdname = EVP_MD_get0_name(md); EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X963KDF, propq); if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) { *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (void *)Z, Zlen); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, (void *)sinfo, sinfolen); *p = OSSL_PARAM_construct_end(); ret = EVP_KDF_derive(kctx, out, outlen, params) > 0; EVP_KDF_CTX_free(kctx); } EVP_KDF_free(kdf); return ret; } static ossl_inline int qat_keyexch_ecdh_X9_63_kdf_derive(void *vpecdhctx, unsigned char *secret, size_t *psecretlen, size_t outlen) { QAT_PROV_ECDH_CTX *pecdhctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; unsigned char *stmp = NULL; size_t stmplen; int ret = 0; if (secret == NULL) { *psecretlen = pecdhctx->kdf_outlen; return 1; } if (pecdhctx->kdf_outlen > outlen) { QATerr(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } if (!qat_keyexch_ecdh_plain_derive(vpecdhctx, NULL, &stmplen, 0)) return 0; if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return 0; } if (!qat_keyexch_ecdh_plain_derive(vpecdhctx, stmp, &stmplen, stmplen)) goto err; /* Do KDF stuff */ if (!qat_keyexch_ecdh_kdf_X9_63(secret, pecdhctx->kdf_outlen, stmp, stmplen, pecdhctx->kdf_ukm, pecdhctx->kdf_ukmlen, pecdhctx->kdf_md, pecdhctx->libctx, NULL)) goto err; *psecretlen = pecdhctx->kdf_outlen; ret = 1; err: OPENSSL_secure_clear_free(stmp, stmplen); return ret; } static int qat_keyexch_ecdh_derive(void *vpecdhctx, unsigned char *secret, size_t *psecretlen, size_t outlen) { int ret = 0; QAT_PROV_ECDH_CTX *pecdhctx = (QAT_PROV_ECDH_CTX *)vpecdhctx; #ifdef ENABLE_QAT_FIPS if (!qat_fips_ec_check_approved_curve(pecdhctx->k)) goto end; qat_fips_service_indicator = 1; #endif if (qat_sw_ecdh_offload != 1 && qat_hw_ecdh_offload != 1) { typedef int (*fun_ptr)(void *, unsigned char *, size_t *, size_t); fun_ptr fun = get_default_ecdh_keyexch().derive; if (!fun) return 0; return fun(vpecdhctx, secret, psecretlen, outlen); } switch (pecdhctx->kdf_type) { case PROV_ECDH_KDF_NONE: ret = qat_keyexch_ecdh_plain_derive(vpecdhctx, secret, psecretlen, outlen); goto end; case PROV_ECDH_KDF_X9_63: ret = qat_keyexch_ecdh_X9_63_kdf_derive(vpecdhctx, secret, psecretlen, outlen); goto end; default: break; } end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } const OSSL_DISPATCH qat_ecdh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))qat_keyexch_ecdh_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))qat_keyexch_ecdh_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))qat_keyexch_ecdh_derive }, { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))qat_keyexch_ecdh_set_peer }, { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))qat_keyexch_ecdh_freectx }, { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))qat_keyexch_ecdh_dupctx }, { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))qat_keyexch_ecdh_set_ctx_params }, { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, (void (*)(void))qat_keyexch_ecdh_settable_ctx_params }, { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))qat_keyexch_ecdh_get_ctx_params }, { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, (void (*)(void))qat_keyexch_ecdh_gettable_ctx_params }, { 0, NULL } }; #endif qatengine-1.9.0/qat_prov_ecdsa.c000066400000000000000000000664711500416242000166420ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_provider_ecdsa.c * * This file contains the qatprovider implementation for QAT_HW and QAT_SW * ECDSA operations. * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include "qat_provider.h" #include "qat_prov_hkdf_packet.h" #include "qat_prov_ec.h" #include "qat_utils.h" #include "qat_evp.h" #include "e_qat.h" #ifdef ENABLE_QAT_FIPS #include "qat_prov_cmvp.h" #endif #ifdef ENABLE_QAT_HW_ECDSA # include "qat_hw_ec.h" #endif #ifdef ENABLE_QAT_SW_ECDSA # include "qat_sw_ec.h" #endif #if defined(ENABLE_QAT_HW_ECDSA) || defined(ENABLE_QAT_SW_ECDSA) #ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; #endif typedef struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; OSSL_FUNC_signature_sign_fn *sign; OSSL_FUNC_signature_verify_init_fn *verify_init; OSSL_FUNC_signature_verify_fn *verify; OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; OSSL_FUNC_signature_verify_recover_fn *verify_recover; OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; OSSL_FUNC_signature_digest_sign_fn *digest_sign; OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; OSSL_FUNC_signature_digest_verify_fn *digest_verify; OSSL_FUNC_signature_freectx_fn *freectx; OSSL_FUNC_signature_dupctx_fn *dupctx; OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } QAT_EVP_SIGNATURE /* EVP_SIGNATURE for QAT Provider ECDSA */; static QAT_EVP_SIGNATURE get_default_ECDSA_signature() { static QAT_EVP_SIGNATURE s_signature; static int initilazed = 0; if (!initilazed) { QAT_EVP_SIGNATURE *signature = (QAT_EVP_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "ECDSA", "provider=default"); if (signature) { s_signature = *signature; EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); initilazed = 1; } else { WARN("EVP_SIGNATURE_fetch from default provider failed"); } } return s_signature; } static const OSSL_PARAM settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), OSSL_PARAM_END }; static const OSSL_PARAM settable_ctx_params_no_digest[] = { OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_KAT, NULL), OSSL_PARAM_END }; int QAT_EC_KEY_up_ref(EC_KEY *r) { int i; # if OPENSSL_VERSION_NUMBER < 0x30200000 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) return 0; # else if (QAT_CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; # endif if(i < 2){ WARN("refcount error"); return 0; } return i > 1 ? 1 : 0; } void QAT_EC_KEY_free(EC_KEY *r) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif int i; if (r == NULL) return; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_DOWN_REF(&r->references, &i, r->lock); # else QAT_CRYPTO_DOWN_REF(&r->references, &i); # endif if (i > 0) return; if(i < 0){ WARN("refcount error"); return; } if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); if (r->group && r->group->meth->keyfinish) r->group->meth->keyfinish(r); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(r->lock); # endif EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r->propq); OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } /* Disable the security checks in the default provider and qat provider */ int qat_securitycheck_enabled(OSSL_LIB_CTX *libctx) { return 0; } #ifndef OPENSSL_NO_EC /* * In FIPS mode: * protect should be 1 for any operations that need 112 bits of security * strength (such as signing, and key exchange), or 0 for operations that allow * a lower security strength (such as verify). * * For ECDH key agreement refer to SP800-56A * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf * "Appendix D" * * For ECDSA signatures refer to * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf * "Table 2" */ int qat_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) { #ifdef ENABLE_QAT_FIPS if (!qat_fips_ec_check_approved_curve(ec)) { return 0; } if (!qat_fips_ec_key_simple_check_key(ec)) { INFO("Invalid pub_key\n"); return 0; } #endif # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) if (qat_securitycheck_enabled(ctx)) { int nid, strength; const char *curve_name; const EC_GROUP *group = EC_KEY_get0_group(ec); if (group == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group"); return 0; } nid = EC_GROUP_get_curve_name(group); if (nid == NID_undef) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "Explicit curves are not allowed in fips mode"); return 0; } curve_name = EC_curve_nid2nist(nid); if (curve_name == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "Curve %s is not approved in FIPS mode", curve_name); return 0; } /* * For EC the security strength is the (order_bits / 2) * e.g. P-224 is 112 bits. */ strength = EC_GROUP_order_bits(group) / 2; /* The min security strength allowed for legacy verification is 80 bits */ if (strength < 80) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_CURVE); return 0; } /* * For signing or key agreement only allow curves with at least 112 bits of * security strength */ if (protect && strength < 112) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "Curve %s cannot be used for signing", curve_name); return 0; } } # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ return 1; } #endif /* OPENSSL_NO_EC */ /* * Internal library code deals with NIDs, so we need to translate from a name. * We do so using EVP_MD_is_a(), and therefore need a name to NID map. */ int qat_digest_ecdsa_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len) { size_t i; if (md == NULL) return NID_undef; for (i = 0; i < it_len; i++) if (EVP_MD_is_a(md, it[i].ptr)) return (int)it[i].id; return NID_undef; } int qat_digest_ecdsa_get_approved_nid(const EVP_MD *md) { static const OSSL_ITEM name_to_nid[] = { { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 }, { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 }, { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, }; return qat_digest_ecdsa_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid)); } int qat_digest_ecdsa_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md, int sha1_allowed) { int mdnid = qat_digest_ecdsa_get_approved_nid(md); return mdnid; } static int qat_ecdsa_setup_md(QAT_PROV_ECDSA_CTX *ctx, const char *mdname, const char *mdprops) { EVP_MD *md = NULL; size_t mdname_len; int md_nid, sha1_allowed; qat_WPACKET pkt; if (mdname == NULL) return 1; mdname_len = strlen(mdname); if (mdname_len >= sizeof(ctx->mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s exceeds name buffer length", mdname); return 0; } if (mdprops == NULL) mdprops = ctx->propq; md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); if (md == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s could not be fetched", mdname); return 0; } sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); md_nid = qat_digest_ecdsa_get_approved_nid_with_sha1(ctx->libctx, md, sha1_allowed); if (md_nid < 0) { ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest=%s", mdname); EVP_MD_free(md); return 0; } EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); ctx->aid_len = 0; if (QAT_WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) && qat_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec, md_nid) && QAT_WPACKET_finish(&pkt)) { QAT_WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = QAT_WPACKET_get_curr(&pkt); } QAT_WPACKET_cleanup(&pkt); ctx->mdctx = NULL; ctx->md = md; ctx->mdsize = EVP_MD_get_size(ctx->md); OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); return 1; } static void *qat_signature_ecdsa_newctx(void *provctx, const char *propq) { QAT_PROV_ECDSA_CTX *ctx; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(QAT_PROV_ECDSA_CTX)); if (ctx == NULL) return NULL; ctx->flag_allow_md = 1; ctx->libctx = prov_libctx_of(provctx); if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(ctx); ctx = NULL; QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); } return ctx; } static int qat_signature_ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; const OSSL_PARAM *p; if (ctx == NULL) return 0; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); /* Not allowed during certain operations */ if (p != NULL && !ctx->flag_allow_md) return 0; if (p != NULL) { char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; const OSSL_PARAM *propsp = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PROPERTIES); if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) return 0; if (propsp != NULL && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) return 0; if (!qat_ecdsa_setup_md(ctx, mdname, mdprops)) return 0; } p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); if (p != NULL && (!ctx->flag_allow_md || !OSSL_PARAM_get_size_t(p, &ctx->mdsize))) return 0; return 1; } static int qat_signature_ecdsa_signverify_init(void *vctx, void *ec, const OSSL_PARAM params[], int operation) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; if (!qat_prov_is_running() || ctx == NULL || ec == NULL || !QAT_EC_KEY_up_ref(ec)) return 0; QAT_EC_KEY_free(ctx->ec); ctx->ec = ec; ctx->operation = operation; if (!qat_signature_ecdsa_set_ctx_params(ctx, params)) return 0; return qat_ec_check_key(ctx->libctx, ec, operation == EVP_PKEY_OP_SIGN); } static int qat_signature_ecdsa_sign_init(void *vctx, void *ec, const OSSL_PARAM params[]) { DEBUG("qat_signature_ecdsa_sign_init\n"); return qat_signature_ecdsa_signverify_init(vctx, ec, params, EVP_PKEY_OP_SIGN); } static int qat_signature_ecdsa_verify_init(void *vctx, void *ec, const OSSL_PARAM params[]) { DEBUG("qat_signature_ecdsa_verify_init\n"); return qat_signature_ecdsa_signverify_init(vctx, ec, params, EVP_PKEY_OP_VERIFY); } static int qat_signature_ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; int ret = 0; unsigned int sltmp; size_t ecsize = ECDSA_size(ctx->ec); #ifdef ENABLE_QAT_FIPS if (!qat_fips_ec_check_approved_curve(ctx->ec)) goto end; qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running()) goto end; if (sig == NULL) { *siglen = ecsize; ret = 1; goto end; } if (sigsize < (size_t)ecsize) goto end; if (ctx->mdsize != 0 && tbslen != ctx->mdsize) goto end; #ifdef ENABLE_QAT_HW_ECDSA if (qat_hw_ecdsa_offload) { ret = qat_ecdsa_sign(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r, ctx->ec); if (ret <= 0) goto end; } #endif #ifdef ENABLE_QAT_SW_ECDSA if (qat_sw_ecdsa_offload) { ret = mb_ecdsa_sign(0, tbs, tbslen, sig, &sltmp, ctx->kinv, ctx->r, ctx->ec); if (ret <= 0) goto end; } else { typedef int (*fun_ptr)(void *, unsigned char *, size_t *, size_t , const unsigned char *, size_t); fun_ptr fun = get_default_ECDSA_signature().sign; if (!fun) return 0; return fun(vctx, sig, siglen, sigsize, tbs, tbslen); } #endif *siglen = sltmp; ret = 1; end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static int qat_signature_ecdsa_verify(void *vctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { int ret = 0; QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; #ifdef ENABLE_QAT_FIPS if (!qat_fips_ec_check_approved_curve(ctx->ec)) goto end; qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running() || (ctx->mdsize != 0 && tbslen != ctx->mdsize)) goto end; #ifdef ENABLE_QAT_HW_ECDSA if (qat_hw_ecdsa_offload) ret = qat_ecdsa_verify(0, tbs, tbslen, sig, siglen, ctx->ec); #endif #ifdef ENABLE_QAT_SW_ECDSA if (qat_sw_ecdsa_offload) { ret = mb_ecdsa_verify(0, tbs, tbslen, sig, siglen, ctx->ec); } else { typedef int (*fun_ptr)(void *, const unsigned char *, size_t, const unsigned char *, size_t); fun_ptr fun = get_default_ECDSA_signature().verify; if (!fun) return 0; return fun(vctx, sig, siglen, tbs, tbslen); } #endif end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static void qat_signature_ecdsa_freectx(void *vctx) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; OPENSSL_free(ctx->propq); EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); ctx->propq = NULL; ctx->mdctx = NULL; ctx->md = NULL; ctx->mdsize = 0; QAT_EC_KEY_free(ctx->ec); BN_clear_free(ctx->kinv); BN_clear_free(ctx->r); OPENSSL_free(ctx); } static const OSSL_PARAM *qat_signature_ecdsa_settable_ctx_params(void *vctx, ossl_unused void *provctx) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; if (ctx != NULL && !ctx->flag_allow_md) return settable_ctx_params_no_digest; return settable_ctx_params; } static int qat_ecdsa_signverify_init(void *vctx, void *ec, const OSSL_PARAM params[], int operation) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; if (!qat_prov_is_running() || ctx == NULL) return 0; if (ec == NULL && ctx->ec == NULL) { QATerr(ERR_LIB_PROV, PROV_R_NO_KEY_SET); return 0; } if (ec != NULL) { if (!qat_ec_check_key(ctx->libctx, ec, operation == EVP_PKEY_OP_SIGN)) return 0; if (!EC_KEY_up_ref(ec)) return 0; EC_KEY_free(ctx->ec); ctx->ec = ec; } ctx->operation = operation; if (!qat_signature_ecdsa_set_ctx_params(ctx, params)) return 0; return 1; } static int qat_ecdsa_digest_signverify_init(void *vctx, const char *mdname, void *ec, const OSSL_PARAM params[], int operation) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; if (!qat_prov_is_running()) return 0; if (!qat_ecdsa_signverify_init(vctx, ec, params, operation) || !qat_ecdsa_setup_md(ctx, mdname, NULL)) return 0; ctx->flag_allow_md = 0; if (ctx->mdctx == NULL) { ctx->mdctx = EVP_MD_CTX_new(); if (ctx->mdctx == NULL) goto error; } if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) goto error; return 1; error: EVP_MD_CTX_free(ctx->mdctx); ctx->mdctx = NULL; return 0; } static int qat_ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec, const OSSL_PARAM params[]) { return qat_ecdsa_digest_signverify_init(vctx, mdname, ec, params, EVP_PKEY_OP_SIGN); } int qat_ecdsa_digest_signverify_update(void *vctx, const unsigned char *data, size_t datalen) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; if (ctx == NULL || ctx->mdctx == NULL) return 0; return EVP_DigestUpdate(ctx->mdctx, data, datalen); } int qat_ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen, size_t sigsize) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (!qat_prov_is_running() || ctx == NULL || ctx->mdctx == NULL) return 0; /* * If sig is NULL then we're just finding out the sig size. Other fields * are ignored. Defer to ecdsa_sign. */ if (sig != NULL && !EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen)) return 0; ctx->flag_allow_md = 1; return qat_signature_ecdsa_sign(vctx, sig, siglen, sigsize, digest, (size_t)dlen); } static int qat_ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec, const OSSL_PARAM params[]) { return qat_ecdsa_digest_signverify_init(vctx, mdname, ec, params, EVP_PKEY_OP_VERIFY); } int qat_ecdsa_digest_verify_final(void *vctx, const unsigned char *sig, size_t siglen) { QAT_PROV_ECDSA_CTX *ctx = (QAT_PROV_ECDSA_CTX *)vctx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (!qat_prov_is_running() || ctx == NULL || ctx->mdctx == NULL) return 0; if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen)) return 0; ctx->flag_allow_md = 1; return qat_signature_ecdsa_verify(ctx, sig, siglen, digest, (size_t)dlen); } static void *qat_ecdsa_dupctx(void *vctx) { QAT_PROV_ECDSA_CTX *srcctx = (QAT_PROV_ECDSA_CTX *)vctx; QAT_PROV_ECDSA_CTX *dstctx; if (!qat_prov_is_running()) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; *dstctx = *srcctx; dstctx->ec = NULL; dstctx->md = NULL; dstctx->mdctx = NULL; dstctx->propq = NULL; if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec)) goto err; /* Test KATS should not need to be supported */ if (srcctx->kinv != NULL || srcctx->r != NULL) goto err; dstctx->ec = srcctx->ec; if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) goto err; dstctx->md = srcctx->md; if (srcctx->mdctx != NULL) { dstctx->mdctx = EVP_MD_CTX_new(); if (dstctx->mdctx == NULL || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) goto err; } if (srcctx->propq != NULL) { dstctx->propq = OPENSSL_strdup(srcctx->propq); if (dstctx->propq == NULL) goto err; } return dstctx; err: qat_signature_ecdsa_freectx(dstctx); return NULL; } static int qat_ecdsa_get_ctx_params(void *vctx, OSSL_PARAM *params) { typedef int (*fun_ptr)(void *vctx, OSSL_PARAM *params); fun_ptr fun = get_default_ECDSA_signature().get_ctx_params; if (!fun) return 0; return fun(vctx, params); } static const OSSL_PARAM *qat_ecdsa_gettable_ctx_params(void *vctx, void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vctx, void *provctx); fun_ptr fun = get_default_ECDSA_signature().gettable_ctx_params; if (!fun) return NULL; return fun(vctx, provctx); } static const OSSL_PARAM *qat_ecdsa_settable_ctx_params(void *vctx, void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vctx, void *provctx); fun_ptr fun = get_default_ECDSA_signature().settable_ctx_params; if (!fun) return NULL; return fun(vctx, provctx); } static int qat_ecdsa_get_ctx_md_params(void *vctx, OSSL_PARAM *params) { typedef int (*fun_ptr)(void *vctx, OSSL_PARAM *params); fun_ptr fun = get_default_ECDSA_signature().get_ctx_md_params; if (!fun) return 0; return fun(vctx, params); } static const OSSL_PARAM *qat_ecdsa_gettable_ctx_md_params(void *vctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vctx); fun_ptr fun = get_default_ECDSA_signature().gettable_ctx_md_params; if (!fun) return NULL; return fun(vctx); } static int qat_ecdsa_set_ctx_md_params(void *vctx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *vctx, const OSSL_PARAM params[]); fun_ptr fun = get_default_ECDSA_signature().set_ctx_md_params; if (!fun) return 0; return fun(vctx, params); } static const OSSL_PARAM *qat_ecdsa_settable_ctx_md_params(void *vctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vctx); fun_ptr fun = get_default_ECDSA_signature().settable_ctx_md_params; if (!fun) return 0; return fun(vctx); } const OSSL_DISPATCH qat_ecdsa_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))qat_signature_ecdsa_newctx }, { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))qat_signature_ecdsa_sign_init }, { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))qat_signature_ecdsa_sign }, { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))qat_signature_ecdsa_verify_init }, { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))qat_signature_ecdsa_verify }, { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))qat_signature_ecdsa_freectx }, { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))qat_signature_ecdsa_set_ctx_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))qat_signature_ecdsa_settable_ctx_params }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))qat_ecdsa_digest_sign_init }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, (void (*)(void))qat_ecdsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))qat_ecdsa_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))qat_ecdsa_digest_verify_init }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, (void (*)(void))qat_ecdsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, (void (*)(void))qat_ecdsa_digest_verify_final }, { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))qat_ecdsa_dupctx }, { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))qat_ecdsa_get_ctx_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))qat_ecdsa_gettable_ctx_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))qat_ecdsa_settable_ctx_params }, { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, (void (*)(void))qat_ecdsa_get_ctx_md_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_ecdsa_gettable_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, (void (*)(void))qat_ecdsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_ecdsa_settable_ctx_md_params }, {0, NULL} }; #endif qatengine-1.9.0/qat_prov_ecx.h000066400000000000000000000147501500416242000163400ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_ecx.h * * This file provides an interface to qatprovider X25519 and X448 operations * *****************************************************************************/ #ifndef QAT_PROV_ECX_H # define QAT_PROV_ECX_H # include # include # include # include "e_qat.h" # define X25519_KEYLEN 32 # define X448_KEYLEN 56 # define ED448_KEYLEN 57 # define MAX_KEYLEN 57 typedef struct{ int id; /* libcrypto internal */ int name_id; # if OPENSSL_VERSION_NUMBER >= 0x30300000 /* NID for the legacy alg if there is one */ int legacy_alg; # endif char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; # endif OSSL_FUNC_keymgmt_new_fn *new; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; OSSL_FUNC_keymgmt_set_params_fn *set_params; OSSL_FUNC_keymgmt_settable_params_fn *settable_params; OSSL_FUNC_keymgmt_gen_init_fn *gen_init; OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; # if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_keymgmt_gen_get_params_fn *gen_get_params; OSSL_FUNC_keymgmt_gen_gettable_params_fn *gen_gettable_params; # endif OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; OSSL_FUNC_keymgmt_gen_fn *gen; OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; OSSL_FUNC_keymgmt_load_fn *load; OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; OSSL_FUNC_keymgmt_has_fn *has; OSSL_FUNC_keymgmt_validate_fn *validate; OSSL_FUNC_keymgmt_match_fn *match; OSSL_FUNC_keymgmt_import_fn *import; OSSL_FUNC_keymgmt_import_types_fn *import_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; # endif OSSL_FUNC_keymgmt_export_fn *export; OSSL_FUNC_keymgmt_export_types_fn *export_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; # endif OSSL_FUNC_keymgmt_dup_fn *dup; } QAT_ECX_KEYMGMT; typedef struct evp_keyexch_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_keyexch_newctx_fn *newctx; OSSL_FUNC_keyexch_init_fn *init; OSSL_FUNC_keyexch_set_peer_fn *set_peer; OSSL_FUNC_keyexch_derive_fn *derive; OSSL_FUNC_keyexch_freectx_fn *freectx; OSSL_FUNC_keyexch_dupctx_fn *dupctx; OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; } QAT_EVP_KEYEXCH; QAT_ECX_KEYMGMT get_default_x25519_keymgmt(); QAT_ECX_KEYMGMT get_default_x448_keymgmt(); QAT_EVP_KEYEXCH get_default_x25519_keyexch(); QAT_EVP_KEYEXCH get_default_x448_keyexch(); typedef enum { ECX_KEY_TYPE_X25519, ECX_KEY_TYPE_X448, }ECX_KEY_TYPE; typedef void CRYPTO_RWLOCK; typedef struct qat_ecx_key_st { OSSL_LIB_CTX *libctx; char *propq; unsigned int haspubkey:1; unsigned char pubkey[MAX_KEYLEN]; unsigned char *privkey; size_t keylen; ECX_KEY_TYPE type; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif }ECX_KEY; typedef struct { size_t keylen; ECX_KEY *key; ECX_KEY *peerkey; } QAT_ECX_CTX; typedef struct ecx_gen_ctx { OSSL_LIB_CTX *libctx; char *propq; ECX_KEY_TYPE type; int selection; # if OPENSSL_VERSION_NUMBER >= 0x30200000 unsigned char *dhkem_ikm; size_t dhkem_ikmlen; # endif }QAT_GEN_CTX; int qat_ecx_key_up_ref(ECX_KEY *key); void qat_ecx_key_free(ECX_KEY *key); int qat_pkey_ecx_derive25519(void *ctx, unsigned char *key, size_t *keylen, size_t outlen); int qat_pkey_ecx_derive448(void *ctx, unsigned char *key, size_t *keylen, size_t outlen); void *qat_pkey_ecx25519_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg); void *qat_pkey_ecx448_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg); void* multibuff_x25519_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg); int multibuff_x25519_derive(void *ctx, unsigned char *key, size_t *keylen,size_t outlen); #endif /* QAT_PROV_ECX_H */ qatengine-1.9.0/qat_prov_exch_ecx.c000066400000000000000000000206041500416242000173350ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_exch_ecx.c * * This file contains the qatprovider implementation for X25519 and X448 * QAT_HW & QAT_SW key exchange operations * *****************************************************************************/ #include #include #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_ecx.h" #include "qat_utils.h" #include "e_qat.h" #if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" extern int qat_fips_key_zeroize; #endif QAT_EVP_KEYEXCH get_default_x25519_keyexch() { static QAT_EVP_KEYEXCH s_keyexch; static int initialized = 0; if (!initialized) { QAT_EVP_KEYEXCH *keyexch = (QAT_EVP_KEYEXCH *)EVP_KEYEXCH_fetch(NULL,"X25519","provider=default"); if (keyexch) { s_keyexch = *keyexch; EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); initialized = 1; } else { WARN("EVP_KEYEXCH_fetch from default provider failed"); } } return s_keyexch; } #ifdef ENABLE_QAT_HW_ECX QAT_EVP_KEYEXCH get_default_x448_keyexch() { static QAT_EVP_KEYEXCH s_keyexch; static int initialized = 0; if (!initialized) { QAT_EVP_KEYEXCH *keyexch = (QAT_EVP_KEYEXCH *)EVP_KEYEXCH_fetch(NULL,"X448","provider=default"); if (keyexch) { s_keyexch = *keyexch; EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); initialized = 1; } else { WARN("EVP_KEYEXCH_fetch from default provider failed"); } } return s_keyexch; } #endif static int qat_ecx_derive25519(void *vecxctx, unsigned char *secret, size_t *secretlen, size_t outlen) { int ret = 0; #ifdef ENABLE_QAT_HW_ECX if (qat_hw_ecx_offload) ret = qat_pkey_ecx_derive25519(vecxctx,secret,secretlen,outlen); #endif #ifdef ENABLE_QAT_SW_ECX if (qat_sw_ecx_offload) { ret = multibuff_x25519_derive(vecxctx,secret,secretlen,outlen); } else { typedef int (*fun_ptr)(void *vecxctx, unsigned char *secret, size_t *secretlen, size_t outlen); fun_ptr fun = get_default_x25519_keyexch().derive; if (!fun) return 0; return fun(vecxctx, secret, secretlen, outlen); } #endif return ret; } #ifdef ENABLE_QAT_HW_ECX static int qat_ecx_derive448(void *vecxctx, unsigned char *secret, size_t *secretlen, size_t outlen) { return qat_pkey_ecx_derive448(vecxctx,secret,secretlen,outlen); } #endif static void *qat_ecx_newctx(void *provctx, size_t keylen) { QAT_ECX_CTX *ctx; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(QAT_ECX_CTX)); if (ctx == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } ctx->keylen = keylen; return ctx; } static void *qat_x25519_newctx(void *provctx) { return qat_ecx_newctx(provctx, X25519_KEYLEN); } #ifdef ENABLE_QAT_HW_ECX static void *qat_x448_newctx(void *provctx) { return qat_ecx_newctx(provctx, X448_KEYLEN); } #endif int qat_ecx_key_up_ref(ECX_KEY *key) { int i; # if OPENSSL_VERSION_NUMBER < 0x30200000 if (CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0) return 0; # else if (QAT_CRYPTO_UP_REF(&key->references, &i) <= 0) return 0; # endif if(i < 2) { WARN("refcount error"); return 0; } return ((i >1) ? 1 : 0); } void qat_ecx_key_free(ECX_KEY *key) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif int i; if (key == NULL) return; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_DOWN_REF(&key->references, &i, key->lock); #else QAT_CRYPTO_DOWN_REF(&key->references, &i); #endif if (i > 0) return; if(i < 0) { WARN("refcount error"); return; } OPENSSL_free(key->propq); OPENSSL_secure_clear_free(key->privkey, key->keylen); #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(key->lock); #endif OPENSSL_free(key); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } static int qat_ecx_init(void *vecxctx, void *vkey, ossl_unused const OSSL_PARAM params[]) { QAT_ECX_CTX *ecxctx = (QAT_ECX_CTX *)vecxctx; ECX_KEY *key = vkey; if (!qat_prov_is_running()) return 0; if (ecxctx == NULL || key == NULL || key->keylen != ecxctx->keylen || !qat_ecx_key_up_ref(key)) { QATerr(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } qat_ecx_key_free(ecxctx->key); ecxctx->key = key; return 1; } static int qat_ecx_set_peer(void *vecxctx, void *vkey) { QAT_ECX_CTX *ecxctx = (QAT_ECX_CTX *)vecxctx; ECX_KEY *key = vkey; if (!qat_prov_is_running()) return 0; if (ecxctx == NULL || key == NULL || key->keylen != ecxctx->keylen || !qat_ecx_key_up_ref(key)) { QATerr(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); return 0; } qat_ecx_key_free(ecxctx->peerkey); ecxctx->peerkey = key; return 1; } static void qat_ecx_freectx(void *vecxctx) { QAT_ECX_CTX *ecxctx = (QAT_ECX_CTX *)vecxctx; qat_ecx_key_free(ecxctx->key); qat_ecx_key_free(ecxctx->peerkey); OPENSSL_free(ecxctx); } static void *qat_ecx_dupctx(void *vecxctx) { typedef void * (*fun_ptr)(void *vecxctx); fun_ptr fun = get_default_x25519_keyexch().dupctx; if (!fun) return NULL; return fun(vecxctx); } const OSSL_DISPATCH qat_X25519_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))qat_x25519_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))qat_ecx_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))qat_ecx_derive25519 }, { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))qat_ecx_set_peer }, { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))qat_ecx_freectx }, { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))qat_ecx_dupctx }, { 0, NULL } }; #endif #ifdef QAT_HW # ifdef ENABLE_QAT_HW_ECX const OSSL_DISPATCH qat_X448_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))qat_x448_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))qat_ecx_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))qat_ecx_derive448 }, { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))qat_ecx_set_peer }, { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))qat_ecx_freectx }, {0, NULL } }; # endif #endif qatengine-1.9.0/qat_prov_hkdf.c000066400000000000000000000511251500416242000164650ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_hkdf.c * * This file contains qatprovider implementation of HKDF. * *****************************************************************************/ #include "qat_prov_hkdf.h" #include "e_qat.h" #ifdef ENABLE_QAT_HW_HKDF static OSSL_FUNC_kdf_newctx_fn qat_kdf_hkdf_new; static OSSL_FUNC_kdf_freectx_fn qat_kdf_hkdf_free; static OSSL_FUNC_kdf_reset_fn qat_kdf_hkdf_reset; static OSSL_FUNC_kdf_derive_fn qat_kdf_hkdf_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn qat_kdf_hkdf_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn qat_kdf_hkdf_set_ctx_params; static OSSL_FUNC_kdf_gettable_ctx_params_fn qat_kdf_hkdf_gettable_ctx_params; static OSSL_FUNC_kdf_get_ctx_params_fn qat_kdf_hkdf_get_ctx_params; static OSSL_FUNC_kdf_derive_fn qat_kdf_tls1_3_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn qat_kdf_tls1_3_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn qat_kdf_tls1_3_set_ctx_params; char *kdf_name = NULL; static void qat_prov_digest_reset(PROV_DIGEST *pd) { EVP_MD_free(pd->alloc_md); pd->alloc_md = NULL; pd->md = NULL; pd->engine = NULL; } static const EVP_MD *qat_prov_digest_md(const PROV_DIGEST *pd) { return pd->md; } static int load_common(const OSSL_PARAM params[], const char **propquery, ENGINE **engine) { const OSSL_PARAM *p; *propquery = NULL; p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; *propquery = p->data; } *engine = NULL; return 1; } static const EVP_MD *qat_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx, const char *mdname, const char *propquery) { EVP_MD_free(pd->alloc_md); pd->md = pd->alloc_md = EVP_MD_fetch(libctx, mdname, propquery); return pd->md; } static int qat_prov_digest_load_from_params(PROV_DIGEST *pd, const OSSL_PARAM params[], OSSL_LIB_CTX *ctx) { const OSSL_PARAM *p; const char *propquery; if (params == NULL) return 1; if (!load_common(params, &propquery, &pd->engine)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST); if (p == NULL) return 1; if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; ERR_set_mark(); qat_prov_digest_fetch(pd, ctx, p->data, propquery); if (pd->md != NULL) ERR_pop_to_mark(); else ERR_clear_last_mark(); return pd->md != NULL; } /* Settable context parameters that are common across HKDF and the TLS KDF */ #define HKDF_COMMON_SETTABLES \ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \ OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \ OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0) static void *qat_kdf_hkdf_new(void *provctx) { QAT_KDF_HKDF *ctx; if (!qat_prov_is_running()) return NULL; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } else ctx->provctx = provctx; ctx->evp_pkey_ctx = OPENSSL_zalloc(sizeof(EVP_PKEY_CTX)); if (ctx->evp_pkey_ctx == NULL){ WARN("Not enough memory for hkdf context.\n"); OPENSSL_free(ctx); ctx = NULL; return NULL; } if (!qat_hkdf_init(ctx->evp_pkey_ctx)){ WARN("qat_hkdf_init failed\n"); } return ctx; } static void qat_kdf_hkdf_free(void *vctx) { QAT_KDF_HKDF *ctx = (QAT_KDF_HKDF *)vctx; if (ctx != NULL) { qat_hkdf_cleanup(ctx->evp_pkey_ctx); OPENSSL_free(ctx->evp_pkey_ctx); ctx->evp_pkey_ctx = NULL; qat_kdf_hkdf_reset(ctx); OPENSSL_free(ctx); } } static void qat_kdf_hkdf_reset(void *vctx) { QAT_KDF_HKDF *ctx = (QAT_KDF_HKDF *)vctx; void *provctx = ctx->provctx; qat_prov_digest_reset(&ctx->digest); OPENSSL_free(ctx->salt); OPENSSL_free(ctx->prefix); OPENSSL_free(ctx->label); OPENSSL_clear_free(ctx->data, ctx->data_len); OPENSSL_clear_free(ctx->key, ctx->key_len); OPENSSL_cleanse(ctx->info, ctx->info_len); memset(ctx, 0, sizeof(*ctx)); ctx->provctx = provctx; } static size_t qat_kdf_hkdf_size(QAT_KDF_HKDF *ctx) { int sz; const EVP_MD *md = qat_prov_digest_md(&ctx->digest); if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY) return SIZE_MAX; if (md == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; } sz = EVP_MD_get_size(md); if (sz < 0) return 0; return sz; } static int qat_kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen, const OSSL_PARAM params[]) { QAT_KDF_HKDF *ctx = (QAT_KDF_HKDF *)vctx; QAT_HKDF_CTX *qat_hkdf_ctx = (QAT_HKDF_CTX *)EVP_PKEY_CTX_get_data( ctx->evp_pkey_ctx); const EVP_MD *md; int ret = 0; if (!qat_prov_is_running() || !qat_kdf_hkdf_set_ctx_params(ctx, params)) goto end; md = qat_prov_digest_md(&ctx->digest); if (md == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); goto end; } if (ctx->key == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_KEY); goto end; } if (keylen == 0) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); goto end; } qat_hkdf_ctx->qat_md = md; ret = qat_hkdf_derive(ctx->evp_pkey_ctx, key, &keylen, params); end: return ret; } static EVP_KDF get_default_tls13_kdf() { static EVP_KDF s_kdf; static int initialized = 0; if (!initialized) { EVP_KDF *kdf = (EVP_KDF *)EVP_KDF_fetch(NULL, "TLS13-KDF", "provider=default"); if (kdf) { s_kdf = *kdf; EVP_KDF_free((EVP_KDF *) kdf); initialized = 1; } else { WARN("EVP_KDF_fetch from default provider failed"); } } return s_kdf; } static int qat_kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen, const OSSL_PARAM params[]) { QAT_KDF_HKDF *ctx = (QAT_KDF_HKDF *)vctx; QAT_HKDF_CTX *qat_hkdf_ctx = (QAT_HKDF_CTX *)EVP_PKEY_CTX_get_data( ctx->evp_pkey_ctx); const EVP_MD *md; size_t mdlen; int ret = 0, fallback = 0; #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running() || !qat_kdf_tls1_3_set_ctx_params(ctx, params)) goto end; md = qat_prov_digest_md(&ctx->digest); if (md == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); goto end; } qat_hkdf_ctx->qat_md = md; if (!qat_get_cipher_suite(qat_hkdf_ctx)) { DEBUG("Failed to get cipher suite, fallback to SW\n"); fallback = 1; goto end; } if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); fallback = 1; goto end; } if (ctx->mode == EVP_KDF_HKDF_MODE_EXTRACT_ONLY) { ret = EVP_MD_get_size(md); /* Ensure cast to size_t is safe */ if (ret <= 0) goto end; mdlen = (size_t)ret; if (ctx->key == NULL) { ctx->key = OPENSSL_zalloc(EVP_MAX_MD_SIZE); ctx->key_len = mdlen; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_KEY, ctx->key_len, ctx->key)){ WARN("Failed to setup tls13-kdf key.\n"); goto end; } } if (ctx->salt != NULL) { ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_LABEL; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_MODE, ctx->mode, NULL)){ WARN("Failed to setup tls13-kdf mode.\n"); goto end; } ret = qat_hkdf_derive(ctx->evp_pkey_ctx, key, &keylen, params); if (ret <= 0) { WARN("Failed to generate the pre-extract secret.\n"); goto end; } ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_MODE, ctx->mode, NULL)){ WARN("Failed to setup tls13-kdf extract mode.\n"); goto end; } if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_SALT, keylen, key)){ WARN("Failed to setup salt for tls13-kdf extract operation\n"); goto end; } if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_KEY, ctx->key_len, ctx->key)){ WARN("Failed to setup key for tls13-kdf extract operation.\n"); goto end; } } } ret = qat_hkdf_derive(ctx->evp_pkey_ctx, key, &keylen, params); end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif if (fallback) { typedef int(*sw_fun_ptr)(void *, unsigned char *, size_t , const OSSL_PARAM *); sw_fun_ptr default_prov_tls13_kdf_fun = get_default_tls13_kdf().derive; ret = default_prov_tls13_kdf_fun(vctx, key, keylen, params); } return ret; } static int qat_hkdf_common_set_ctx_params(const char *kdf_name, QAT_KDF_HKDF *ctx, const OSSL_PARAM params[]) { OSSL_LIB_CTX *libctx = prov_libctx_of(ctx->provctx); const OSSL_PARAM *p; int n; if (params == NULL) return 1; if (!qat_prov_digest_load_from_params(&ctx->digest, params, libctx)) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_MODE)) != NULL) { if (p->data_type == OSSL_PARAM_UTF8_STRING) { if (strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) { ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; } else if (strcasecmp(p->data, "EXTRACT_ONLY") == 0) { ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; } else if (strcasecmp(p->data, "EXPAND_ONLY") == 0) { if(!strcmp((const char*)kdf_name, "HKDF")) ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; if(!strcmp((const char*)kdf_name, "TLS13-KDF")) ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_LABEL; } else { QATerr(ERR_LIB_PROV, PROV_R_INVALID_MODE); return 0; } } else if (OSSL_PARAM_get_int(p, &n)) { if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND && n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY && n != EVP_KDF_HKDF_MODE_EXPAND_LABEL && n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_MODE); return 0; } ctx->mode = n; } else { QATerr(ERR_LIB_PROV, PROV_R_INVALID_MODE); return 0; } if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_MODE, ctx->mode, NULL)){ WARN("Failed in setting hkdf mode.\n"); return 0; } } if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) { OPENSSL_clear_free(ctx->key, ctx->key_len); ctx->key = NULL; if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->key, 0, &ctx->key_len)) return 0; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_KEY, ctx->key_len, ctx->key)){ WARN("Failed in setting hkdf key.\n"); return 0; } } if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) { if (p->data_size != 0 && p->data != NULL) { OPENSSL_free(ctx->salt); ctx->salt = NULL; if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, &ctx->salt_len)) return 0; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_SALT, ctx->salt_len, ctx->salt)) { WARN("Failed in setting hkdf salt.\n"); return 0; } } } return 1; } static int qat_kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; QAT_KDF_HKDF *ctx = vctx; if (params == NULL) return 1; EVP_KDF *kdf = (EVP_KDF *)EVP_KDF_fetch(NULL, "HKDF", "provider=qatprovider"); const char *name = EVP_KDF_get0_name(kdf); kdf_name = (char *)name; if (!qat_hkdf_common_set_ctx_params(kdf_name, ctx, params)) return 0; /* The info fields concatenate, so process them all */ if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) { ctx->info_len = 0; for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_INFO)) { const void *q = ctx->info + ctx->info_len; size_t sz = 0; if (p->data_size != 0 && p->data != NULL && !OSSL_PARAM_get_octet_string(p, (void **)&q, HKDF_MAXBUF - ctx->info_len, &sz)) return 0; ctx->info_len += sz; } if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_INFO, ctx->info_len, ctx->info)){ WARN("Failed in setting hkdf info.\n"); return 0; } } return 1; } static const OSSL_PARAM *qat_kdf_hkdf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { HKDF_COMMON_SETTABLES, OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), OSSL_PARAM_END }; return known_settable_ctx_params; } static const OSSL_PARAM *qat_kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { HKDF_COMMON_SETTABLES, OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0), OSSL_PARAM_END }; return known_settable_ctx_params; } static int qat_kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; QAT_KDF_HKDF *ctx = vctx; if (params == NULL) return 1; EVP_KDF *kdf = (EVP_KDF *)EVP_KDF_fetch(NULL, "TLS13-KDF", "provider=qatprovider"); const char *name = EVP_KDF_get0_name(kdf); kdf_name = (char *)name; if (!qat_hkdf_common_set_ctx_params(kdf_name, ctx, params)) return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PREFIX)) != NULL) { OPENSSL_free(ctx->prefix); ctx->prefix = NULL; if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->prefix, 0, &ctx->prefix_len)) return 0; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_PREFIX, ctx->prefix_len, ctx->prefix)){ WARN("Failed in setting hkdf info.\n"); return 0; } } if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_LABEL)) != NULL) { OPENSSL_free(ctx->label); ctx->label = NULL; if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->label, 0, &ctx->label_len)) return 0; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_LABEL, ctx->label_len, ctx->label)){ WARN("Failed in setting hkdf info.\n"); return 0; } } OPENSSL_clear_free(ctx->data, ctx->data_len); ctx->data = NULL; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DATA)) != NULL && !OSSL_PARAM_get_octet_string(p, (void **)&ctx->data, 0, &ctx->data_len)) return 0; if (!qat_hkdf_ctrl(ctx->evp_pkey_ctx, EVP_PKEY_CTRL_HKDF_DATA, ctx->data_len, ctx->data)){ WARN("Failed in setting hkdf info.\n"); return 0; } return 1; } static int qat_kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) { QAT_KDF_HKDF *ctx = (QAT_KDF_HKDF *)vctx; OSSL_PARAM *p; if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) { size_t sz = qat_kdf_hkdf_size(ctx); if (sz == 0) return 0; return OSSL_PARAM_set_size_t(p, sz); } return -2; } static const OSSL_PARAM *qat_kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END }; return known_gettable_ctx_params; } const OSSL_DISPATCH qat_kdf_hkdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))qat_kdf_hkdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))qat_kdf_hkdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))qat_kdf_hkdf_reset }, { OSSL_FUNC_KDF_DERIVE, (void(*)(void))qat_kdf_hkdf_derive }, { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void(*)(void))qat_kdf_hkdf_settable_ctx_params }, { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))qat_kdf_hkdf_set_ctx_params }, { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))qat_kdf_hkdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))qat_kdf_hkdf_get_ctx_params }, { 0, NULL } }; const OSSL_DISPATCH qat_kdf_tls1_3_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))qat_kdf_hkdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))qat_kdf_hkdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))qat_kdf_hkdf_reset }, { OSSL_FUNC_KDF_DERIVE, (void(*)(void))qat_kdf_tls1_3_derive }, { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void(*)(void))qat_kdf_tls1_3_settable_ctx_params }, { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))qat_kdf_tls1_3_set_ctx_params }, { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))qat_kdf_hkdf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))qat_kdf_hkdf_get_ctx_params }, { 0, NULL } }; #endif /* ENABLE_QAT_HW_HKDF */ qatengine-1.9.0/qat_prov_hkdf.h000066400000000000000000000170621500416242000164740ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_hkdf.h * * This file contains qatprovider interface of HKDF. * *****************************************************************************/ #ifndef QAT_PROV_HKDF_H # define QAT_PROV_HKDF_H # ifdef ENABLE_QAT_HW_HKDF # include # include # include # include # include # include # include # include # include # include # include # include "qat_provider.h" # include "qat_hw_hkdf.h" # include "e_qat.h" # include "qat_prov_hkdf_packet.h" # define HKDF_MAXBUF 1024 typedef void CRYPTO_RWLOCK; struct kdf_data_st { OSSL_LIB_CTX *libctx; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif }; typedef struct kdf_data_st QAT_KDF_DATA; typedef struct { /* * References to the underlying digest implementation. |md| caches * the digest, always. |alloc_md| only holds a reference to an explicitly * fetched digest. */ const EVP_MD *md; /* digest */ EVP_MD *alloc_md; /* fetched digest */ /* Conditions for legacy EVP_MD uses */ ENGINE *engine; /* digest engine */ } PROV_DIGEST; typedef struct { void *provctx; int mode; PROV_DIGEST digest; unsigned char *salt; size_t salt_len; unsigned char *key; size_t key_len; unsigned char *prefix; size_t prefix_len; unsigned char *label; size_t label_len; unsigned char *data; size_t data_len; unsigned char info[QAT_HKDF_INFO_MAXBUF]; size_t info_len; EVP_PKEY_CTX *evp_pkey_ctx; } QAT_KDF_HKDF; struct evp_kdf_st { OSSL_PROVIDER *prov; int name_id; char *type_name; const char *description; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_kdf_newctx_fn *newctx; OSSL_FUNC_kdf_dupctx_fn *dupctx; OSSL_FUNC_kdf_freectx_fn *freectx; OSSL_FUNC_kdf_reset_fn *reset; OSSL_FUNC_kdf_derive_fn *derive; OSSL_FUNC_kdf_gettable_params_fn *gettable_params; OSSL_FUNC_kdf_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_kdf_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_kdf_get_params_fn *get_params; OSSL_FUNC_kdf_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_kdf_set_ctx_params_fn *set_ctx_params; }; typedef struct evp_kdf_st EVP_KDF; struct evp_pkey_ctx_st { /* Actual operation */ int operation; /* * Library context, property query, keytype and keymgmt associated with * this context */ OSSL_LIB_CTX *libctx; char *propquery; const char *keytype; /* If |pkey| below is set, this field is always a reference to its keymgmt */ EVP_KEYMGMT *keymgmt; union { struct { void *genctx; } keymgmt; struct { EVP_KEYEXCH *exchange; /* * Opaque ctx returned from a providers exchange algorithm * implementation OSSL_FUNC_keyexch_newctx() */ void *algctx; } kex; struct { EVP_SIGNATURE *signature; /* * Opaque ctx returned from a providers signature algorithm * implementation OSSL_FUNC_signature_newctx() */ void *algctx; } sig; struct { EVP_ASYM_CIPHER *cipher; /* * Opaque ctx returned from a providers asymmetric cipher algorithm * implementation OSSL_FUNC_asym_cipher_newctx() */ void *algctx; } ciph; struct { EVP_KEM *kem; /* * Opaque ctx returned from a providers KEM algorithm * implementation OSSL_FUNC_kem_newctx() */ void *algctx; } encap; } op; /* * Cached parameters. Inits of operations that depend on these should * call evp_pkey_ctx_use_delayed_data() when the operation has been set * up properly. */ struct { /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */ char *dist_id_name; /* The name used with EVP_PKEY_CTX_ctrl_str() */ void *dist_id; /* The distinguishing ID itself */ size_t dist_id_len; /* The length of the distinguishing ID */ /* Indicators of what has been set. Keep them together! */ unsigned int dist_id_set : 1; } cached_parameters; /* Application specific data, usually used by the callback */ void *app_data; /* Keygen callback */ EVP_PKEY_gen_cb *pkey_gencb; /* implementation specific keygen data */ int *keygen_info; int keygen_info_count; /* Legacy fields below */ /* EVP_PKEY identity */ int legacy_keytype; /* Method associated with this operation */ const EVP_PKEY_METHOD *pmeth; /* Engine that implements this method or NULL if builtin */ ENGINE *engine; /* Key: may be NULL */ EVP_PKEY *pkey; /* Peer key for key agreement, may be NULL */ EVP_PKEY *peerkey; /* Algorithm specific data */ void *data; /* Indicator if digest_custom needs to be called */ unsigned int flag_call_digest_custom:1; /* * Used to support taking custody of memory in the case of a provider being * used with the deprecated EVP_PKEY_CTX_set_rsa_keygen_pubexp() API. This * member should NOT be used for any other purpose and should be removed * when said deprecated API is excised completely. */ BIGNUM *rsa_pubexp; } /* EVP_PKEY_CTX */ ; int qat_get_cipher_suite(QAT_HKDF_CTX * qat_hkdf_ctx); # endif /* ENABLE_QAT_HW_HKDF */ #endif /* QAT_PROV_HKDF_H */ qatengine-1.9.0/qat_prov_hkdf_packet.c000066400000000000000000000430601500416242000200130ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_hkdf_packet.c * * This file contains the TLS13-KDF hkdflabel implementation * *****************************************************************************/ #include "qat_prov_hkdf_packet.h" #include "qat_prov_sign_sm2.h" #include #define DEFAULT_BUF_SIZE 256 #define QAT_DER_OID_V_ecdsa_with_SHA1 QAT_DER_P_OBJECT, 7, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01 #define QAT_DER_OID_SZ_ecdsa_with_SHA1 9 extern const unsigned char qat_der_oid_ecdsa_with_SHA1[QAT_DER_OID_SZ_ecdsa_with_SHA1]; #define QAT_DER_OID_V_ecdsa_with_SHA224 QAT_DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01 #define QAT_DER_OID_SZ_ecdsa_with_SHA224 10 extern const unsigned char qat_der_oid_ecdsa_with_SHA224[QAT_DER_OID_SZ_ecdsa_with_SHA224]; #define QAT_DER_OID_V_ecdsa_with_SHA256 QAT_DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 #define QAT_DER_OID_SZ_ecdsa_with_SHA256 10 extern const unsigned char qat_der_oid_ecdsa_with_SHA256[QAT_DER_OID_SZ_ecdsa_with_SHA256]; #define QAT_DER_OID_V_ecdsa_with_SHA384 QAT_DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03 #define QAT_DER_OID_SZ_ecdsa_with_SHA384 10 extern const unsigned char qat_der_oid_ecdsa_with_SHA384[QAT_DER_OID_SZ_ecdsa_with_SHA384]; #define QAT_DER_OID_V_ecdsa_with_SHA512 QAT_DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04 #define QAT_DER_OID_SZ_ecdsa_with_SHA512 10 extern const unsigned char qat_der_oid_ecdsa_with_SHA512[QAT_DER_OID_SZ_ecdsa_with_SHA512]; const unsigned char qat_der_oid_ecdsa_with_SHA1[QAT_DER_OID_SZ_ecdsa_with_SHA1] = { QAT_DER_OID_V_ecdsa_with_SHA1 }; const unsigned char qat_der_oid_ecdsa_with_SHA224[QAT_DER_OID_SZ_ecdsa_with_SHA224] = { QAT_DER_OID_V_ecdsa_with_SHA224 }; const unsigned char qat_der_oid_ecdsa_with_SHA256[QAT_DER_OID_SZ_ecdsa_with_SHA256] = { QAT_DER_OID_V_ecdsa_with_SHA256 }; const unsigned char qat_der_oid_ecdsa_with_SHA384[QAT_DER_OID_SZ_ecdsa_with_SHA384] = { QAT_DER_OID_V_ecdsa_with_SHA384 }; const unsigned char qat_der_oid_ecdsa_with_SHA512[QAT_DER_OID_SZ_ecdsa_with_SHA512] = { QAT_DER_OID_V_ecdsa_with_SHA512 }; /* Aliases so we can have a uniform MD_CASE */ #define qat_der_oid_id_ecdsa_with_sha1 qat_der_oid_ecdsa_with_SHA1 #define qat_der_oid_id_ecdsa_with_sha224 qat_der_oid_ecdsa_with_SHA224 #define qat_der_oid_id_ecdsa_with_sha256 qat_der_oid_ecdsa_with_SHA256 #define qat_der_oid_id_ecdsa_with_sha384 qat_der_oid_ecdsa_with_SHA384 #define qat_der_oid_id_ecdsa_with_sha512 qat_der_oid_ecdsa_with_SHA512 #define QAT_MD_CASE(name) \ case NID_##name: \ precompiled = qat_der_oid_id_ecdsa_with_##name; \ precompiled_sz = sizeof(qat_der_oid_id_ecdsa_with_##name); \ break; unsigned char qat_der_oid_sm2_with_SM3[DER_OID_SZ_sm2_with_SM3] = { 6, 8, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 }; int QAT_WPACKET_allocate_bytes(qat_WPACKET *pkt, size_t len, unsigned char **allocbytes) { if (!QAT_WPACKET_reserve_bytes(pkt, len, allocbytes)) return 0; pkt->written += len; pkt->curr += len; return 1; } #define GETBUF(p) (((p)->staticbuf != NULL) \ ? (p)->staticbuf \ : ((p)->buf != NULL \ ? (unsigned char *)(p)->buf->data \ : NULL)) int QAT_WPACKET_reserve_bytes(qat_WPACKET *pkt, size_t len, unsigned char **allocbytes) { /* Internal API, so should not fail */ if (!ossl_assert(pkt->subs != NULL && len != 0)) return 0; if (pkt->maxsize - pkt->written < len) return 0; if (pkt->buf != NULL && (pkt->buf->length - pkt->written < len)) { size_t newlen; size_t reflen; reflen = (len > pkt->buf->length) ? len : pkt->buf->length; if (reflen > SIZE_MAX / 2) { newlen = SIZE_MAX; } else { newlen = reflen * 2; if (newlen < DEFAULT_BUF_SIZE) newlen = DEFAULT_BUF_SIZE; } if (BUF_MEM_grow(pkt->buf, newlen) == 0) return 0; } if (allocbytes != NULL) { *allocbytes = QAT_WPACKET_get_curr(pkt); if (pkt->endfirst && *allocbytes != NULL) *allocbytes -= len; } return 1; } static size_t QAT_maxmaxsize(size_t lenbytes) { if (lenbytes >= sizeof(size_t) || lenbytes == 0) return SIZE_MAX; return ((size_t)1 << (lenbytes * 8)) - 1 + lenbytes; } static int QAT_wpacket_intern_init_len(qat_WPACKET *pkt, size_t lenbytes) { unsigned char *lenchars; pkt->curr = 0; pkt->written = 0; if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) { ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } if (lenbytes == 0) return 1; pkt->subs->pwritten = lenbytes; pkt->subs->lenbytes = lenbytes; if (!QAT_WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) { OPENSSL_free(pkt->subs); pkt->subs = NULL; return 0; } pkt->subs->packet_len = 0; return 1; } int QAT_WPACKET_init_static_len(qat_WPACKET *pkt, unsigned char *buf, size_t len, size_t lenbytes) { size_t max = QAT_maxmaxsize(lenbytes); /* Internal API, so should not fail */ if (!ossl_assert(buf != NULL && len > 0)) return 0; pkt->staticbuf = buf; pkt->buf = NULL; pkt->maxsize = (max < len) ? max : len; pkt->endfirst = 0; return QAT_wpacket_intern_init_len(pkt, lenbytes); } /* Store the |value| of length |len| at location |data| */ static int QAT_put_value(unsigned char *data, uint64_t value, size_t len) { if (data == NULL) return 1; for (data += len - 1; len > 0; len--) { *data = (unsigned char)(value & 0xff); data--; value >>= 8; } /* Check whether we could fit the value in the assigned number of bytes */ if (value > 0) return 0; return 1; } /* * Internal helper function used by qat_QAT_WPACKET_close(), QAT_WPACKET_finish() and * qat_WPACKET_fill_lengths() to close a sub-packet and write out its length if * necessary. If |doclose| is 0 then it goes through the motions of closing * (i.e. it fills in all the lengths), but doesn't actually close anything. */ static int QAT_wpacket_intern_close(qat_WPACKET *pkt, qat_WPACKET_SUB *sub, int doclose) { size_t packlen = pkt->written - sub->pwritten; if (packlen == 0 && (sub->flags & QAT_WPACKET_FLAGS_NON_ZERO_LENGTH) != 0) return 0; if (packlen == 0 && sub->flags & QAT_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) { /* We can't handle this case. Return an error */ if (!doclose) return 0; /* Deallocate any bytes allocated for the length of the qat_WPACKET */ if ((pkt->curr - sub->lenbytes) == sub->packet_len) { pkt->written -= sub->lenbytes; pkt->curr -= sub->lenbytes; } /* Don't write out the packet length */ sub->packet_len = 0; sub->lenbytes = 0; } /* Write out the qat_WPACKET length if needed */ if (sub->lenbytes > 0) { unsigned char *buf = GETBUF(pkt); if (buf != NULL && !QAT_put_value(&buf[sub->packet_len], packlen, sub->lenbytes)) return 0; } else if (pkt->endfirst && sub->parent != NULL && (packlen != 0 || (sub->flags & QAT_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) == 0)) { size_t tmplen = packlen; size_t numlenbytes = 1; while ((tmplen = tmplen >> 8) > 0) numlenbytes++; if (!QAT_WPACKET_put_bytes__(pkt, packlen, numlenbytes)) return 0; if (packlen > 0x7f) { numlenbytes |= 0x80; if (!QAT_WPACKET_put_bytes_u8(pkt, numlenbytes)) return 0; } } if (doclose) { pkt->subs = sub->parent; OPENSSL_free(sub); } return 1; } int QAT_WPACKET_close(qat_WPACKET *pkt) { /* * Internal API, so should not fail - but we do negative testing of this * so no assert (otherwise the tests fail) */ if (pkt->subs == NULL || pkt->subs->parent == NULL) return 0; return QAT_wpacket_intern_close(pkt, pkt->subs, 1); } int QAT_WPACKET_finish(qat_WPACKET *pkt) { int ret; /* * Internal API, so should not fail - but we do negative testing of this * so no assert (otherwise the tests fail) */ if (pkt->subs == NULL || pkt->subs->parent != NULL) return 0; ret = QAT_wpacket_intern_close(pkt, pkt->subs, 1); if (ret) { OPENSSL_free(pkt->subs); pkt->subs = NULL; } return ret; } int QAT_WPACKET_start_sub_packet_len__(qat_WPACKET *pkt, size_t lenbytes) { qat_WPACKET_SUB *sub; unsigned char *lenchars; /* Internal API, so should not fail */ if (!ossl_assert(pkt->subs != NULL)) return 0; /* We don't support lenbytes greater than 0 when doing endfirst writing */ if (lenbytes > 0 && pkt->endfirst) return 0; if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) { ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } sub->parent = pkt->subs; pkt->subs = sub; sub->pwritten = pkt->written + lenbytes; sub->lenbytes = lenbytes; if (lenbytes == 0) { sub->packet_len = 0; return 1; } sub->packet_len = pkt->written; if (!QAT_WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) return 0; return 1; } int QAT_WPACKET_start_sub_packet(qat_WPACKET *pkt) { return QAT_WPACKET_start_sub_packet_len__(pkt, 0); } int QAT_WPACKET_put_bytes__(qat_WPACKET *pkt, uint64_t val, size_t size) { unsigned char *data; /* Internal API, so should not fail */ if (!ossl_assert(size <= sizeof(uint64_t)) || !QAT_WPACKET_allocate_bytes(pkt, size, &data) || !QAT_put_value(data, val, size)) return 0; return 1; } int QAT_WPACKET_memcpy(qat_WPACKET *pkt, const void *src, size_t len) { unsigned char *dest; if (len == 0) return 1; if (!QAT_WPACKET_allocate_bytes(pkt, len, &dest)) return 0; if (dest != NULL) memcpy(dest, src, len); return 1; } int QAT_WPACKET_sub_memcpy__(qat_WPACKET *pkt, const void *src, size_t len, size_t lenbytes) { if (!QAT_WPACKET_start_sub_packet_len__(pkt, lenbytes) || !QAT_WPACKET_memcpy(pkt, src, len) || !QAT_WPACKET_close(pkt)) return 0; return 1; } int QAT_WPACKET_get_total_written(qat_WPACKET *pkt, size_t *written) { /* Internal API, so should not fail */ if (!ossl_assert(written != NULL)) return 0; *written = pkt->written; return 1; } unsigned char *QAT_WPACKET_get_curr(qat_WPACKET *pkt) { unsigned char *buf = GETBUF(pkt); if (buf == NULL) return NULL; if (pkt->endfirst) return buf + pkt->maxsize - pkt->curr; return buf + pkt->curr; } int WPACKET_is_null_buf(qat_WPACKET *pkt) { return pkt->buf == NULL && pkt->staticbuf == NULL; } void QAT_WPACKET_cleanup(qat_WPACKET *pkt) { qat_WPACKET_SUB *sub, *parent; for (sub = pkt->subs; sub != NULL; sub = parent) { parent = sub->parent; OPENSSL_free(sub); } pkt->subs = NULL; } int QAT_WPACKET_init_der(qat_WPACKET *pkt, unsigned char *buf, size_t len) { /* Internal API, so should not fail */ if (!ossl_assert(buf != NULL && len > 0)) return 0; pkt->staticbuf = buf; pkt->buf = NULL; pkt->maxsize = len; pkt->endfirst = 1; return QAT_wpacket_intern_init_len(pkt, 0); } int QAT_WPACKET_set_flags(qat_WPACKET *pkt, unsigned int flags) { /* Internal API, so should not fail */ if (!ossl_assert(pkt->subs != NULL)) return 0; pkt->subs->flags = flags; return 1; } /*SM2 releated functions*/ int qat_int_end_context(qat_WPACKET *pkt, int tag) { /* * If someone set the flag WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH on this * sub-packet and this sub-packet has nothing written to it, the DER length * will not be written, and the total written size will be unchanged before * and after WPACKET_close(). We use size1 and size2 to determine if * anything was written, and only write our tag if it has. * */ size_t size1, size2; if (tag < 0) return 1; if (!ossl_assert(tag <= 30)) return 0; /* Context specific are normally (?) constructed */ tag |= QAT_DER_F_CONSTRUCTED | QAT_DER_C_CONTEXT; return QAT_WPACKET_get_total_written(pkt, &size1) && QAT_WPACKET_close(pkt) && QAT_WPACKET_get_total_written(pkt, &size2) && (size1 == size2 || QAT_WPACKET_put_bytes_u8(pkt, tag)); } int qat_int_start_context(qat_WPACKET *pkt, int tag) { if (tag < 0) return 1; if (!ossl_assert(tag <= 30)) return 0; return QAT_WPACKET_start_sub_packet(pkt); } int qat_DER_w_end_sequence(qat_WPACKET *pkt, int tag) { /* * If someone set the flag WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH on this * sub-packet and this sub-packet has nothing written to it, the DER length * will not be written, and the total written size will be unchanged before * and after WPACKET_close(). We use size1 and size2 to determine if * anything was written, and only write our tag if it has. * * Because we know that qat_int_end_context() needs to do the same check, * we reproduce this flag if the written length was unchanged, or we will * have an erroneous context tag. */ size_t size1, size2; return QAT_WPACKET_get_total_written(pkt, &size1) && QAT_WPACKET_close(pkt) && QAT_WPACKET_get_total_written(pkt, &size2) && (size1 == size2 ? QAT_WPACKET_set_flags(pkt, QAT_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) : QAT_WPACKET_put_bytes_u8(pkt, QAT_DER_F_CONSTRUCTED | QAT_DER_P_SEQUENCE)) && qat_int_end_context(pkt, tag); } int qat_DER_w_precompiled(qat_WPACKET *pkt, int tag, const unsigned char *precompiled, size_t precompiled_n) { return qat_int_start_context(pkt, tag) && QAT_WPACKET_memcpy(pkt, precompiled, precompiled_n) && qat_int_end_context(pkt, tag); } /* Constructed things need a start and an end */ int qat_DER_w_begin_sequence(qat_WPACKET *pkt, int tag) { return qat_int_start_context(pkt, tag) && QAT_WPACKET_start_sub_packet(pkt); } int qat_DER_w_algorithmIdentifier_ECDSA_with_MD(qat_WPACKET *pkt, int cont, EC_KEY *ec, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; switch (mdnid) { QAT_MD_CASE(sha1); QAT_MD_CASE(sha224); QAT_MD_CASE(sha256); QAT_MD_CASE(sha384); QAT_MD_CASE(sha512); default: return 0; } return qat_DER_w_begin_sequence(pkt, cont) /* No parameters (yet?) */ && qat_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) && qat_DER_w_end_sequence(pkt, cont); } int qat_DER_w_algorithmIdentifier_SM2_with_MD(qat_WPACKET *pkt, int cont, EC_KEY *ec, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; switch (mdnid) { case NID_sm3: precompiled = qat_der_oid_sm2_with_SM3; precompiled_sz = sizeof(qat_der_oid_sm2_with_SM3); default: return 0; } return qat_DER_w_begin_sequence(pkt, cont) /* No parameters (yet?) */ && qat_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) && qat_DER_w_end_sequence(pkt, cont); } qatengine-1.9.0/qat_prov_hkdf_packet.h000066400000000000000000000713611500416242000200250ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_hkdf_packet.h * * This file provides an interface to TLS13-KDF hkdflabel. * *****************************************************************************/ # pragma once # include # include # include # include # include /* * QAT_DER UNIVERSAL tags, occupying bits 1-5 in the QAT_DER identifier byte * These are only valid for the UNIVERSAL class. With the other classes, * these bits have a different meaning. */ #define QAT_DER_P_EOC 0 /* BER End Of Contents tag */ #define QAT_DER_P_BOOLEAN 1 #define QAT_DER_P_INTEGER 2 #define QAT_DER_P_BIT_STRING 3 #define QAT_DER_P_OCTET_STRING 4 #define QAT_DER_P_NULL 5 #define QAT_DER_P_OBJECT 6 #define QAT_DER_P_OBJECT_DESCRIPTOR 7 #define QAT_DER_P_EXTERNAL 8 #define QAT_DER_P_REAL 9 #define QAT_DER_P_ENUMERATED 10 #define QAT_DER_P_UTF8STRING 12 #define QAT_DER_P_SEQUENCE 16 #define QAT_DER_P_SET 17 #define QAT_DER_P_NUMERICSTRING 18 #define QAT_DER_P_PRINTABLESTRING 19 #define QAT_DER_P_T61STRING 20 #define QAT_DER_P_VIDEOTEXSTRING 21 #define QAT_DER_P_IA5STRING 22 #define QAT_DER_P_UTCTIME 23 #define QAT_DER_P_GENERALIZEDTIME 24 #define QAT_DER_P_GRAPHICSTRING 25 #define QAT_DER_P_ISO64STRING 26 #define QAT_DER_P_GENERALSTRING 27 #define QAT_DER_P_UNIVERSALSTRING 28 #define QAT_DER_P_BMPSTRING 30 /* QAT_DER Flags, occupying bit 6 in the QAT_DER identifier byte */ #define QAT_DER_F_PRIMITIVE 0x00 #define QAT_DER_F_CONSTRUCTED 0x20 /* QAT_DER classes tags, occupying bits 7-8 in the QAT_DER identifier byte */ #define QAT_DER_C_UNIVERSAL 0x00 #define QAT_DER_C_APPLICATION 0x40 #define QAT_DER_C_CONTEXT 0x80 #define QAT_DER_C_PRIVATE 0xC0 #ifdef NDEBUG # define ossl_assert(x) ((x) != 0) #else __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr, const char *file, int line) { if (!expr) OPENSSL_die(exprstr, file, line); return expr; } # define ossl_assert(x) ossl_assert_int((x) != 0, "Assertion failed: "#x, \ __FILE__, __LINE__) #endif /* * Convenience macros for calling WPACKET_start_sub_packet_len with different * lengths */ #define QAT_WPACKET_start_sub_packet_u8(pkt) \ QAT_WPACKET_start_sub_packet_len__((pkt), 1) #define QAT_WPACKET_start_sub_packet_u16(pkt) \ QAT_WPACKET_start_sub_packet_len__((pkt), 2) #define QAT_WPACKET_start_sub_packet_u24(pkt) \ QAT_WPACKET_start_sub_packet_len__((pkt), 3) #define QAT_WPACKET_start_sub_packet_u32(pkt) \ QAT_WPACKET_start_sub_packet_len__((pkt), 4) typedef struct { /* Pointer to where we are currently reading from */ const unsigned char *curr; /* Number of bytes remaining */ size_t remaining; } PACKET; /* Internal unchecked shorthand; don't use outside this file. */ static ossl_inline void packet_forward(PACKET *pkt, size_t len) { pkt->curr += len; pkt->remaining -= len; } /* * Returns the number of bytes remaining to be read in the PACKET */ static ossl_inline size_t PACKET_remaining(const PACKET *pkt) { return pkt->remaining; } /* * Returns a pointer to the first byte after the packet data. * Useful for integrating with non-PACKET parsing code. * Specifically, we use PACKET_end() to verify that a d2i_... call * has consumed the entire packet contents. */ static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt) { return pkt->curr + pkt->remaining; } /* * Returns a pointer to the PACKET's current position. * For use in non-PACKETized APIs. */ static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt) { return pkt->curr; } /* * Initialise a PACKET with |len| bytes held in |buf|. This does not make a * copy of the data so |buf| must be present for the whole time that the PACKET * is being used. */ __owur static ossl_inline int PACKET_buf_init(PACKET *pkt, const unsigned char *buf, size_t len) { /* Sanity check for negative values. */ if (len > (size_t)(SIZE_MAX / 2)) return 0; pkt->curr = buf; pkt->remaining = len; return 1; } /* Initialize a PACKET to hold zero bytes. */ static ossl_inline void PACKET_null_init(PACKET *pkt) { pkt->curr = NULL; pkt->remaining = 0; } /* * Returns 1 if the packet has length |num| and its contents equal the |num| * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal). * If lengths are equal, performs the comparison in constant time. */ __owur static ossl_inline int PACKET_equal(const PACKET *pkt, const void *ptr, size_t num) { if (PACKET_remaining(pkt) != num) return 0; return CRYPTO_memcmp(pkt->curr, ptr, num) == 0; } /* * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|. * Data is not copied: the |subpkt| packet will share its underlying buffer with * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. */ __owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt, PACKET *subpkt, size_t len) { if (PACKET_remaining(pkt) < len) return 0; return PACKET_buf_init(subpkt, pkt->curr, len); } /* * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not * copied: the |subpkt| packet will share its underlying buffer with the * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. */ __owur static ossl_inline int PACKET_get_sub_packet(PACKET *pkt, PACKET *subpkt, size_t len) { if (!PACKET_peek_sub_packet(pkt, subpkt, len)) return 0; packet_forward(pkt, len); return 1; } /* * Peek ahead at 2 bytes in network order from |pkt| and store the value in * |*data| */ __owur static ossl_inline int PACKET_peek_net_2(const PACKET *pkt, unsigned int *data) { if (PACKET_remaining(pkt) < 2) return 0; *data = ((unsigned int)(*pkt->curr)) << 8; *data |= *(pkt->curr + 1); return 1; } /* Equivalent of n2s */ /* Get 2 bytes in network order from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_get_net_2(PACKET *pkt, unsigned int *data) { if (!PACKET_peek_net_2(pkt, data)) return 0; packet_forward(pkt, 2); return 1; } /* Same as PACKET_get_net_2() but for a size_t */ __owur static ossl_inline int PACKET_get_net_2_len(PACKET *pkt, size_t *data) { unsigned int i; int ret = PACKET_get_net_2(pkt, &i); if (ret) *data = (size_t)i; return ret; } /* * Peek ahead at 3 bytes in network order from |pkt| and store the value in * |*data| */ __owur static ossl_inline int PACKET_peek_net_3(const PACKET *pkt, unsigned long *data) { if (PACKET_remaining(pkt) < 3) return 0; *data = ((unsigned long)(*pkt->curr)) << 16; *data |= ((unsigned long)(*(pkt->curr + 1))) << 8; *data |= *(pkt->curr + 2); return 1; } /* Equivalent of n2l3 */ /* Get 3 bytes in network order from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_get_net_3(PACKET *pkt, unsigned long *data) { if (!PACKET_peek_net_3(pkt, data)) return 0; packet_forward(pkt, 3); return 1; } /* Same as PACKET_get_net_3() but for a size_t */ __owur static ossl_inline int PACKET_get_net_3_len(PACKET *pkt, size_t *data) { unsigned long i; int ret = PACKET_get_net_3(pkt, &i); if (ret) *data = (size_t)i; return ret; } /* * Peek ahead at 4 bytes in network order from |pkt| and store the value in * |*data| */ __owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt, unsigned long *data) { if (PACKET_remaining(pkt) < 4) return 0; *data = ((unsigned long)(*pkt->curr)) << 24; *data |= ((unsigned long)(*(pkt->curr + 1))) << 16; *data |= ((unsigned long)(*(pkt->curr + 2))) << 8; *data |= *(pkt->curr + 3); return 1; } /* * Peek ahead at 8 bytes in network order from |pkt| and store the value in * |*data| */ __owur static ossl_inline int PACKET_peek_net_8(const PACKET *pkt, uint64_t *data) { if (PACKET_remaining(pkt) < 8) return 0; *data = ((uint64_t)(*pkt->curr)) << 56; *data |= ((uint64_t)(*(pkt->curr + 1))) << 48; *data |= ((uint64_t)(*(pkt->curr + 2))) << 40; *data |= ((uint64_t)(*(pkt->curr + 3))) << 32; *data |= ((uint64_t)(*(pkt->curr + 4))) << 24; *data |= ((uint64_t)(*(pkt->curr + 5))) << 16; *data |= ((uint64_t)(*(pkt->curr + 6))) << 8; *data |= *(pkt->curr + 7); return 1; } /* Equivalent of n2l */ /* Get 4 bytes in network order from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data) { if (!PACKET_peek_net_4(pkt, data)) return 0; packet_forward(pkt, 4); return 1; } /* Same as PACKET_get_net_4() but for a size_t */ __owur static ossl_inline int PACKET_get_net_4_len(PACKET *pkt, size_t *data) { unsigned long i; int ret = PACKET_get_net_4(pkt, &i); if (ret) *data = (size_t)i; return ret; } /* Get 8 bytes in network order from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_get_net_8(PACKET *pkt, uint64_t *data) { if (!PACKET_peek_net_8(pkt, data)) return 0; packet_forward(pkt, 8); return 1; } /* Peek ahead at 1 byte from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_peek_1(const PACKET *pkt, unsigned int *data) { if (!PACKET_remaining(pkt)) return 0; *data = *pkt->curr; return 1; } /* Get 1 byte from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_get_1(PACKET *pkt, unsigned int *data) { if (!PACKET_peek_1(pkt, data)) return 0; packet_forward(pkt, 1); return 1; } /* Same as PACKET_get_1() but for a size_t */ __owur static ossl_inline int PACKET_get_1_len(PACKET *pkt, size_t *data) { unsigned int i; int ret = PACKET_get_1(pkt, &i); if (ret) *data = (size_t)i; return ret; } /* * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value * in |*data| */ __owur static ossl_inline int PACKET_peek_4(const PACKET *pkt, unsigned long *data) { if (PACKET_remaining(pkt) < 4) return 0; *data = *pkt->curr; *data |= ((unsigned long)(*(pkt->curr + 1))) << 8; *data |= ((unsigned long)(*(pkt->curr + 2))) << 16; *data |= ((unsigned long)(*(pkt->curr + 3))) << 24; return 1; } /* Equivalent of c2l */ /* * Get 4 bytes in reverse network order from |pkt| and store the value in * |*data| */ __owur static ossl_inline int PACKET_get_4(PACKET *pkt, unsigned long *data) { if (!PACKET_peek_4(pkt, data)) return 0; packet_forward(pkt, 4); return 1; } /* * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in * |*data|. This just points at the underlying buffer that |pkt| is using. The * caller should not free this data directly (it will be freed when the * underlying buffer gets freed */ __owur static ossl_inline int PACKET_peek_bytes(const PACKET *pkt, const unsigned char **data, size_t len) { if (PACKET_remaining(pkt) < len) return 0; *data = pkt->curr; return 1; } /* * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This * just points at the underlying buffer that |pkt| is using. The caller should * not free this data directly (it will be freed when the underlying buffer gets * freed */ __owur static ossl_inline int PACKET_get_bytes(PACKET *pkt, const unsigned char **data, size_t len) { if (!PACKET_peek_bytes(pkt, data, len)) return 0; packet_forward(pkt, len); return 1; } /* Peek ahead at |len| bytes from |pkt| and copy them to |data| */ __owur static ossl_inline int PACKET_peek_copy_bytes(const PACKET *pkt, unsigned char *data, size_t len) { if (PACKET_remaining(pkt) < len) return 0; memcpy(data, pkt->curr, len); return 1; } /* * Read |len| bytes from |pkt| and copy them to |data|. * The caller is responsible for ensuring that |data| can hold |len| bytes. */ __owur static ossl_inline int PACKET_copy_bytes(PACKET *pkt, unsigned char *data, size_t len) { if (!PACKET_peek_copy_bytes(pkt, data, len)) return 0; packet_forward(pkt, len); return 1; } /* * Copy packet data to |dest|, and set |len| to the number of copied bytes. * If the packet has more than |dest_len| bytes, nothing is copied. * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise. * Does not forward PACKET position (because it is typically the last thing * done with a given PACKET). */ __owur static ossl_inline int PACKET_copy_all(const PACKET *pkt, unsigned char *dest, size_t dest_len, size_t *len) { if (PACKET_remaining(pkt) > dest_len) { *len = 0; return 0; } *len = pkt->remaining; memcpy(dest, pkt->curr, pkt->remaining); return 1; } /* * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the * result in |*data|, and the length in |len|. * If |*data| is not NULL, the old data is OPENSSL_free'd. * If the packet is empty, or malloc fails, |*data| will be set to NULL. * Returns 1 if the malloc succeeds and 0 otherwise. * Does not forward PACKET position (because it is typically the last thing * done with a given PACKET). */ __owur static ossl_inline int PACKET_memdup(const PACKET *pkt, unsigned char **data, size_t *len) { size_t length; OPENSSL_free(*data); *data = NULL; *len = 0; length = PACKET_remaining(pkt); if (length == 0) return 1; *data = OPENSSL_memdup(pkt->curr, length); if (*data == NULL) return 0; *len = length; return 1; } /* * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated * buffer. Store a pointer to the result in |*data|. * If |*data| is not NULL, the old data is OPENSSL_free'd. * If the data in |pkt| does not contain a NUL-byte, the entire data is * copied and NUL-terminated. * Returns 1 if the malloc succeeds and 0 otherwise. * Does not forward PACKET position (because it is typically the last thing done * with a given PACKET). */ __owur static ossl_inline int PACKET_strndup(const PACKET *pkt, char **data) { OPENSSL_free(*data); /* This will succeed on an empty packet, unless pkt->curr == NULL. */ *data = OPENSSL_strndup((const char *)pkt->curr, PACKET_remaining(pkt)); return (*data != NULL); } /* Returns 1 if |pkt| contains at least one 0-byte, 0 otherwise. */ static ossl_inline int PACKET_contains_zero_byte(const PACKET *pkt) { return memchr(pkt->curr, 0, pkt->remaining) != NULL; } /* Move the current reading position forward |len| bytes */ __owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len) { if (PACKET_remaining(pkt) < len) return 0; packet_forward(pkt, len); return 1; } /* * Reads a variable-length vector prefixed with a one-byte length, and stores * the contents in |subpkt|. |pkt| can equal |subpkt|. * Data is not copied: the |subpkt| packet will share its underlying buffer with * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. * Upon failure, the original |pkt| and |subpkt| are not modified. */ __owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt, PACKET *subpkt) { unsigned int length; const unsigned char *data; PACKET tmp = *pkt; if (!PACKET_get_1(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length)) { return 0; } *pkt = tmp; subpkt->curr = data; subpkt->remaining = length; return 1; } /* * Like PACKET_get_length_prefixed_1, but additionally, fails when there are * leftover bytes in |pkt|. */ __owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt, PACKET *subpkt) { unsigned int length; const unsigned char *data; PACKET tmp = *pkt; if (!PACKET_get_1(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length) || PACKET_remaining(&tmp) != 0) { return 0; } *pkt = tmp; subpkt->curr = data; subpkt->remaining = length; return 1; } /* * Reads a variable-length vector prefixed with a two-byte length, and stores * the contents in |subpkt|. |pkt| can equal |subpkt|. * Data is not copied: the |subpkt| packet will share its underlying buffer with * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. * Upon failure, the original |pkt| and |subpkt| are not modified. */ __owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt, PACKET *subpkt) { unsigned int length; const unsigned char *data; PACKET tmp = *pkt; if (!PACKET_get_net_2(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length)) { return 0; } *pkt = tmp; subpkt->curr = data; subpkt->remaining = length; return 1; } /* * Like PACKET_get_length_prefixed_2, but additionally, fails when there are * leftover bytes in |pkt|. */ __owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt, PACKET *subpkt) { unsigned int length; const unsigned char *data; PACKET tmp = *pkt; if (!PACKET_get_net_2(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length) || PACKET_remaining(&tmp) != 0) { return 0; } *pkt = tmp; subpkt->curr = data; subpkt->remaining = length; return 1; } /* * Reads a variable-length vector prefixed with a three-byte length, and stores * the contents in |subpkt|. |pkt| can equal |subpkt|. * Data is not copied: the |subpkt| packet will share its underlying buffer with * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. * Upon failure, the original |pkt| and |subpkt| are not modified. */ __owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt, PACKET *subpkt) { unsigned long length; const unsigned char *data; PACKET tmp = *pkt; if (!PACKET_get_net_3(&tmp, &length) || !PACKET_get_bytes(&tmp, &data, (size_t)length)) { return 0; } *pkt = tmp; subpkt->curr = data; subpkt->remaining = length; return 1; } /* Writeable packets */ typedef struct qat_wpacket_sub qat_WPACKET_SUB; struct qat_wpacket_sub { /* The parent WPACKET_SUB if we have one or NULL otherwise */ qat_WPACKET_SUB *parent; /* * Offset into the buffer where the length of this WPACKET goes. We use an * offset in case the buffer grows and gets reallocated. */ size_t packet_len; /* Number of bytes in the packet_len or 0 if we don't write the length */ size_t lenbytes; /* Number of bytes written to the buf prior to this packet starting */ size_t pwritten; /* Flags for this sub-packet */ unsigned int flags; }; typedef struct qat_wpacket_st qat_WPACKET; struct qat_wpacket_st { /* The buffer where we store the output data */ BUF_MEM *buf; /* Fixed sized buffer which can be used as an alternative to buf */ unsigned char *staticbuf; /* * Offset into the buffer where we are currently writing. We use an offset * in case the buffer grows and gets reallocated. */ size_t curr; /* Number of bytes written so far */ size_t written; /* Maximum number of bytes we will allow to be written to this WPACKET */ size_t maxsize; /* Our sub-packets (always at least one if not finished) */ qat_WPACKET_SUB *subs; /* Writing from the end first? */ unsigned int endfirst : 1; }; /* Flags */ /* Default */ #define QAT_WPACKET_FLAGS_NONE 0 /* Error on QAT_WPACKET_close() if no data written to the WPACKET */ #define QAT_WPACKET_FLAGS_NON_ZERO_LENGTH 1 /* * Abandon all changes on QAT_WPACKET_close() if no data written to the WPACKET, * i.e. this does not write out a zero packet length */ #define QAT_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH 2 int QAT_WPACKET_init_static_len(qat_WPACKET *pkt, unsigned char *buf, size_t len, size_t lenbytes); /* * Same as WPACKET_init_static_len except lenbytes is always 0, and we set the * WPACKET to write to the end of the buffer moving towards the start and use * QAT_DER length encoding for sub-packets. */ int QAT_WPACKET_close(qat_WPACKET *pkt); /* * The same as QAT_WPACKET_close() but only for the top most WPACKET. Additionally * frees memory resources for this WPACKET. */ int QAT_WPACKET_finish(qat_WPACKET *pkt); /* * Iterate through all the sub-packets and write out their lengths as if they * were being closed. The lengths will be overwritten with the final lengths * when the sub-packets are eventually closed (which may be different if more * data is added to the WPACKET). This function fails if a sub-packet is of 0 * length and QAT_WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH is set. */ int QAT_WPACKET_start_sub_packet_len__(qat_WPACKET *pkt, size_t lenbytes); /* * Same as QAT_WPACKET_start_sub_packet_len__() except no bytes are pre-allocated * for the sub-packet length. */ int QAT_WPACKET_allocate_bytes(qat_WPACKET *pkt, size_t len, unsigned char **allocbytes); /* * The same as QAT_WPACKET_allocate_bytes() except additionally a new sub-packet is * started for the allocated bytes, and then closed immediately afterwards. The * number of length bytes for the sub-packet is in |lenbytes|. Don't call this * directly. Use the convenience macros below instead. */ /* * The same as QAT_WPACKET_allocate_bytes() except the reserved bytes are not * actually counted as written. Typically this will be for when we don't know * how big arbitrary data is going to be up front, but we do know what the * maximum size will be. If this function is used, then it should be immediately * followed by a QAT_WPACKET_allocate_bytes() call before any other WPACKET * functions are called (unless the write to the allocated bytes is abandoned). * * For example: If we are generating a signature, then the size of that * signature may not be known in advance. We can use QAT_WPACKET_reserve_bytes() to * handle this: * * if (!WPACKET_sub_reserve_bytes_u16(&pkt, EVP_PKEY_get_size(pkey), &sigbytes1) * || EVP_SignFinal(md_ctx, sigbytes1, &siglen, pkey) <= 0 * || !WPACKET_sub_allocate_bytes_u16(&pkt, siglen, &sigbytes2) * || sigbytes1 != sigbytes2) * goto err; */ int QAT_WPACKET_reserve_bytes(qat_WPACKET *pkt, size_t len, unsigned char **allocbytes); /* * The "reserve_bytes" equivalent of WPACKET_sub_allocate_bytes__() */ /* * Write the value stored in |val| into the WPACKET. The value will consume * |bytes| amount of storage. An error will occur if |val| cannot be * accommodated in |bytes| storage, e.g. attempting to write the value 256 into * 1 byte will fail. Don't call this directly. Use the convenience macros below * instead. */ int QAT_WPACKET_put_bytes__(qat_WPACKET *pkt, uint64_t val, size_t bytes); /* * Convenience macros for calling WPACKET_put_bytes with different * lengths */ #define QAT_WPACKET_put_bytes_u8(pkt, val) \ QAT_WPACKET_put_bytes__((pkt), (val), 1) #define QAT_WPACKET_put_bytes_u16(pkt, val) \ QAT_WPACKET_put_bytes__((pkt), (val), 2) #define QAT_WPACKET_put_bytes_u24(pkt, val) \ QAT_WPACKET_put_bytes__((pkt), (val), 3) #define QAT_WPACKET_put_bytes_u32(pkt, val) \ QAT_WPACKET_put_bytes__((pkt), (val), 4) #define QAT_WPACKET_put_bytes_u64(pkt, val) \ QAT_WPACKET_put_bytes__((pkt), (val), 8) /* Copy |len| bytes of data from |*src| into the WPACKET. */ int QAT_WPACKET_memcpy(qat_WPACKET *pkt, const void *src, size_t len); /* * Copy |len| bytes of data from |*src| into the WPACKET and prefix with its * length (consuming |lenbytes| of data for the length). Don't call this * directly. Use the convenience macros below instead. */ int QAT_WPACKET_sub_memcpy__(qat_WPACKET *pkt, const void *src, size_t len, size_t lenbytes); /* Convenience macros for calling WPACKET_sub_memcpy with different lengths */ #define QAT_WPACKET_sub_memcpy_u8(pkt, src, len) \ QAT_WPACKET_sub_memcpy__((pkt), (src), (len), 1) #define QAT_WPACKET_sub_memcpy_u16(pkt, src, len) \ QAT_WPACKET_sub_memcpy__((pkt), (src), (len), 2) #define QAT_WPACKET_sub_memcpy_u24(pkt, src, len) \ QAT_WPACKET_sub_memcpy__((pkt), (src), (len), 3) #define QAT_WPACKET_sub_memcpy_u32(pkt, src, len) \ QAT_WPACKET_sub_memcpy__((pkt), (src), (len), 4) /* * Return the total number of bytes written so far to the underlying buffer * including any storage allocated for length bytes */ int QAT_WPACKET_get_total_written(qat_WPACKET *pkt, size_t *written); /* * Returns a pointer to the current write location, but does not allocate any * bytes. */ unsigned char *QAT_WPACKET_get_curr(qat_WPACKET *pkt); int WPACKET_is_null_buf(qat_WPACKET *pkt); /* Release resources in a WPACKET if a failure has occurred. */ void QAT_WPACKET_cleanup(qat_WPACKET *pkt); int QAT_WPACKET_init_der(qat_WPACKET *pkt, unsigned char *buf, size_t len); int QAT_WPACKET_set_flags(qat_WPACKET *pkt, unsigned int flags); int QAT_WPACKET_start_sub_packet(qat_WPACKET *pkt); int qat_int_end_context(qat_WPACKET *pkt, int tag); int qat_int_start_context(qat_WPACKET *pkt, int tag); int qat_DER_w_end_sequence(qat_WPACKET *pkt, int tag); int qat_DER_w_algorithmIdentifier_SM2_with_MD(qat_WPACKET *pkt, int cont, EC_KEY *ec, int mdnid); int qat_DER_w_algorithmIdentifier_ECDSA_with_MD(qat_WPACKET *pkt, int cont, EC_KEY *ec, int mdnid); qatengine-1.9.0/qat_prov_init.c000066400000000000000000000540311500416242000165130ustar00rootroot00000000000000/* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif #ifdef ENABLE_QAT_FIPS # include # include # include #endif #include #include #include "qat_provider.h" #include "e_qat.h" #include "qat_evp.h" #include "qat_fork.h" #include "qat_utils.h" #include "qat_prov_bio.h" #ifdef QAT_SW # include "qat_sw_polling.h" # include "crypto_mb/cpu_features.h" #endif #ifdef ENABLE_QAT_SW_GCM # include "qat_sw_gcm.h" #endif #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) # include "qat_sw_sha2.h" #endif #include "qat_fips.h" #include "qat_prov_cmvp.h" OSSL_PROVIDER *prov = NULL; #ifdef ENABLE_QAT_FIPS # define SM_KEY 0x00102F void *sm_ptr; int sm_id; #endif /* By default, qat provider always in a happy state */ int qat_prov_is_running(void) { return 1; } OSSL_LIB_CTX *prov_libctx_of(QAT_PROV_CTX *ctx) { if (ctx == NULL) return NULL; return ctx->libctx; } void qat_prov_ctx_set_core_bio_method(QAT_PROV_CTX *ctx, QAT_BIO_METHOD *corebiometh) { if (ctx != NULL) ctx->corebiometh = corebiometh; } #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) extern const OSSL_DISPATCH qat_rsa_keymgmt_functions[]; extern const OSSL_DISPATCH qat_rsa_signature_functions[]; #endif #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) extern const OSSL_DISPATCH qat_rsa_asym_cipher_functions[]; #endif #if defined(ENABLE_QAT_HW_ECDSA) || defined(ENABLE_QAT_SW_ECDSA) extern const OSSL_DISPATCH qat_ecdsa_keymgmt_functions[]; extern const OSSL_DISPATCH qat_ecdsa_signature_functions[]; #endif #if defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) extern const OSSL_DISPATCH qat_ecdh_keymgmt_functions[]; extern const OSSL_DISPATCH qat_ecdh_keyexch_functions[]; #endif #if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) extern const OSSL_DISPATCH qat_X25519_keyexch_functions[]; extern const OSSL_DISPATCH qat_X25519_keymgmt_functions[]; #endif #ifdef ENABLE_QAT_HW_ECX extern const OSSL_DISPATCH qat_X448_keyexch_functions[]; extern const OSSL_DISPATCH qat_X448_keymgmt_functions[]; #endif #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) extern const OSSL_DISPATCH qat_aes128gcm_functions[]; # ifdef ENABLE_QAT_SW_GCM extern const OSSL_DISPATCH qat_aes192gcm_functions[]; # endif extern const OSSL_DISPATCH qat_aes256gcm_functions[]; #endif #ifdef ENABLE_QAT_HW_CCM extern const OSSL_DISPATCH qat_aes128ccm_functions[]; extern const OSSL_DISPATCH qat_aes192ccm_functions[]; extern const OSSL_DISPATCH qat_aes256ccm_functions[]; #endif #if defined(ENABLE_QAT_HW_DSA) && defined(QAT_INSECURE_ALGO) extern const OSSL_DISPATCH qat_dsa_keymgmt_functions[]; extern const OSSL_DISPATCH qat_dsa_signature_functions[]; #endif #if defined(ENABLE_QAT_HW_DH) && defined(QAT_INSECURE_ALGO) extern const OSSL_DISPATCH qat_dh_keymgmt_functions[]; extern const OSSL_DISPATCH qat_dh_keyexch_functions[]; #endif #ifdef ENABLE_QAT_HW_CIPHERS # ifdef QAT_INSECURE_ALGO extern const OSSL_DISPATCH qat_aes128cbc_hmac_sha1_functions[]; extern const OSSL_DISPATCH qat_aes256cbc_hmac_sha1_functions[]; # endif extern const OSSL_DISPATCH qat_aes128cbc_hmac_sha256_functions[]; extern const OSSL_DISPATCH qat_aes256cbc_hmac_sha256_functions[]; #endif /* ENABLE_QAT_HW_CIPHERS */ #ifdef ENABLE_QAT_HW_CHACHAPOLY extern const OSSL_DISPATCH qat_chacha20_poly1305_functions[]; #endif /* ENABLE_QAT_HW_CHACHAPOLY */ #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) # ifdef QAT_INSECURE_ALGO extern const OSSL_DISPATCH qat_sha224_functions[]; # endif /* QAT_INSECURE_ALGO */ extern const OSSL_DISPATCH qat_sha256_functions[]; extern const OSSL_DISPATCH qat_sha384_functions[]; extern const OSSL_DISPATCH qat_sha512_functions[]; #endif #ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO extern const OSSL_DISPATCH qat_sha3_224_functions[]; # endif extern const OSSL_DISPATCH qat_sha3_256_functions[]; extern const OSSL_DISPATCH qat_sha3_384_functions[]; extern const OSSL_DISPATCH qat_sha3_512_functions[]; #endif /* ENABLE_QAT_HW_SHA3 */ #if defined(ENABLE_QAT_HW_SM3) || defined (ENABLE_QAT_SW_SM3) extern const OSSL_DISPATCH qat_sm3_functions[]; #endif #ifdef ENABLE_QAT_HW_HKDF extern const OSSL_DISPATCH qat_kdf_hkdf_functions[]; extern const OSSL_DISPATCH qat_kdf_tls1_3_functions[]; #endif #ifdef ENABLE_QAT_HW_PRF extern const OSSL_DISPATCH qat_tls_prf_functions[]; #endif # if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) extern const OSSL_DISPATCH qat_sm2_signature_functions[]; extern const OSSL_DISPATCH qat_sm2_keymgmt_functions[]; #endif #ifdef ENABLE_QAT_SW_SM4_GCM extern const OSSL_DISPATCH qat_sm4_gcm_functions[]; #endif #ifdef ENABLE_QAT_SW_SM4_CCM extern const OSSL_DISPATCH qat_sm4_ccm_functions[]; # endif #if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) extern const OSSL_DISPATCH qat_sm4_cbc_functions[]; # endif QAT_PROV_PARAMS qat_params; static void qat_teardown(void *provctx) { DEBUG("qatprovider teardown\n"); qat_free_ciphers(); qat_free_digest_meth(); qat_engine_finish_int(NULL, QAT_RESET_GLOBALS); ERR_unload_QAT_strings(); #if defined(ENABLE_QAT_FIPS) && defined (ENABLE_QAT_SW_SHA2) sha_free_ipsec_mb_mgr(); #endif #ifdef ENABLE_QAT_FIPS shmctl(sm_id, IPC_RMID, 0); #endif if (provctx) { QAT_PROV_CTX *qat_ctx = (QAT_PROV_CTX *)provctx; BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(qat_ctx)); OPENSSL_free(qat_ctx); OSSL_PROVIDER_unload(prov); } } /* Parameters we provide to the core */ static const OSSL_PARAM qat_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END}; static const OSSL_PARAM *qat_gettable_params(void *provctx) { return qat_param_types; } static int qat_get_params(void *provctx, OSSL_PARAM params[]) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, QAT_PROVIDER_NAME_STR)) return 0; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, QAT_PROVIDER_VERSION_STR)) return 0; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, QAT_PROVIDER_FULL_VERSION_STR)) return 0; p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); if (p != NULL && !OSSL_PARAM_set_int(p, 1)) return 0; return 1; } static const OSSL_ALGORITHM_CAPABLE qat_deflt_ciphers[] = { #if defined(ENABLE_QAT_HW_GCM) || defined(ENABLE_QAT_SW_GCM) ALG(QAT_NAMES_AES_128_GCM, qat_aes128gcm_functions), ALG(QAT_NAMES_AES_256_GCM, qat_aes256gcm_functions), #endif #ifdef ENABLE_QAT_SW_GCM ALG(QAT_NAMES_AES_192_GCM, qat_aes192gcm_functions), #endif #ifdef ENABLE_QAT_HW_CCM ALG(QAT_NAMES_AES_128_CCM, qat_aes128ccm_functions), ALG(QAT_NAMES_AES_192_CCM, qat_aes192ccm_functions), ALG(QAT_NAMES_AES_256_CCM, qat_aes256ccm_functions), #endif #if defined(ENABLE_QAT_HW_CIPHERS) && !defined(ENABLE_QAT_FIPS) # ifdef QAT_INSECURE_ALGO ALG(QAT_NAMES_AES_128_CBC_HMAC_SHA1, qat_aes128cbc_hmac_sha1_functions), ALG(QAT_NAMES_AES_256_CBC_HMAC_SHA1, qat_aes256cbc_hmac_sha1_functions), # endif ALG(QAT_NAMES_AES_128_CBC_HMAC_SHA256, qat_aes128cbc_hmac_sha256_functions), ALG(QAT_NAMES_AES_256_CBC_HMAC_SHA256, qat_aes256cbc_hmac_sha256_functions), #endif # ifdef ENABLE_QAT_HW_CHACHAPOLY ALG(QAT_NAMES_CHACHA20_POLY1305, qat_chacha20_poly1305_functions), # endif /* ENABLE_QAT_HW_CHACHAPOLY */ # ifdef ENABLE_QAT_SW_SM4_GCM ALG(QAT_NAMES_SM4_GCM, qat_sm4_gcm_functions), # endif # ifdef ENABLE_QAT_SW_SM4_CCM ALG(QAT_NAMES_SM4_CCM, qat_sm4_ccm_functions), # endif #if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) ALG(QAT_NAMES_SM4_CBC, qat_sm4_cbc_functions), # endif { { NULL, NULL, NULL }, NULL }}; static OSSL_ALGORITHM qat_exported_ciphers[OSSL_NELEM(qat_deflt_ciphers)]; static const OSSL_ALGORITHM qat_keyexch[] = { #if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) {"X25519", QAT_DEFAULT_PROPERTIES, qat_X25519_keyexch_functions, "QAT X25519 keyexch implementation."}, #endif #if defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) {"ECDH", QAT_DEFAULT_PROPERTIES, qat_ecdh_keyexch_functions, "QAT ECDH keyexch implementation."}, # if !defined(ENABLE_QAT_FIPS) # if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) # if defined(TONGSUO_VERSION_NUMBER) {"SM2DH", QAT_DEFAULT_PROPERTIES, qat_ecdh_keyexch_functions, "QAT SM2 keyexch implementation."}, # else {"SM2", QAT_DEFAULT_PROPERTIES, qat_ecdh_keyexch_functions, "QAT SM2 keyexch implementation."}, # endif # endif # endif #endif #if defined(ENABLE_QAT_HW_DH) && defined(QAT_INSECURE_ALGO) {"DH", QAT_DEFAULT_PROPERTIES, qat_dh_keyexch_functions, "QAT DH keyexch implementation"}, #endif #ifdef ENABLE_QAT_HW_ECX {"X448", QAT_DEFAULT_PROPERTIES, qat_X448_keyexch_functions, "QAT X448 keyexch implementation."}, #endif {NULL, NULL, NULL}}; static const OSSL_ALGORITHM qat_keymgmt[] = { #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) {"RSA", QAT_DEFAULT_PROPERTIES, qat_rsa_keymgmt_functions, "QAT RSA Keymgmt implementation."}, #endif #if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) {"X25519", QAT_DEFAULT_PROPERTIES, qat_X25519_keymgmt_functions, "QAT X25519 Keymgmt implementation."}, #endif #if defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) {"EC", QAT_DEFAULT_PROPERTIES, qat_ecdh_keymgmt_functions, "QAT EC Keymgmt implementation."}, #endif #if defined(ENABLE_QAT_HW_DSA) && defined(QAT_INSECURE_ALGO) {"DSA", QAT_DEFAULT_PROPERTIES, qat_dsa_keymgmt_functions, "QAT DSA Keymgmt implementation."}, # endif #if defined(ENABLE_QAT_HW_DH) && defined(QAT_INSECURE_ALGO) {"DH", QAT_DEFAULT_PROPERTIES, qat_dh_keymgmt_functions, "QAT DH Keymgmt implementation"}, #endif #ifdef ENABLE_QAT_HW_ECX {"X448", QAT_DEFAULT_PROPERTIES, qat_X448_keymgmt_functions, "QAT X448 Keymgmt implementation."}, #endif #if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) {"SM2", QAT_DEFAULT_PROPERTIES, qat_sm2_keymgmt_functions, "QAT SM2 Keymgmt implementation."}, #endif {NULL, NULL, NULL}}; static const OSSL_ALGORITHM qat_signature[] = { #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) {"RSA", QAT_DEFAULT_PROPERTIES, qat_rsa_signature_functions, "QAT RSA Signature implementation."}, #endif #if defined(ENABLE_QAT_HW_ECDSA) || defined(ENABLE_QAT_SW_ECDSA) {"ECDSA", QAT_DEFAULT_PROPERTIES, qat_ecdsa_signature_functions, "QAT ECDSA Signature implementation."}, #endif #if defined(ENABLE_QAT_HW_DSA) && defined(QAT_INSECURE_ALGO) {"DSA", QAT_DEFAULT_PROPERTIES, qat_dsa_signature_functions, "QAT DSA Signature implementation."}, #endif # if !defined(ENABLE_QAT_FIPS) # if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) {"SM2", QAT_DEFAULT_PROPERTIES, qat_sm2_signature_functions, "QAT SM2 Signature implementation."}, # endif # endif {NULL, NULL, NULL}}; #if defined(ENABLE_QAT_HW_HKDF) || defined(ENABLE_QAT_HW_PRF) static const OSSL_ALGORITHM qat_kdfs[] = { # ifdef ENABLE_QAT_HW_HKDF {"HKDF", QAT_DEFAULT_PROPERTIES, qat_kdf_hkdf_functions, "QAT HKDF implementation"}, {"TLS13-KDF", QAT_DEFAULT_PROPERTIES, qat_kdf_tls1_3_functions, "QAT HKDF implementation"}, # endif # ifdef ENABLE_QAT_HW_PRF {"TLS1-PRF", QAT_DEFAULT_PROPERTIES, qat_tls_prf_functions, "QAT PRF implementation"}, # endif {NULL, NULL, NULL}}; #endif #if defined(ENABLE_QAT_HW_SHA3) || defined(ENABLE_QAT_SW_SHA2) || defined(ENABLE_QAT_HW_SM3) || defined(ENABLE_QAT_SW_SM3) static const OSSL_ALGORITHM qat_digests[] = { #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) # ifdef QAT_INSECURE_ALGO { QAT_NAMES_SHA2_224, QAT_DEFAULT_PROPERTIES, qat_sha224_functions }, # endif { QAT_NAMES_SHA2_256, QAT_DEFAULT_PROPERTIES, qat_sha256_functions }, { QAT_NAMES_SHA2_384, QAT_DEFAULT_PROPERTIES, qat_sha384_functions }, { QAT_NAMES_SHA2_512, QAT_DEFAULT_PROPERTIES, qat_sha512_functions }, #endif #ifdef ENABLE_QAT_HW_SHA3 # ifdef QAT_INSECURE_ALGO { QAT_NAMES_SHA3_224, QAT_DEFAULT_PROPERTIES, qat_sha3_224_functions }, # endif { QAT_NAMES_SHA3_256, QAT_DEFAULT_PROPERTIES, qat_sha3_256_functions }, { QAT_NAMES_SHA3_384, QAT_DEFAULT_PROPERTIES, qat_sha3_384_functions }, { QAT_NAMES_SHA3_512, QAT_DEFAULT_PROPERTIES, qat_sha3_512_functions }, #endif # if defined(ENABLE_QAT_HW_SM3) || defined (ENABLE_QAT_SW_SM3) { QAT_NAMES_SM3, QAT_DEFAULT_PROPERTIES, qat_sm3_functions }, # endif { NULL, NULL, NULL }}; #endif #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) static const OSSL_ALGORITHM qat_asym_cipher[] = { { "RSA", QAT_DEFAULT_PROPERTIES, qat_rsa_asym_cipher_functions }, { NULL, NULL, NULL } }; #endif #ifdef ENABLE_QAT_FIPS int qat_operations(int operation_id) { switch (operation_id) { case OSSL_OP_DIGEST: case OSSL_OP_CIPHER: case OSSL_OP_SIGNATURE: case OSSL_OP_KEYMGMT: case OSSL_OP_KEYEXCH: case OSSL_OP_KDF: return 1; default: return 0; } } #endif static const OSSL_ALGORITHM *qat_query(void *provctx, int operation_id, int *no_cache) { static int prov_init = 0; prov = OSSL_PROVIDER_load(NULL, "default"); #ifdef ENABLE_QAT_FIPS /* * By using this variable can set FIPs on-demand test internally * 1 - ondemand test set * 0 - ondemand test unset */ int ondemand = 0; static int self_test_init = 0; static int count = 1; sm_id = shmget((key_t)SM_KEY, 16, 0666); sm_ptr = shmat(sm_id, NULL, 0); static pid_t init_pid = 0; if (prov_init == 2 && self_test_init == 0) { prov_init++; self_test_init++; if (!strcmp((char *)sm_ptr, "KAT_RSET")) { strcpy(sm_ptr, "KAT_DONE"); init_pid = getpid(); if (qat_hw_offload && qat_sw_offload) qat_fips_self_test(provctx, ondemand, 1); else qat_fips_self_test(provctx, ondemand, 0); } } if (prov_init == 1 && self_test_init == 0) { prov_init++; if (operation_id != OSSL_OP_RAND) { prov_init++; self_test_init++; if (!strcmp((char *)sm_ptr, "KAT_RSET")) { strcpy(sm_ptr, "KAT_DONE"); init_pid = getpid(); if (qat_hw_offload && qat_sw_offload) qat_fips_self_test(provctx, ondemand, 1); else qat_fips_self_test(provctx, ondemand, 0); } } } #endif if (!prov_init) { prov_init = 1; /* qat provider takes the highest priority * and overwrite the openssl.cnf property. */ EVP_set_default_properties(NULL, "?provider=qatprovider"); #ifdef ENABLE_QAT_FIPS if (qat_operations(operation_id)) { prov_init++; self_test_init++; if (!strcmp((char *)sm_ptr, "KAT_RSET")) { strcpy(sm_ptr, "KAT_DONE"); init_pid = getpid(); if (qat_hw_offload && qat_sw_offload) qat_fips_self_test(provctx, ondemand, 1); else qat_fips_self_test(provctx, ondemand, 0); } } #endif } *no_cache = 0; #ifdef ENABLE_QAT_FIPS while (count && sm_ptr != NULL) { if (strcmp((char *)sm_ptr, "KAT_DONE") != 0 || init_pid == getpid()) { count = 1; break; } count++; } if (integrity_status && strcmp((char *)sm_ptr, "KAT_FAIL") != 0) { #endif switch (operation_id) { #if defined(ENABLE_QAT_HW_SHA3) || defined(ENABLE_QAT_SW_SHA2) || defined(ENABLE_QAT_HW_SM3) || defined(ENABLE_QAT_SW_SM3) case OSSL_OP_DIGEST: return qat_digests; #endif case OSSL_OP_CIPHER: return qat_exported_ciphers; case OSSL_OP_SIGNATURE: return qat_signature; case OSSL_OP_KEYMGMT: return qat_keymgmt; case OSSL_OP_KEYEXCH: return qat_keyexch; #if defined(ENABLE_QAT_HW_HKDF) || defined(ENABLE_QAT_HW_PRF) case OSSL_OP_KDF: return qat_kdfs; #endif #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) case OSSL_OP_ASYM_CIPHER: return qat_asym_cipher; #endif } return OSSL_PROVIDER_query_operation(prov, operation_id, no_cache); #ifdef ENABLE_QAT_FIPS } else { qat_teardown(provctx); exit(EXIT_FAILURE); } #endif } static const OSSL_DISPATCH qat_dispatch_table[] = { {OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))qat_teardown}, {OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))qat_gettable_params}, {OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))qat_get_params}, {OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))qat_query}, { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))qat_prov_get_capabilities}, {0, NULL}}; /* Functions provided by the core */ static OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL; static OSSL_FUNC_core_get_params_fn *c_get_params = NULL; static OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; int qat_get_params_from_core(const OSSL_CORE_HANDLE *handle) { OSSL_PARAM core_params[10], *p = core_params; *p++ = OSSL_PARAM_construct_utf8_ptr( "enable_external_polling", (char **)&qat_params.enable_external_polling, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "enable_heuristic_polling", (char **)&qat_params.enable_heuristic_polling, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "enable_sw_fallback", (char **)&qat_params.enable_sw_fallback, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "enable_inline_polling", (char **)&qat_params.enable_inline_polling, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "qat_poll_interval", (char **)&qat_params.qat_poll_interval, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "qat_epoll_timeout", (char **)&qat_params.qat_epoll_timeout, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "enable_event_driven_polling", (char **)&qat_params.enable_event_driven_polling, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "enable_instance_for_thread", (char **)&qat_params.enable_instance_for_thread, 0); *p++ = OSSL_PARAM_construct_utf8_ptr( "qat_max_retry_count", (char **)&qat_params.qat_max_retry_count, 0); *p = OSSL_PARAM_construct_end(); if (!c_get_params(handle, core_params)) { WARN("QAT get parameters from core is failed.\n"); return 0; } if (qat_params.enable_external_polling == NULL) { DEBUG("get_params is NULL. Using the default params\n"); return 1; } enable_external_polling = atoi(qat_params.enable_external_polling); enable_heuristic_polling = atoi(qat_params.enable_heuristic_polling); #ifdef QAT_HW enable_sw_fallback = atoi(qat_params.enable_sw_fallback); enable_inline_polling = atoi(qat_params.enable_inline_polling); qat_poll_interval = atoi(qat_params.qat_poll_interval); qat_epoll_timeout = atoi(qat_params.qat_epoll_timeout); enable_event_driven_polling = atoi(qat_params.enable_event_driven_polling); enable_instance_for_thread = atoi(qat_params.enable_instance_for_thread); qat_max_retry_count = atoi(qat_params.qat_max_retry_count); #endif return 1; } void qat_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in, OSSL_ALGORITHM *out) { int i, j; if (out[0].algorithm_names == NULL) { for (i = j = 0; in[i].alg.algorithm_names != NULL; ++i) { if (in[i].capable == NULL || in[i].capable()) out[j++] = in[i].alg; } out[j++] = in[i].alg; } } int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, void **provctx) { QAT_PROV_CTX *qat_ctx = NULL; BIO_METHOD *corebiometh = NULL; QAT_DEBUG_LOG_INIT(); if (!ossl_prov_bio_from_dispatch(in)) return 0; for (; in->function_id != 0; in++) { switch (in->function_id) { case OSSL_FUNC_CORE_GETTABLE_PARAMS: c_gettable_params = OSSL_FUNC_core_gettable_params(in); break; case OSSL_FUNC_CORE_GET_PARAMS: c_get_params = OSSL_FUNC_core_get_params(in); break; case OSSL_FUNC_CORE_GET_LIBCTX: c_get_libctx = OSSL_FUNC_core_get_libctx(in); break; default: /* Just ignore anything we don't understand */ break; } } #ifdef ENABLE_QAT_FIPS /*displaying module_name, ID & version of FIPs module*/ if(qat_provider_info()) { goto err; } #endif /* get parameters from qat_provider.cnf */ if (!qat_get_params_from_core(handle)) { return 0; } if (!bind_qat(NULL, NULL) || !qat_engine_init(NULL)) { goto err; } qat_ctx = OPENSSL_zalloc(sizeof(QAT_PROV_CTX)); if (qat_ctx == NULL) { goto err; } qat_ctx->handle = handle; #ifndef ENABLE_QAT_FIPS qat_ctx->libctx = (OSSL_LIB_CTX *)c_get_libctx(handle); #else qat_ctx->libctx = (OSSL_LIB_CTX *)OSSL_LIB_CTX_new_from_dispatch(handle, in); #endif *provctx = (void *)qat_ctx; corebiometh = ossl_bio_prov_init_bio_method(); qat_prov_ctx_set_core_bio_method(*provctx, corebiometh); *out = qat_dispatch_table; qat_prov_cache_exported_algorithms(qat_deflt_ciphers, qat_exported_ciphers); #ifdef ENABLE_QAT_FIPS sm_id = shmget((key_t)SM_KEY, 16, IPC_CREAT|0666); sm_ptr = shmat(sm_id, NULL, 0); strcpy(sm_ptr, "KAT_RSET"); #endif return 1; err: WARN("QAT provider init failed\n"); qat_teardown(qat_ctx); return 0; } qatengine-1.9.0/qat_prov_kmgmt_dh.c000066400000000000000000000317361500416242000173510ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_kmgmt_dh.c * * This file contains the Qat Provider DH Key Management implementation * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_dh.h" #include "qat_utils.h" #include "qat_evp.h" #include "e_qat.h" #include "qat_prov_cmvp.h" #ifdef ENABLE_QAT_HW_DH typedef struct { int id; /* libcrypto internal */ int name_id; # if OPENSSL_VERSION_NUMBER >= 0x30300000 /* NID for the legacy alg if there is one */ int legacy_alg; # endif char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif /* Constructor(s), destructor, information */ OSSL_FUNC_keymgmt_new_fn *new; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; OSSL_FUNC_keymgmt_set_params_fn *set_params; OSSL_FUNC_keymgmt_settable_params_fn *settable_params; /* Generation, a complex constructor */ OSSL_FUNC_keymgmt_gen_init_fn *gen_init; OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; # if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_keymgmt_gen_get_params_fn *gen_get_params; OSSL_FUNC_keymgmt_gen_gettable_params_fn *gen_gettable_params; # endif OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; OSSL_FUNC_keymgmt_gen_fn *gen; OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; OSSL_FUNC_keymgmt_load_fn *load; /* Key object checking */ OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; OSSL_FUNC_keymgmt_has_fn *has; OSSL_FUNC_keymgmt_validate_fn *validate; OSSL_FUNC_keymgmt_match_fn *match; /* Import and export routines */ OSSL_FUNC_keymgmt_import_fn *import; OSSL_FUNC_keymgmt_import_types_fn *import_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; # endif OSSL_FUNC_keymgmt_export_fn *export; OSSL_FUNC_keymgmt_export_types_fn *export_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; # endif OSSL_FUNC_keymgmt_dup_fn *dup; } QAT_DH_KEYMGMT; static OSSL_FUNC_keymgmt_new_fn qat_dh_newdata; static OSSL_FUNC_keymgmt_free_fn qat_dh_freedata; static OSSL_FUNC_keymgmt_gen_init_fn qat_dh_gen_init; static OSSL_FUNC_keymgmt_gen_set_template_fn qat_dh_gen_set_template; static OSSL_FUNC_keymgmt_gen_set_params_fn qat_dh_gen_set_params; static OSSL_FUNC_keymgmt_gen_settable_params_fn qat_dh_gen_settable_params; static OSSL_FUNC_keymgmt_gen_fn qat_dh_gen; static OSSL_FUNC_keymgmt_gen_cleanup_fn qat_dh_gen_cleanup; static OSSL_FUNC_keymgmt_load_fn qat_dh_load; static OSSL_FUNC_keymgmt_get_params_fn qat_dh_get_params; static OSSL_FUNC_keymgmt_gettable_params_fn qat_dh_gettable_params; static OSSL_FUNC_keymgmt_set_params_fn qat_dh_set_params; static OSSL_FUNC_keymgmt_settable_params_fn qat_dh_settable_params; static OSSL_FUNC_keymgmt_has_fn qat_dh_has; static OSSL_FUNC_keymgmt_match_fn qat_dh_match; static OSSL_FUNC_keymgmt_validate_fn qat_dh_validate; static OSSL_FUNC_keymgmt_import_fn qat_dh_import; static OSSL_FUNC_keymgmt_import_types_fn qat_dh_import_types; static OSSL_FUNC_keymgmt_export_fn qat_dh_export; static OSSL_FUNC_keymgmt_export_types_fn qat_dh_export_types; static OSSL_FUNC_keymgmt_dup_fn qat_dh_dup; static QAT_DH_KEYMGMT get_default_keymgmt() { static QAT_DH_KEYMGMT s_keymgmt; static int initilazed = 0; if (!initilazed) { QAT_DH_KEYMGMT *keymgmt = (QAT_DH_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "DH", "provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initilazed = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } static void *qat_dh_newdata(void *provctx) { typedef void *(*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().new; if (!fun) return NULL; return fun(provctx); } static void qat_dh_freedata(void *keydata) { #ifdef ENABLE_QAT_FIPS qat_DH_free(keydata); #else typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().free; if (!fun) return; fun(keydata); #endif } static int qat_dh_has(const void *keydata, int selection) { typedef int (*fun_ptr)(const void *, int); fun_ptr fun = get_default_keymgmt().has; if (!fun) return 0; return fun(keydata, selection); } static int qat_dh_match(const void *keydata1, const void *keydata2, int selection) { typedef int (*fun_ptr)(const void *, const void *, int); fun_ptr fun = get_default_keymgmt().match; if (!fun) return 0; return fun(keydata1, keydata2, selection); } static int qat_dh_import(void *keydata, int selection, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().import; if (!fun) return 0; return fun(keydata, selection, params); } static int qat_dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg) { typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); fun_ptr fun = get_default_keymgmt().export; if (!fun) return 0; return fun(keydata, selection, param_cb, cbarg); } static const OSSL_PARAM *qat_dh_import_types(int selection) { typedef const OSSL_PARAM *(*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().import_types; if (!fun) return NULL; return fun(selection); } static const OSSL_PARAM *qat_dh_export_types(int selection) { typedef const OSSL_PARAM *(*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().export_types; if (!fun) return NULL; return fun(selection); } static ossl_inline int qat_dh_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_dh_gettable_params(void *provctx) { typedef const OSSL_PARAM *(*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static const OSSL_PARAM *qat_dh_settable_params(void *provctx) { typedef const OSSL_PARAM *(*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().settable_params; if (!fun) return NULL; return fun(provctx); } static int qat_dh_set_params(void *key, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().set_params; if (!fun) return 0; return fun(key, params); } static int qat_dh_validate(const void *keydata, int selection, int checktype) { typedef int (*fun_ptr)(const void *, int, int); fun_ptr fun = get_default_keymgmt().validate; if (!fun) return 0; return fun(keydata, selection, checktype); } static void *qat_dh_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { typedef void *(*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_init; if (!fun) return NULL; return fun(provctx, selection, params); } static int qat_dh_gen_set_template(void *genctx, void *templ) { typedef int (*fun_ptr)(void *, void *); fun_ptr fun = get_default_keymgmt().gen_set_template; if (!fun) return 0; return fun(genctx, templ); } static const OSSL_PARAM *qat_dh_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { typedef const OSSL_PARAM *(*fun_ptr)(void *, void *); fun_ptr fun = get_default_keymgmt().gen_settable_params; if (!fun) return NULL; return fun(genctx, provctx); } static int qat_dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_set_params; if (!fun) return 0; return fun(genctx, params); } static void *qat_dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { typedef void* (*fun_ptr)(void *, OSSL_CALLBACK *, void *); fun_ptr fun = get_default_keymgmt().gen; if (!fun) return NULL; return fun(genctx,osslcb,cbarg); } static void qat_dh_gen_cleanup(void *genctx) { typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gen_cleanup; if (!fun) return; fun(genctx); } static void *qat_dh_load(const void *reference, size_t reference_sz) { typedef void *(*fun_ptr)(const void *, size_t); fun_ptr fun = get_default_keymgmt().load; if (!fun) return NULL; return fun(reference, reference_sz); } static void *qat_dh_dup(const void *keydata_from, int selection) { typedef void *(*fun_ptr)(const void *, int); fun_ptr fun = get_default_keymgmt().dup; if (!fun) return NULL; return fun(keydata_from, selection); } # if OPENSSL_VERSION_NUMBER >= 0x30400000 static const char *qat_dh_query_operation_name(int operation_id) { return "DH"; } # endif const OSSL_DISPATCH qat_dh_keymgmt_functions[] = { {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_dh_newdata}, {OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_dh_gen_init}, {OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))qat_dh_gen_set_template}, {OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_dh_gen_set_params}, {OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_dh_gen_settable_params}, {OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_dh_gen}, {OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))qat_dh_gen_cleanup}, {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))qat_dh_load}, {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_dh_freedata}, {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))qat_dh_get_params}, {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))qat_dh_gettable_params}, {OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))qat_dh_set_params}, {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))qat_dh_settable_params}, {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_dh_has}, {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_dh_match}, {OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))qat_dh_validate}, {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_dh_import}, {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_dh_import_types}, {OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_dh_export}, {OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_dh_export_types}, # if OPENSSL_VERSION_NUMBER >= 0x30400000 { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))qat_dh_query_operation_name }, # endif {OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_dh_dup}, {0, NULL}}; #endif qatengine-1.9.0/qat_prov_kmgmt_dsa.c000066400000000000000000000260761500416242000175260ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_kmgmt_dsa.c * * This file contains the Qat Provider DSA Key Management implementation * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_dsa.h" #include "qat_utils.h" #include "qat_evp.h" #include "e_qat.h" #include "qat_prov_cmvp.h" #ifdef QAT_HW #include "qat_hw_dsa.h" #endif #ifdef ENABLE_QAT_HW_DSA typedef struct { int id; /* libcrypto internal */ int name_id; # if OPENSSL_VERSION_NUMBER >= 0x30300000 /* NID for the legacy alg if there is one */ int legacy_alg; # endif char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif /* Constructor(s), destructor, information */ OSSL_FUNC_keymgmt_new_fn *new; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; OSSL_FUNC_keymgmt_set_params_fn *set_params; OSSL_FUNC_keymgmt_settable_params_fn *settable_params; /* Generation, a complex constructor */ OSSL_FUNC_keymgmt_gen_init_fn *gen_init; OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; # if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_keymgmt_gen_get_params_fn *gen_get_params; OSSL_FUNC_keymgmt_gen_gettable_params_fn *gen_gettable_params; # endif OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; OSSL_FUNC_keymgmt_gen_fn *gen; OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; OSSL_FUNC_keymgmt_load_fn *load; /* Key object checking */ OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; OSSL_FUNC_keymgmt_has_fn *has; OSSL_FUNC_keymgmt_validate_fn *validate; OSSL_FUNC_keymgmt_match_fn *match; /* Import and export routines */ OSSL_FUNC_keymgmt_import_fn *import; OSSL_FUNC_keymgmt_import_types_fn *import_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; # endif OSSL_FUNC_keymgmt_export_fn *export; OSSL_FUNC_keymgmt_export_types_fn *export_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; # endif OSSL_FUNC_keymgmt_dup_fn *dup; } QAT_DSA_KEYMGMT; static QAT_DSA_KEYMGMT get_default_keymgmt() { static QAT_DSA_KEYMGMT s_keymgmt; static int initilazed = 0; if (!initilazed) { QAT_DSA_KEYMGMT *keymgmt = (QAT_DSA_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "DSA", "provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initilazed = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } static void *qat_dsa_newdata(void *provctx) { typedef void *(*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().new; if (!fun) return NULL; return fun(provctx); } static void qat_dsa_freedata(void *keydata) { #ifdef ENABLE_QAT_FIPS qat_DSA_free(keydata); #else typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().free; if (!fun) return; fun(keydata); #endif } static int qat_dsa_has(const void *keydata, int selection) { typedef int (*fun_ptr)(const void *, int); fun_ptr fun = get_default_keymgmt().has; if (!fun) return 0; return fun(keydata, selection); } static int qat_dsa_match(const void *keydata1, const void *keydata2, int selection) { typedef int (*fun_ptr)(const void *, const void *, int); fun_ptr fun = get_default_keymgmt().match; if (!fun) return 0; return fun(keydata1, keydata2, selection); } static int qat_dsa_import(void *keydata, int selection, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().import; if (!fun) return 0; return fun(keydata, selection, params); } static int qat_dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg) { typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); fun_ptr fun = get_default_keymgmt().export; if (!fun) return 0; return fun(keydata, selection, param_cb, cbarg); } static const OSSL_PARAM *qat_dsa_import_types(int selection) { typedef const OSSL_PARAM *(*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().import_types; if (!fun) return NULL; return fun(selection); } static const OSSL_PARAM *qat_dsa_export_types(int selection) { typedef const OSSL_PARAM *(*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().export_types; if (!fun) return NULL; return fun(selection); } static ossl_inline int qat_dsa_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_dsa_gettable_params(void *provctx) { typedef const OSSL_PARAM *(*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static int qat_dsa_validate(const void *keydata, int selection, int checktype) { typedef int (*fun_ptr)(const void *, int, int); fun_ptr fun = get_default_keymgmt().validate; if (!fun) return 0; return fun(keydata, selection, checktype); } static void *qat_dsa_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { typedef void *(*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_init; if (!fun) return NULL; return fun(provctx, selection, params); } static int qat_dsa_gen_set_template(void *genctx, void *templ) { typedef int (*fun_ptr)(void *, void *); fun_ptr fun = get_default_keymgmt().gen_set_template; if (!fun) return 0; return fun(genctx, templ); } static int qat_dsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_set_params; if (!fun) return 0; return fun(genctx, params); } static const OSSL_PARAM *qat_dsa_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { typedef const OSSL_PARAM *(*fun_ptr)(void *, void *); fun_ptr fun = get_default_keymgmt().gen_settable_params; if (!fun) return NULL; return fun(genctx, provctx); } static void *qat_dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { typedef void *(*fun_ptr)(void *, OSSL_CALLBACK *, void *); DSA* dsa = NULL; fun_ptr fun = get_default_keymgmt().gen; if (!fun) goto end; dsa = fun(genctx, osslcb, cbarg); end: return dsa; } static void qat_dsa_gen_cleanup(void *genctx) { typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gen_cleanup; if (!fun) return; fun(genctx); } static void *qat_dsa_load(const void *reference, size_t reference_sz) { typedef void *(*fun_ptr)(const void *, size_t); fun_ptr fun = get_default_keymgmt().load; if (!fun) return NULL; return fun(reference, reference_sz); } static void *qat_dsa_dup(const void *keydata_from, int selection) { typedef void *(*fun_ptr)(const void *, int); fun_ptr fun = get_default_keymgmt().dup; if (!fun) return NULL; return fun(keydata_from, selection); } const OSSL_DISPATCH qat_dsa_keymgmt_functions[] = { {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_dsa_newdata}, {OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_dsa_gen_init}, {OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))qat_dsa_gen_set_template}, {OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_dsa_gen_set_params}, {OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_dsa_gen_settable_params}, {OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_dsa_gen}, {OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))qat_dsa_gen_cleanup}, {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))qat_dsa_load}, {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_dsa_freedata}, {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))qat_dsa_get_params}, {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))qat_dsa_gettable_params}, {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_dsa_has}, {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_dsa_match}, {OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))qat_dsa_validate}, {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_dsa_import}, {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_dsa_import_types}, {OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_dsa_export}, {OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_dsa_export_types}, {OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_dsa_dup}, {0, NULL}}; #endif qatengine-1.9.0/qat_prov_kmgmt_ec.c000066400000000000000000001054111500416242000173350ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_provider_kmgmt_ec.c * * This file contains the Qat provider EC Key Management implementation for * QAT_SW and QAT_HW operations * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_ec.h" #include "qat_utils.h" #include "qat_evp.h" #include "e_qat.h" #ifdef QAT_HW # include "qat_hw_ec.h" #endif #ifdef QAT_SW # include "qat_sw_ec.h" #endif #define COPY_INT_PARAM(params, key, val) \ p = OSSL_PARAM_locate_const(params, key); \ if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \ goto err; #define COPY_UTF8_PARAM(params, key, val) \ p = OSSL_PARAM_locate_const(params, key); \ if (p != NULL) { \ if (p->data_type != OSSL_PARAM_UTF8_STRING) \ goto err; \ OPENSSL_free(val); \ val = OPENSSL_strdup(p->data); \ if (val == NULL) \ goto err; \ } #define COPY_OCTET_PARAM(params, key, val, len) \ p = OSSL_PARAM_locate_const(params, key); \ if (p != NULL) { \ if (p->data_type != OSSL_PARAM_OCTET_STRING) \ goto err; \ OPENSSL_free(val); \ len = p->data_size; \ val = OPENSSL_memdup(p->data, p->data_size); \ if (val == NULL) \ goto err; \ } #define COPY_BN_PARAM(params, key, bn) \ p = OSSL_PARAM_locate_const(params, key); \ if (p != NULL) { \ if (bn == NULL) \ bn = BN_new(); \ if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \ goto err; \ } typedef struct{ int id; /* libcrypto internal */ int name_id; # if OPENSSL_VERSION_NUMBER >= 0x30300000 /* NID for the legacy alg if there is one */ int legacy_alg; # endif char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif /* Constructor(s), destructor, information */ OSSL_FUNC_keymgmt_new_fn *new; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; OSSL_FUNC_keymgmt_set_params_fn *set_params; OSSL_FUNC_keymgmt_settable_params_fn *settable_params; /* Generation, a complex constructor */ OSSL_FUNC_keymgmt_gen_init_fn *gen_init; OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; # if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_keymgmt_gen_get_params_fn *gen_get_params; OSSL_FUNC_keymgmt_gen_gettable_params_fn *gen_gettable_params; # endif OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; OSSL_FUNC_keymgmt_gen_fn *gen; OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; OSSL_FUNC_keymgmt_load_fn *load; /* Key object checking */ OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; OSSL_FUNC_keymgmt_has_fn *has; OSSL_FUNC_keymgmt_validate_fn *validate; OSSL_FUNC_keymgmt_match_fn *match; /* Import and export routines */ OSSL_FUNC_keymgmt_import_fn *import; OSSL_FUNC_keymgmt_import_types_fn *import_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; # endif OSSL_FUNC_keymgmt_export_fn *export; OSSL_FUNC_keymgmt_export_types_fn *export_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; # endif OSSL_FUNC_keymgmt_dup_fn *dup; } QAT_EC_KEYMGMT; typedef struct { OSSL_LIB_CTX *libctx; char *group_name; char *encoding; char *pt_format; char *group_check; char *field_type; BIGNUM *p, *a, *b, *order, *cofactor; unsigned char *gen, *seed; size_t gen_len, seed_len; int selection; int ecdh_mode; EC_GROUP *gen_group; }QAT_EC_GEN_CTX; #if defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) static QAT_EC_KEYMGMT get_default_keymgmt() { static QAT_EC_KEYMGMT s_keymgmt; static int initialized = 0; if (!initialized) { QAT_EC_KEYMGMT *keymgmt = (QAT_EC_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "EC", "provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initialized = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } EC_KEY *qat_ec_key_new(OSSL_LIB_CTX *libctx, const char *propq) { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { QATerr(ERR_LIB_EC, QAT_R_MALLOC_FAILURE); return NULL; } ret->libctx = libctx; if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); if (ret->propq == NULL) { QATerr(ERR_LIB_EC, QAT_R_MALLOC_FAILURE); goto err; } } # if OPENSSL_VERSION_NUMBER < 0x30200000 ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { QATerr(ERR_LIB_EC, QAT_R_MALLOC_FAILURE); goto err; } # else ret->references.val = 1; # endif ret->meth = EC_KEY_get_default_method(); ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { goto err; } if (ret->meth->init != NULL && ret->meth->init(ret) == 0) { QATerr(ERR_LIB_EC, QAT_R_INIT_FAIL); goto err; } return ret; err: EC_KEY_free(ret); return NULL; } static void *qat_keymgmt_ec_newdata(void *provctx) { if (!qat_prov_is_running()) return NULL; return qat_ec_key_new(prov_libctx_of(provctx), NULL); } static const char *qat_keymgmt_ec_query_operation_name(int operation_id) { typedef const char* (*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().query_operation_name; if (!fun) return NULL; return fun(operation_id); } static int qat_keymgmt_ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) { int ret = 0; QAT_EC_GEN_CTX *gctx = genctx; const OSSL_PARAM *p; COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode); COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name); COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type); COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding); COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format); COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check); COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p); COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a); COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b); COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order); COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor); COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len); COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen, gctx->gen_len); ret = 1; err: return ret; } static void *qat_keymgmt_ec_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { OSSL_LIB_CTX *libctx = prov_libctx_of(provctx); QAT_EC_GEN_CTX *gctx = NULL; if (qat_sw_ecdh_offload) { if (!qat_prov_is_running() || (selection & (OSSL_KEYMGMT_SELECT_ALL)) == 0) return NULL; if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { gctx->libctx = libctx; gctx->selection = selection; gctx->ecdh_mode = 0; if (!qat_keymgmt_ec_gen_set_params(gctx, params)) { OPENSSL_free(gctx); gctx = NULL; } } } else { typedef void * (*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_init; if (!fun) return NULL; return fun(provctx, selection, params); } return gctx; } static int qat_ec_gen_set_group(void *genctx, const EC_GROUP *src) { QAT_EC_GEN_CTX *gctx = genctx; EC_GROUP *group; group = EC_GROUP_dup(src); if (group == NULL) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_CURVE); return 0; } EC_GROUP_free(gctx->gen_group); gctx->gen_group = group; return 1; } static int qat_keymgmt_ec_gen_set_template(void *genctx, void *templ) { QAT_EC_GEN_CTX *gctx = genctx; EC_KEY *ec = templ; const EC_GROUP *ec_group; if (!qat_prov_is_running() || gctx == NULL || ec == NULL) return 0; if ((ec_group = EC_KEY_get0_group(ec)) == NULL) return 0; return qat_ec_gen_set_group(gctx, ec_group); } static const OSSL_PARAM *qat_keymgmt_ec_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { static OSSL_PARAM settable[] = { OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), OSSL_PARAM_END }; return settable; } static int qat_ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group) { if (group == NULL) { QATerr(ERR_LIB_PROV, QAT_R_NO_PARAMETERS_SET); return 0; } return EC_KEY_set_group(ec, group) > 0; } /* Mapping between a flag and a name */ static const OSSL_ITEM qat_encoding_nameid_map[] = { { OPENSSL_EC_EXPLICIT_CURVE, OSSL_PKEY_EC_ENCODING_EXPLICIT }, { OPENSSL_EC_NAMED_CURVE, OSSL_PKEY_EC_ENCODING_GROUP }, }; static const OSSL_ITEM qat_check_group_type_nameid_map[] = { { 0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT }, { EC_FLAG_CHECK_NAMED_GROUP, OSSL_PKEY_EC_GROUP_CHECK_NAMED }, { EC_FLAG_CHECK_NAMED_GROUP_NIST, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST }, }; static const OSSL_ITEM qat_format_nameid_map[] = { { (int)POINT_CONVERSION_UNCOMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED }, { (int)POINT_CONVERSION_COMPRESSED, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED }, { (int)POINT_CONVERSION_HYBRID, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID }, }; int qat_ec_encoding_name2id(const char *name) { size_t i, sz; /* Return the default value if there is no name */ if (name == NULL) return OPENSSL_EC_NAMED_CURVE; for (i = 0, sz = OSSL_NELEM(qat_encoding_nameid_map); i < sz; i++) { if (OPENSSL_strcasecmp(name, qat_encoding_nameid_map[i].ptr) == 0) return qat_encoding_nameid_map[i].id; } return -1; } int qat_ec_pt_format_name2id(const char *name) { size_t i, sz; /* Return the default value if there is no name */ if (name == NULL) return (int)POINT_CONVERSION_UNCOMPRESSED; for (i = 0, sz = OSSL_NELEM(qat_format_nameid_map); i < sz; i++) { if (OPENSSL_strcasecmp(name, qat_format_nameid_map[i].ptr) == 0) return qat_format_nameid_map[i].id; } return -1; } static int qat_ec_check_group_type_name2id(const char *name) { size_t i, sz; /* Return the default value if there is no name */ if (name == NULL) return 0; for (i = 0, sz = OSSL_NELEM(qat_check_group_type_nameid_map); i < sz; i++) { if (OPENSSL_strcasecmp(name, qat_check_group_type_nameid_map[i].ptr) == 0) return qat_check_group_type_nameid_map[i].id; } return -1; } static int qat_ec_gen_set_group_from_params(QAT_EC_GEN_CTX *gctx) { int ret = 0; OSSL_PARAM_BLD *bld; OSSL_PARAM *params = NULL; EC_GROUP *group = NULL; bld = OSSL_PARAM_BLD_new(); if (bld == NULL) return 0; if (gctx->encoding != NULL && !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding, 0)) goto err; if (gctx->pt_format != NULL && !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format, 0)) goto err; if (gctx->group_name != NULL) { if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name, 0)) goto err; /* Ignore any other parameters if there is a group name */ goto build; } else if (gctx->field_type != NULL) { if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type, 0)) goto err; } else { goto err; } if (gctx->p == NULL || gctx->a == NULL || gctx->b == NULL || gctx->order == NULL || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, gctx->p) || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, gctx->a) || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, gctx->b) || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, gctx->order)) goto err; if (gctx->cofactor != NULL && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor)) goto err; if (gctx->seed != NULL && !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len)) goto err; if (gctx->gen == NULL || !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen, gctx->gen_len)) goto err; build: params = OSSL_PARAM_BLD_to_param(bld); if (params == NULL) goto err; group = EC_GROUP_new_from_params(params, gctx->libctx, NULL); if (group == NULL) goto err; EC_GROUP_free(gctx->gen_group); gctx->gen_group = group; ret = 1; err: OSSL_PARAM_free(params); OSSL_PARAM_BLD_free(bld); return ret; } int qat_ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode) { const EC_GROUP *ecg = EC_KEY_get0_group(ec); const BIGNUM *cofactor; /* * mode can be only 0 for disable, or 1 for enable here. * * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that * also supports mode == -1 with the meaning of "reset to the default for * the associated key". */ if (mode < 0 || mode > 1) return 0; if ((cofactor = EC_GROUP_get0_cofactor(ecg)) == NULL ) return 0; /* ECDH cofactor mode has no effect if cofactor is 1 */ if (BN_is_one(cofactor)) return 1; if (mode == 1) EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH); else if (mode == 0) EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH); return 1; } int qat_ec_set_check_group_type_from_name(EC_KEY *ec, const char *name) { int flags = qat_ec_check_group_type_name2id(name); if (flags == -1) return 0; EC_KEY_clear_flags(ec, EC_FLAG_CHECK_NAMED_GROUP_MASK); EC_KEY_set_flags(ec, flags); return 1; } static void *qat_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { QAT_EC_GEN_CTX *gctx = genctx; EC_KEY *ec = NULL; int ret = 0; if (!qat_prov_is_running() || gctx == NULL || (ec = qat_ec_key_new(gctx->libctx, NULL)) == NULL) return NULL; if (gctx->gen_group == NULL) { if (!qat_ec_gen_set_group_from_params(gctx)) goto err; } else { if (gctx->encoding != NULL) { int flags = qat_ec_encoding_name2id(gctx->encoding); if (flags < 0) goto err; EC_GROUP_set_asn1_flag(gctx->gen_group, flags); } if (gctx->pt_format != NULL) { int format = qat_ec_pt_format_name2id(gctx->pt_format); if (format < 0) goto err; EC_GROUP_set_point_conversion_form(gctx->gen_group, format); } } /* We must always assign a group, no matter what */ ret = qat_ec_gen_assign_group(ec, gctx->gen_group); #if ENABLE_QAT_HW_ECDH if (qat_hw_ecdh_offload) ret = ret && qat_ecdh_generate_key(ec); #endif #if ENABLE_QAT_SW_ECDH if (qat_sw_ecdh_offload) { ret = ret && mb_ecdh_generate_key(ec); } else { typedef void * (*fun_ptr)(void *, OSSL_CALLBACK *, void *); fun_ptr fun = get_default_keymgmt().gen; if (!fun) return NULL; return fun(genctx, osslcb, cbarg); } #endif if (gctx->ecdh_mode != -1) ret = ret && qat_ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode); if (gctx->group_check != NULL) ret = ret && qat_ec_set_check_group_type_from_name(ec, gctx->group_check); if (ret) return ec; err: /* Something went wrong, throw the key away */ EC_KEY_free(ec); return NULL; } static int qat_keymgmt_ec_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_keymgmt_ec_gettable_params(void *provctx) { typedef const OSSL_PARAM* (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static const OSSL_PARAM *qat_keymgmt_ec_settable_params(void *provctx) { typedef const OSSL_PARAM* (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().settable_params; if (!fun) return NULL; return fun(provctx); } static int qat_keymgmt_ec_set_params(void *key, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *,const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().set_params; if (!fun) return 0; return fun(key,params); } static void qat_keymgmt_ec_freedata(void *keydata) { #ifdef ENABLE_QAT_FIPS QAT_EC_KEY_free(keydata); #else typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().free; if (!fun) return; fun(keydata); #endif } static int qat_keymgmt_ec_has(const void *keydata, int selection) { typedef int (*fun_ptr)(const void *,int); fun_ptr fun = get_default_keymgmt().has; if (!fun) return 0; return fun(keydata,selection); } static int qat_keymgmt_ec_import(void *keydata, int selection, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, int, const OSSL_PARAM*); fun_ptr fun = get_default_keymgmt().import; if (!fun) return 0; return fun(keydata,selection,params); } static const OSSL_PARAM *qat_keymgmt_ec_import_types(int selection) { typedef const OSSL_PARAM* (*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().import_types; if (!fun) return NULL; return fun(selection); } static int qat_keymgmt_ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg) { typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); fun_ptr fun = get_default_keymgmt().export; if (!fun) return 0; return fun(keydata,selection,param_cb,cbarg); } static const OSSL_PARAM *qat_keymgmt_ec_export_types(int selection) { typedef const OSSL_PARAM* (*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().export_types; if (!fun) return NULL; return fun(selection); } static void qat_keymgmt_ec_gen_cleanup(void *genctx) { QAT_EC_GEN_CTX *gctx = genctx; if (gctx == NULL) return; EC_GROUP_free(gctx->gen_group); BN_free(gctx->p); BN_free(gctx->a); BN_free(gctx->b); BN_free(gctx->order); BN_free(gctx->cofactor); OPENSSL_free(gctx->group_name); OPENSSL_free(gctx->field_type); OPENSSL_free(gctx->pt_format); OPENSSL_free(gctx->encoding); OPENSSL_free(gctx->seed); OPENSSL_free(gctx->gen); OPENSSL_free(gctx); } static void *qat_keymgmt_ec_load(const void *reference, size_t reference_sz) { typedef void* (*fun_ptr)(const void *, size_t); fun_ptr fun = get_default_keymgmt().load; if (!fun) return NULL; return fun(reference,reference_sz); } static void *qat_keymgmt_ec_dup(const void *keydata_from, int selection) { typedef void* (*fun_ptr)(const void *, int); fun_ptr fun = get_default_keymgmt().dup; if (!fun) return NULL; return fun(keydata_from, selection); } static int qat_keymgmt_ec_validate(const void *keydata, int selection, int checktype) { typedef int (*fun_ptr)(const void *, int, int); fun_ptr fun = get_default_keymgmt().validate; if (!fun) return 0; return fun(keydata, selection, checktype); } static int qat_keymgmt_ec_match(const void *keydata1, const void *keydata2, int selection) { typedef int (*fun_ptr)(const void *, const void *, int); fun_ptr fun = get_default_keymgmt().match; if (!fun) return 0; return fun(keydata1, keydata2, selection); } #endif #if defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) const OSSL_DISPATCH qat_ecdh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_keymgmt_ec_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_keymgmt_ec_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))qat_keymgmt_ec_gen_set_template }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_keymgmt_ec_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_keymgmt_ec_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_keymgmt_ec_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))qat_keymgmt_ec_gen_cleanup }, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))qat_keymgmt_ec_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_keymgmt_ec_freedata}, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))qat_keymgmt_ec_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))qat_keymgmt_ec_gettable_params }, { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))qat_keymgmt_ec_set_params }, { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))qat_keymgmt_ec_settable_params }, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_keymgmt_ec_has }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_keymgmt_ec_match }, { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))qat_keymgmt_ec_validate }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_keymgmt_ec_import }, { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_keymgmt_ec_import_types }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_keymgmt_ec_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_keymgmt_ec_export_types }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_keymgmt_ec_dup }, { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))qat_keymgmt_ec_query_operation_name }, {0, NULL } }; #endif /* defined(ENABLE_QAT_HW_ECDH) || defined(ENABLE_QAT_SW_ECDH) */ #if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) static QAT_EC_KEYMGMT sm2_get_default_keymgmt() { static QAT_EC_KEYMGMT s_keymgmt; static int initialized = 0; if (!initialized) { QAT_EC_KEYMGMT *keymgmt = (QAT_EC_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "SM2", "provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initialized = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } static void *qat_sm2_keymgmt_ec_newdata(void *provctx) { typedef void* (*fun_ptr)(void *); fun_ptr fun = sm2_get_default_keymgmt().new; if (!fun) return NULL; return fun(provctx); } static const char *qat_sm2_keymgmt_ec_query_operation_name(int operation_id) { typedef const char* (*fun_ptr)(int); fun_ptr fun = sm2_get_default_keymgmt().query_operation_name; if (!fun) return NULL; return fun(operation_id); } static void *qat_sm2_keymgmt_ec_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { typedef void* (*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = sm2_get_default_keymgmt().gen_init; if (!fun) return NULL; return fun(provctx, selection, params); } static int qat_sm2_keymgmt_ec_gen_set_template(void *genctx, void *templ) { typedef int (*fun_ptr)(void *, void *); fun_ptr fun = sm2_get_default_keymgmt().gen_set_template; if (!fun) return 0; return fun(genctx,templ); } static int qat_sm2_keymgmt_ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, const OSSL_PARAM *); fun_ptr fun = sm2_get_default_keymgmt().gen_set_params; if (!fun) return 0; return fun(genctx,params); } static const OSSL_PARAM *qat_sm2_keymgmt_ec_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { typedef const OSSL_PARAM* (*fun_ptr)(void *, void *); fun_ptr fun = sm2_get_default_keymgmt().gen_settable_params; if (!fun) return NULL; return fun(genctx,provctx); } static void *qat_sm2_keymgmt_ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { typedef void* (*fun_ptr)(void *, OSSL_CALLBACK *, void *); fun_ptr fun = sm2_get_default_keymgmt().gen; if (!fun) return NULL; return fun(genctx,osslcb,cbarg); } static int qat_sm2_keymgmt_ec_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, OSSL_PARAM *); fun_ptr fun = sm2_get_default_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_sm2_keymgmt_ec_gettable_params(void *provctx) { typedef const OSSL_PARAM* (*fun_ptr)(void *); fun_ptr fun = sm2_get_default_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static const OSSL_PARAM *qat_sm2_keymgmt_ec_settable_params(void *provctx) { typedef const OSSL_PARAM* (*fun_ptr)(void *); fun_ptr fun = sm2_get_default_keymgmt().settable_params; if (!fun) return NULL; return fun(provctx); } static int qat_sm2_keymgmt_ec_set_params(void *key, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *,const OSSL_PARAM *); fun_ptr fun = sm2_get_default_keymgmt().set_params; if (!fun) return 0; return fun(key,params); } static void qat_sm2_keymgmt_ec_freedata(void *keydata) { typedef void (*fun_ptr)(void *); fun_ptr fun = sm2_get_default_keymgmt().free; if (!fun) return; fun(keydata); } static int qat_sm2_keymgmt_ec_has(const void *keydata, int selection) { typedef int (*fun_ptr)(const void *,int); fun_ptr fun = sm2_get_default_keymgmt().has; if (!fun) return 0; return fun(keydata,selection); } static int qat_sm2_keymgmt_ec_import(void *keydata, int selection, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, int, const OSSL_PARAM*); fun_ptr fun = sm2_get_default_keymgmt().import; if (!fun) return 0; return fun(keydata,selection,params); } static const OSSL_PARAM *qat_sm2_keymgmt_ec_import_types(int selection) { typedef const OSSL_PARAM* (*fun_ptr)(int); fun_ptr fun = sm2_get_default_keymgmt().import_types; if (!fun) return NULL; return fun(selection); } static int qat_sm2_keymgmt_ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg) { typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); fun_ptr fun = sm2_get_default_keymgmt().export; if (!fun) return 0; return fun(keydata,selection,param_cb,cbarg); } static const OSSL_PARAM *qat_sm2_keymgmt_ec_export_types(int selection) { typedef const OSSL_PARAM* (*fun_ptr)(int); fun_ptr fun = sm2_get_default_keymgmt().export_types; if (!fun) return NULL; return fun(selection); } static void qat_sm2_keymgmt_ec_gen_cleanup(void *genctx) { typedef void (*fun_ptr)(void *); fun_ptr fun = sm2_get_default_keymgmt().gen_cleanup; if (!fun) return; fun(genctx); } static void *qat_sm2_keymgmt_ec_load(const void *reference, size_t reference_sz) { typedef void* (*fun_ptr)(const void *, size_t); fun_ptr fun = sm2_get_default_keymgmt().load; if (!fun) return NULL; return fun(reference,reference_sz); } static int qat_sm2_keymgmt_match(const void *keydata1, const void *keydata2, int selection) { typedef int (*fun_ptr)(const void *, const void *, int); fun_ptr fun = sm2_get_default_keymgmt().match; if (!fun) return 0; return fun(keydata1, keydata2, selection); } int qat_sm2_keymgmt_validate(const void *keydata, int selection, int checktype) { typedef int (*fun_ptr)(const void *, int, int); fun_ptr fun = sm2_get_default_keymgmt().validate; if (!fun) return 0; return fun(keydata, selection, checktype); } static void *qat_sm2_keymgmt_ec_dup(const void *keydata_from, int selection) { typedef void * (*fun_ptr)(const void *, int); fun_ptr fun = sm2_get_default_keymgmt().dup; if (!fun) return NULL; return fun(keydata_from, selection); } const OSSL_DISPATCH qat_sm2_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_sm2_keymgmt_ec_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_sm2_keymgmt_ec_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))qat_sm2_keymgmt_ec_gen_set_template }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_sm2_keymgmt_ec_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_sm2_keymgmt_ec_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_sm2_keymgmt_ec_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))qat_sm2_keymgmt_ec_gen_cleanup }, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))qat_sm2_keymgmt_ec_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_sm2_keymgmt_ec_freedata}, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))qat_sm2_keymgmt_ec_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))qat_sm2_keymgmt_ec_gettable_params }, { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))qat_sm2_keymgmt_ec_set_params }, { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))qat_sm2_keymgmt_ec_settable_params }, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_sm2_keymgmt_ec_has }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_sm2_keymgmt_match }, { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))qat_sm2_keymgmt_validate }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_sm2_keymgmt_ec_import }, { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_sm2_keymgmt_ec_import_types }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_sm2_keymgmt_ec_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_sm2_keymgmt_ec_export_types }, { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))qat_sm2_keymgmt_ec_query_operation_name }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_sm2_keymgmt_ec_dup }, {0, NULL } }; # endif /* ENABLE_QAT_SW_SM2 */ qatengine-1.9.0/qat_prov_kmgmt_ecx.c000066400000000000000000000375471500416242000175430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_kmgmt_ecx.c * * This file contains X25519 qatprovider key management implementation * for QAT_HW & QAT_SW * *****************************************************************************/ #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_ecx.h" #include "qat_utils.h" #include "e_qat.h" #if defined(ENABLE_QAT_HW_ECX) || defined(ENABLE_QAT_SW_ECX) QAT_ECX_KEYMGMT get_default_x25519_keymgmt() { static QAT_ECX_KEYMGMT s_keymgmt; static int initialized = 0; if (!initialized) { QAT_ECX_KEYMGMT *keymgmt = (QAT_ECX_KEYMGMT *)EVP_KEYMGMT_fetch(NULL,"X25519","provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initialized = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } ECX_KEY *qat_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, const char *propq) { ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) return NULL; ret->libctx = libctx; ret->haspubkey = haspubkey; switch (type) { case ECX_KEY_TYPE_X25519: ret->keylen = X25519_KEYLEN; break; case ECX_KEY_TYPE_X448: ret->keylen = X448_KEYLEN; break; } ret->type = type; #if OPENSSL_VERSION_NUMBER < 0x30200000 ret->references = 1; #else ret->references.val = 1; #endif if (propq != NULL) { ret->propq = OPENSSL_strdup(propq); if (ret->propq == NULL) goto err; } #if OPENSSL_VERSION_NUMBER < 0x30200000 ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) goto err; #endif return ret; err: QATerr(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } static void *qat_x25519_new_key(void *provctx) { if (!qat_prov_is_running()) return 0; return qat_ecx_key_new(prov_libctx_of(provctx), ECX_KEY_TYPE_X25519, 0, NULL); } static int qat_ecx_has(const void *keydata, int selection) { const ECX_KEY *key = keydata; int ok = 0; if (qat_prov_is_running() && key != NULL) { ok = 1; if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) ok = ok && key->haspubkey; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) ok = ok && key->privkey != NULL; } return ok; } void *qat_ecx_load(const void *reference, size_t reference_sz) { ECX_KEY *key = NULL; if (qat_prov_is_running() && reference_sz == sizeof(key)) { /* The contents of the reference is the address to our object */ key = *(ECX_KEY **)reference; /* We grabbed, so we detach it */ *(ECX_KEY **)reference = NULL; return key; } return NULL; } static void *qat_ecx_gen_init(void *provctx, int selection, const OSSL_PARAM params[], ECX_KEY_TYPE type) { OSSL_LIB_CTX *libctx = prov_libctx_of(provctx); QAT_GEN_CTX *gctx = NULL; if (!qat_prov_is_running()) return NULL; if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { gctx->libctx = libctx; gctx->type = type; gctx->selection = selection; } return gctx; } static void *qat_x25519_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { return qat_ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519); } static void *qat_x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { #ifdef ENABLE_QAT_HW_ECX if (qat_hw_ecx_offload) return qat_pkey_ecx25519_keygen(genctx,osslcb,cbarg); #endif #ifdef ENABLE_QAT_SW_ECX if (qat_sw_ecx_offload) { return multibuff_x25519_keygen(genctx,osslcb,cbarg); } else { typedef void* (*fun_ptr)(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg); fun_ptr fun = get_default_x25519_keymgmt().gen; if (!fun) return NULL; return fun(genctx, osslcb, cbarg); } #endif return 0; } #ifdef ENABLE_QAT_HW_ECX static void *qat_x448_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { return qat_ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448); } static void *qat_x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { return qat_pkey_ecx448_keygen(genctx,osslcb,cbarg); } #endif static void qat_ecx_gen_cleanup(void *genctx) { QAT_GEN_CTX *gctx = genctx; OPENSSL_free(gctx->propq); OPENSSL_free(gctx); } static int qat_x25519_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *key, OSSL_PARAM params[]); fun_ptr fun = get_default_x25519_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_x25519_gettable_params(void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *provctx); fun_ptr fun = get_default_x25519_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static int qat_x25519_set_params(void *key, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *key, const OSSL_PARAM params[]); fun_ptr fun = get_default_x25519_keymgmt().set_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_x25519_settable_params(void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *provctx); fun_ptr fun = get_default_x25519_keymgmt().settable_params; if (!fun) return NULL; return fun(provctx); } #ifdef ENABLE_QAT_HW_ECX QAT_ECX_KEYMGMT get_default_x448_keymgmt() { static QAT_ECX_KEYMGMT s_keymgmt; static int initialized = 0; if (!initialized) { QAT_ECX_KEYMGMT *keymgmt = (QAT_ECX_KEYMGMT *)EVP_KEYMGMT_fetch(NULL,"X448","provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initialized = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } static void *qat_x448_new_key(void *provctx) { if (!qat_prov_is_running()) return 0; return qat_ecx_key_new(prov_libctx_of(provctx), ECX_KEY_TYPE_X448, 0, NULL); } static int qat_x448_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *key, OSSL_PARAM params[]); fun_ptr fun = get_default_x448_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_x448_gettable_params(void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *provctx); fun_ptr fun = get_default_x448_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static int qat_x448_set_params(void *key, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *key, const OSSL_PARAM params[]); fun_ptr fun = get_default_x448_keymgmt().set_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_x448_settable_params(void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *provctx); fun_ptr fun = get_default_x448_keymgmt().settable_params; if (!fun) return NULL; return fun(provctx); } #endif static int qat_ecx_match(const void *keydata1, const void *keydata2, int selection) { typedef int (*fun_ptr)(const void *keydata1, const void *keydata2, int selection); fun_ptr fun = get_default_x25519_keymgmt().match; if (!fun) return 0; return fun(keydata1, keydata2, selection); } static int qat_ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *keydata, int selection, const OSSL_PARAM params[]); fun_ptr fun = get_default_x25519_keymgmt().import; if (!fun) return 0; return fun(keydata, selection, params); } static const OSSL_PARAM *qat_ecx_import_types(int selection) { typedef const OSSL_PARAM * (*fun_ptr)(int selection); fun_ptr fun = get_default_x25519_keymgmt().import_types; if (!fun) return NULL; return fun(selection); } static const OSSL_PARAM *qat_ecx_export_types(int selection) { typedef const OSSL_PARAM * (*fun_ptr)(int selection); fun_ptr fun = get_default_x25519_keymgmt().export_types; if (!fun) return NULL; return fun(selection); } static int qat_ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg) { typedef int (*fun_ptr)(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg); fun_ptr fun = get_default_x25519_keymgmt().export; if (!fun) return 0; return fun(keydata, selection, param_cb, cbarg); } static int qat_ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *genctx, const OSSL_PARAM params[]); fun_ptr fun = get_default_x25519_keymgmt().gen_set_params; if (!fun) return 0; return fun(genctx, params); } static const OSSL_PARAM *qat_ecx_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(ossl_unused void *genctx, ossl_unused void *provctx); fun_ptr fun = get_default_x25519_keymgmt().gen_settable_params; if (!fun) return NULL; return fun(genctx, provctx); } unsigned char *qat_ecx_key_allocate_privkey(ECX_KEY *key) { key->privkey = OPENSSL_secure_zalloc(key->keylen); return key->privkey; } ECX_KEY *qat_ecx_key_dup(const ECX_KEY *key, int selection) { ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { QATerr(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } #if OPENSSL_VERSION_NUMBER < 0x30200000 ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { OPENSSL_free(ret); return NULL; } #endif ret->libctx = key->libctx; ret->haspubkey = key->haspubkey; ret->keylen = key->keylen; ret->type = key->type; #if OPENSSL_VERSION_NUMBER < 0x30200000 ret->references = 1; #else ret->references.val = 1; #endif if (key->propq != NULL) { ret->propq = OPENSSL_strdup(key->propq); if (ret->propq == NULL) goto err; } if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey)); if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && key->privkey != NULL) { if (qat_ecx_key_allocate_privkey(ret) == NULL) goto err; memcpy(ret->privkey, key->privkey, ret->keylen); } return ret; err: qat_ecx_key_free(ret); QATerr(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return NULL; } static void *qat_ecx_dup(const void *keydata_from, int selection) { if (qat_prov_is_running()) return qat_ecx_key_dup(keydata_from, selection); return NULL; } const OSSL_DISPATCH qat_X25519_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_x25519_new_key}, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_ecx_key_free}, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_ecx_has }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_x25519_gen_init}, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_x25519_gen}, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void)) qat_ecx_gen_cleanup}, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void)) qat_ecx_load}, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))qat_x25519_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))qat_x25519_gettable_params }, { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))qat_x25519_set_params }, { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))qat_x25519_settable_params }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_ecx_match }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_ecx_import }, { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_ecx_import_types }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_ecx_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_ecx_export_types }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_ecx_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_ecx_gen_settable_params }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_ecx_dup }, { 0, NULL }}; #endif #ifdef ENABLE_QAT_HW_ECX const OSSL_DISPATCH qat_X448_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_x448_new_key}, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_ecx_key_free}, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_ecx_has }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_x448_gen_init}, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_x448_gen}, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void)) qat_ecx_gen_cleanup}, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void)) qat_ecx_load}, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))qat_x448_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))qat_x448_gettable_params }, { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))qat_x448_set_params }, { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))qat_x448_settable_params }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_ecx_match }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_ecx_import }, { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_ecx_import_types }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_ecx_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_ecx_export_types }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_ecx_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_ecx_gen_settable_params }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_ecx_dup }, { 0, NULL }}; #endif qatengine-1.9.0/qat_prov_kmgmt_rsa.c000066400000000000000000000266231500416242000175420ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_kmgmt_rsa.c * * This file contains RSA key management implementation from default provider. * *****************************************************************************/ #include #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_rsa.h" #include "qat_utils.h" #include "qat_prov_cmvp.h" #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) typedef struct{ int id; /* libcrypto internal */ int name_id; # if OPENSSL_VERSION_NUMBER >= 0x30300000 /* NID for the legacy alg if there is one */ int legacy_alg; # endif char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif /* Constructor(s), destructor, information */ OSSL_FUNC_keymgmt_new_fn *new; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; OSSL_FUNC_keymgmt_set_params_fn *set_params; OSSL_FUNC_keymgmt_settable_params_fn *settable_params; /* Generation, a complex constructor */ OSSL_FUNC_keymgmt_gen_init_fn *gen_init; OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; # if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_keymgmt_gen_get_params_fn *gen_get_params; OSSL_FUNC_keymgmt_gen_gettable_params_fn *gen_gettable_params; # endif OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; OSSL_FUNC_keymgmt_gen_fn *gen; OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; OSSL_FUNC_keymgmt_load_fn *load; /* Key object checking */ OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; OSSL_FUNC_keymgmt_has_fn *has; OSSL_FUNC_keymgmt_validate_fn *validate; OSSL_FUNC_keymgmt_match_fn *match; /* Import and export routines */ OSSL_FUNC_keymgmt_import_fn *import; OSSL_FUNC_keymgmt_import_types_fn *import_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; # endif OSSL_FUNC_keymgmt_export_fn *export; OSSL_FUNC_keymgmt_export_types_fn *export_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; # endif OSSL_FUNC_keymgmt_dup_fn *dup; } QAT_RSA_KEYMGMT; typedef struct { OSSL_LIB_CTX *libctx; const char *propq; int rsa_type; size_t nbits; BIGNUM *pub_exp; size_t primes; #if 0 /* For PSS */ RSA_PSS_PARAMS_30 pss_params; int pss_defaults_set; /* For generation callback */ OSSL_CALLBACK *cb; void *cbarg; #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) /* ACVP test parameters */ OSSL_PARAM *acvp_test_params; #endif #endif }QAT_RSA_GEN_CTX; QAT_RSA_KEYMGMT get_default_keymgmt() { static QAT_RSA_KEYMGMT s_keymgmt; static int initialized = 0; if (!initialized) { QAT_RSA_KEYMGMT *keymgmt = (QAT_RSA_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "RSA", "provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initialized = 1; } else { WARN("EVP_KEYMGMT_fetch from default provider failed"); } } return s_keymgmt; } static void *qat_keymgmt_rsa_newdata(void *provctx) { typedef void* (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().new; if (!fun) return NULL; return fun(provctx); } static void qat_keymgmt_rsa_freedata(void *keydata) { #ifdef ENABLE_QAT_FIPS QAT_RSA_free(keydata); #else typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().free; if (!fun) return; fun(keydata); #endif } static int qat_keymgmt_rsa_has(const void *keydata, int selection) { typedef int (*fun_ptr)(const void *,int); fun_ptr fun = get_default_keymgmt().has; if (!fun) return 0; return fun(keydata,selection); } static int qat_keymgmt_rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, int, const OSSL_PARAM*); fun_ptr fun = get_default_keymgmt().import; if (!fun) return 0; return fun(keydata,selection,params); } static const OSSL_PARAM *qat_keymgmt_rsa_import_types(int selection) { typedef const OSSL_PARAM* (*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().import_types; if (!fun) return NULL; return fun(selection); } static void *qat_keymgmt_rsa_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { typedef void * (*fun_ptr)(void *, int, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_init; if (!fun) return NULL; return fun(provctx, selection, params); } static int qat_keymgmt_rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, const OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().gen_set_params; if (!fun) return 0; return fun(genctx, params); } static const OSSL_PARAM *qat_keymgmt_rsa_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *, void *); fun_ptr fun = get_default_keymgmt().gen_settable_params; if (!fun) return NULL; return fun(genctx, provctx); } static void *qat_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { typedef void * (*fun_ptr)(void *, OSSL_CALLBACK *, void *); RSA *rsa = NULL; fun_ptr fun = get_default_keymgmt().gen; if (!fun) goto end; rsa = fun(genctx, osslcb, cbarg); end: return rsa; } static void qat_keymgmt_rsa_gen_cleanup(void *genctx) { typedef void (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gen_cleanup; if (!fun) return; fun(genctx); } static void *qat_keymgmt_rsa_load(const void *reference, size_t reference_sz) { typedef void * (*fun_ptr)(const void *, size_t); fun_ptr fun = get_default_keymgmt().load; if (!fun) return NULL; return fun(reference, reference_sz); } static int qat_keymgmt_rsa_get_params(void *key, OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *, OSSL_PARAM *); fun_ptr fun = get_default_keymgmt().get_params; if (!fun) return 0; return fun(key, params); } static const OSSL_PARAM *qat_keymgmt_rsa_gettable_params(void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(void *); fun_ptr fun = get_default_keymgmt().gettable_params; if (!fun) return NULL; return fun(provctx); } static int qat_keymgmt_rsa_match(const void *keydata1, const void *keydata2, int selection) { typedef int (*fun_ptr)(const void *, const void *, int); fun_ptr fun = get_default_keymgmt().match; if (!fun) return 0; return fun(keydata1, keydata2, selection); } static int qat_keymgmt_rsa_validate(const void *keydata, int selection, int checktype) { typedef int (*fun_ptr)(const void *, int, int); fun_ptr fun = get_default_keymgmt().validate; if (!fun) return 0; return fun(keydata, selection, checktype); } static int qat_keymgmt_rsa_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); fun_ptr fun = get_default_keymgmt().export; if (!fun) return 0; return fun(keydata, selection, param_callback, cbarg); } static const OSSL_PARAM *qat_keymgmt_rsa_export_types(int selection) { typedef const OSSL_PARAM * (*fun_ptr)(int); fun_ptr fun = get_default_keymgmt().export_types; if (!fun) return NULL; return fun(selection); } static void *qat_keymgmt_rsa_dup(const void *keydata_from, int selection) { typedef void * (*fun_ptr)(const void *, int); fun_ptr fun = get_default_keymgmt().dup; if (!fun) return NULL; return fun(keydata_from, selection); } const OSSL_DISPATCH qat_rsa_keymgmt_functions[] = { {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))qat_keymgmt_rsa_newdata}, {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))qat_keymgmt_rsa_freedata}, {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))qat_keymgmt_rsa_has}, {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))qat_keymgmt_rsa_import}, {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))qat_keymgmt_rsa_import_types}, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))qat_keymgmt_rsa_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))qat_keymgmt_rsa_gen_set_params }, { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))qat_keymgmt_rsa_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))qat_keymgmt_rsa_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))qat_keymgmt_rsa_gen_cleanup }, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))qat_keymgmt_rsa_load }, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))qat_keymgmt_rsa_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))qat_keymgmt_rsa_gettable_params }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))qat_keymgmt_rsa_match }, { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))qat_keymgmt_rsa_validate }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))qat_keymgmt_rsa_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))qat_keymgmt_rsa_export_types }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))qat_keymgmt_rsa_dup }, {0, NULL} }; #endif qatengine-1.9.0/qat_prov_prf.c000066400000000000000000000444051500416242000163430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_prf.c * * This file contains qatprovider implementation of PRF. * *****************************************************************************/ #include "qat_prov_prf.h" #include "e_qat.h" #include "qat_prov_cmvp.h" #ifdef ENABLE_QAT_HW_PRF static OSSL_FUNC_kdf_newctx_fn qat_tls_prf_new; static OSSL_FUNC_kdf_freectx_fn qat_tls_prf_free; static OSSL_FUNC_kdf_reset_fn qat_tls_prf_reset; static OSSL_FUNC_kdf_derive_fn qat_tls_prf_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn qat_tls_prf_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn qat_tls_prf_set_ctx_params; static OSSL_FUNC_kdf_gettable_ctx_params_fn qat_tls_prf_gettable_ctx_params; static OSSL_FUNC_kdf_get_ctx_params_fn qat_tls_prf_get_ctx_params; static QAT_EVP_KDF get_default_tls12_kdf() { static QAT_EVP_KDF s_kdf; static int initialized = 0; if (!initialized) { QAT_EVP_KDF *kdf = (QAT_EVP_KDF *)EVP_KDF_fetch(NULL, "TLS1-PRF", "provider=default"); if (kdf) { s_kdf = *kdf; EVP_KDF_free((QAT_EVP_KDF *) kdf); initialized = 1; } else { WARN("EVP_KDF_fetch from default provider failed"); } } return s_kdf; } static const EVP_MD *qat_prov_digest_md(const PROV_DIGEST *pd) { return pd->md; } static int load_common(const OSSL_PARAM params[], const char **propquery, ENGINE **engine) { const OSSL_PARAM *p; *propquery = NULL; p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; *propquery = p->data; } *engine = NULL; return 1; } static const EVP_MD *qat_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx, const char *mdname, const char *propquery) { EVP_MD_free(pd->alloc_md); pd->md = pd->alloc_md = EVP_MD_fetch(libctx, mdname, propquery); return pd->md; } static int qat_prov_digest_load_from_params(PROV_DIGEST *pd, const OSSL_PARAM params[], OSSL_LIB_CTX *ctx) { const OSSL_PARAM *p; const char *propquery; if (params == NULL) return 1; if (!load_common(params, &propquery, &pd->engine)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST); if (p == NULL) return 1; if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; ERR_set_mark(); qat_prov_digest_fetch(pd, ctx, p->data, propquery); if (pd->md != NULL) ERR_pop_to_mark(); else ERR_clear_last_mark(); return pd->md != NULL; } static void *qat_tls_prf_new(void *provctx) { QAT_TLS_PRF *ctx; QAT_EVP_KDF sw_prf_kdf; sw_prf_kdf = get_default_tls12_kdf(); if (!qat_prov_is_running()) return NULL; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } else ctx->provctx = provctx; ctx->pctx = OPENSSL_zalloc(sizeof(EVP_PKEY_CTX)); if (ctx->pctx == NULL){ WARN("Malloc for EVP_PKEY_CTX error.\n"); return NULL; } if (!ctx->sw_ctx) ctx->sw_ctx = sw_prf_kdf.newctx(ctx); if (!qat_tls1_prf_init(ctx->pctx)){ if (!qat_get_sw_fallback_enabled()) { WARN("EVP_PKEY_CTX init failed.\n"); return NULL; } } return ctx; } static void qat_tls_prf_free(void *vctx) { QAT_TLS_PRF *ctx = (QAT_TLS_PRF *)vctx; int fallback = 0; if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); fallback = 1; goto end; } if (ctx != NULL) { if (ctx->sw_ctx) { OPENSSL_free(ctx->sw_ctx); ctx->sw_ctx = NULL; } qat_prf_cleanup(ctx->pctx); OPENSSL_free(ctx->pctx); ctx->pctx = NULL; qat_tls_prf_reset(ctx); OPENSSL_free(ctx); } end: if (fallback) { typedef void(*sw_fun_ptr)(void *); sw_fun_ptr default_prov_tls12_kdf_fun = get_default_tls12_kdf().freectx; default_prov_tls12_kdf_fun(ctx->sw_ctx); } } static void qat_tls_prf_reset(void *vctx) { QAT_TLS_PRF *ctx = (QAT_TLS_PRF *)vctx; void *provctx = ctx->provctx; EVP_MAC_CTX_free(ctx->P_hash); EVP_MAC_CTX_free(ctx->P_sha1); OPENSSL_clear_free(ctx->sec, ctx->seclen); OPENSSL_cleanse(ctx->seed, ctx->seedlen); OPENSSL_cleanse(ctx->qat_userLabel, ctx->qat_userLabel_len); OPENSSL_free(ctx->qat_userLabel); ctx->qat_userLabel = NULL; memset(ctx, 0, sizeof(*ctx)); ctx->provctx = provctx; } static int qat_tls_prf_derive(void *vctx, unsigned char *key, size_t keylen, const OSSL_PARAM params[]) { QAT_TLS_PRF *ctx = (QAT_TLS_PRF *)vctx; QAT_TLS1_PRF_CTX *qat_prf_ctx = (QAT_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data( ctx->pctx); const EVP_MD *md; int ret = 0, fallback = 0; #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); fallback = 1; goto end; } if (!qat_prov_is_running() || !qat_tls_prf_set_ctx_params(ctx, params)) goto end; md = qat_prov_digest_md(&ctx->digest); if (md == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); goto end; } if (ctx->P_hash == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); goto end; } if (ctx->sec == NULL) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_SECRET); goto end; } if (ctx->seedlen == 0 && ctx->qat_userLabel_len == 0) { QATerr(ERR_LIB_PROV, PROV_R_MISSING_SEED); goto end; } if (keylen == 0) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); goto end; } qat_prf_ctx->qat_md = md; if (!qat_tls1_prf_ctrl(ctx->pctx, EVP_PKEY_CTRL_TLS_SEED, ctx->qat_userLabel_len, ctx->qat_userLabel)){ WARN("Failed in setting prf userLabel.\n"); goto end; } if (!qat_tls1_prf_ctrl(ctx->pctx, EVP_PKEY_CTRL_TLS_SEED, ctx->seedlen, ctx->seed)) { WARN("Failed in setting prf seed.\n"); goto end; } ret = qat_prf_tls_derive(ctx->pctx, key, &keylen); end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif if (fallback) { typedef int(*sw_fun_ptr)(void *, unsigned char *, size_t , const OSSL_PARAM *); sw_fun_ptr default_prov_tls12_kdf_fun = get_default_tls12_kdf().derive; ret = default_prov_tls12_kdf_fun(ctx->sw_ctx, key, keylen, params); } return ret; } static int qat_prf_common_set_ctx_params(QAT_TLS_PRF *ctx, const OSSL_PARAM params[]) { OSSL_LIB_CTX *libctx = prov_libctx_of(ctx->provctx); if (params == NULL) return 1; if (!qat_prov_digest_load_from_params(&ctx->digest, params, libctx)) return 0; return 1; } static int qat_prov_set_macctx(EVP_MAC_CTX *macctx, const OSSL_PARAM params[], const char *ciphername, const char *mdname, const char *engine, const char *properties, const unsigned char *key, size_t keylen) { const OSSL_PARAM *p; OSSL_PARAM mac_params[6], *mp = mac_params; if (params != NULL) { if (mdname == NULL) { if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST)) != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; mdname = p->data; } } if (ciphername == NULL) { if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_CIPHER)) != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; ciphername = p->data; } } if (engine == NULL) { if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE)) != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; engine = p->data; } } } if (mdname != NULL) *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, (char *)mdname, 0); if (ciphername != NULL) *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, (char *)ciphername, 0); if (properties != NULL) *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, (char *)properties, 0); #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) if (engine != NULL) *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_ENGINE, (char *) engine, 0); #endif if (key != NULL) *mp++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (unsigned char *)key, keylen); *mp = OSSL_PARAM_construct_end(); return EVP_MAC_CTX_set_params(macctx, mac_params); } static int qat_prov_macctx_load_from_params(EVP_MAC_CTX **macctx, const OSSL_PARAM params[], const char *macname, const char *ciphername, const char *mdname, OSSL_LIB_CTX *libctx) { const OSSL_PARAM *p; const char *properties = NULL; if (macname == NULL && (p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC)) != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; macname = p->data; } if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES)) != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; properties = p->data; } /* If we got a new mac name, we make a new EVP_MAC_CTX */ if (macname != NULL) { EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties); EVP_MAC_CTX_free(*macctx); *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac); /* The context holds on to the MAC */ EVP_MAC_free(mac); if (*macctx == NULL) return 0; } /* * If there is no MAC yet (and therefore, no MAC context), we ignore * all other parameters. */ if (*macctx == NULL) return 1; if (qat_prov_set_macctx(*macctx, params, ciphername, mdname, NULL, properties, NULL, 0)) return 1; EVP_MAC_CTX_free(*macctx); *macctx = NULL; return 0; } static int qat_tls_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; QAT_TLS_PRF *ctx = (QAT_TLS_PRF *)vctx; OSSL_LIB_CTX *libctx = prov_libctx_of(ctx->provctx); int fallback = 0; if (qat_get_qat_offload_disabled()) { DEBUG("- Switched to software mode\n"); fallback = 1; goto end; } if (params == NULL) return 1; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) { if (!qat_prf_common_set_ctx_params(ctx, params)) return 0; if (strcasecmp(p->data, SN_md5_sha1) == 0) { if (!qat_prov_macctx_load_from_params(&ctx->P_hash, params, OSSL_MAC_NAME_HMAC, NULL, SN_md5, libctx) || !qat_prov_macctx_load_from_params(&ctx->P_sha1, params, OSSL_MAC_NAME_HMAC, NULL, SN_sha1, libctx)) return 0; } else { EVP_MAC_CTX_free(ctx->P_sha1); if (!qat_prov_macctx_load_from_params(&ctx->P_hash, params, OSSL_MAC_NAME_HMAC, NULL, NULL, libctx)) return 0; } } if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) { OPENSSL_clear_free(ctx->sec, ctx->seclen); ctx->sec = NULL; if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sec, 0, &ctx->seclen)) return 0; if (!qat_tls1_prf_ctrl(ctx->pctx, EVP_PKEY_CTRL_TLS_SECRET, ctx->seclen, ctx->sec)){ WARN("Failed in setting prf secret.\n"); return 0; } } /* The seed fields concatenate, so process them all */ if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) { for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_SEED)) { if (ctx->qat_userLabel_len == 0){ ctx->qat_userLabel = OPENSSL_zalloc(p->data_size + 1); if (ctx->qat_userLabel == NULL){ WARN("Zalloc error in qat_tls_prf_set_ctx_params\n"); return 0; } const void *q = ctx->qat_userLabel; size_t sz = 0; if (p->data_size != 0 && p->data != NULL && !OSSL_PARAM_get_octet_string(p, (void **)&q, TLS1_PRF_MAXBUF - ctx->seedlen, &sz)){ OPENSSL_clear_free(ctx->qat_userLabel, ctx->qat_userLabel_len); return 0; } ctx->qat_userLabel_len = sz; } else{ const void *q = ctx->seed + ctx->seedlen; size_t sz = 0; if (p->data_size != 0 && p->data != NULL && !OSSL_PARAM_get_octet_string(p, (void **)&q, TLS1_PRF_MAXBUF - ctx->seedlen, &sz)) return 0; ctx->seedlen += sz; } } } end: if (fallback) { typedef int(*sw_fun_ptr)(void *, const OSSL_PARAM *); sw_fun_ptr default_prov_tls12_kdf_fun = get_default_tls12_kdf().set_ctx_params; default_prov_tls12_kdf_fun(ctx->sw_ctx, params); } return 1; } static const OSSL_PARAM *qat_tls_prf_settable_ctx_params( ossl_unused void *ctx, ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0), OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0), OSSL_PARAM_END }; return known_settable_ctx_params; } static int qat_tls_prf_get_ctx_params(void *vctx, OSSL_PARAM params[]) { OSSL_PARAM *p; if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) return OSSL_PARAM_set_size_t(p, SIZE_MAX); return -2; } static const OSSL_PARAM *qat_tls_prf_gettable_ctx_params( ossl_unused void *ctx, ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END }; return known_gettable_ctx_params; } const OSSL_DISPATCH qat_tls_prf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))qat_tls_prf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))qat_tls_prf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))qat_tls_prf_reset }, { OSSL_FUNC_KDF_DERIVE, (void(*)(void))qat_tls_prf_derive }, { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void(*)(void))qat_tls_prf_settable_ctx_params }, { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))qat_tls_prf_set_ctx_params }, { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void(*)(void))qat_tls_prf_gettable_ctx_params }, { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))qat_tls_prf_get_ctx_params }, { 0, NULL } }; #endif /* ENABLE_QAT_HW_PRF */ qatengine-1.9.0/qat_prov_prf.h000066400000000000000000000165451500416242000163540ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_prf.h * * This file contains qatprovider interface of PRF. * *****************************************************************************/ #ifndef QAT_PROV_PRF_H # define QAT_PROV_PRF_H # ifdef ENABLE_QAT_HW_PRF # include # include # include # include # include # include # include # include # include # include "qat_hw_prf.h" # include "qat_provider.h" # include "e_qat.h" # define TLS1_PRF_MAXBUF 1024 typedef void CRYPTO_RWLOCK; struct evp_kdf_st { OSSL_PROVIDER *prov; int name_id; char *type_name; const char *description; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_kdf_newctx_fn *newctx; OSSL_FUNC_kdf_dupctx_fn *dupctx; OSSL_FUNC_kdf_freectx_fn *freectx; OSSL_FUNC_kdf_reset_fn *reset; OSSL_FUNC_kdf_derive_fn *derive; OSSL_FUNC_kdf_gettable_params_fn *gettable_params; OSSL_FUNC_kdf_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_kdf_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_kdf_get_params_fn *get_params; OSSL_FUNC_kdf_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_kdf_set_ctx_params_fn *set_ctx_params; }; typedef struct evp_kdf_st QAT_EVP_KDF; typedef struct { /* * References to the underlying digest implementation. |md| caches * the digest, always. |alloc_md| only holds a reference to an explicitly * fetched digest. */ const EVP_MD *md; /* digest */ EVP_MD *alloc_md; /* fetched digest */ /* Conditions for legacy EVP_MD uses */ ENGINE *engine; /* digest engine */ } PROV_DIGEST; /* TLS KDF kdf context structure */ typedef struct { void *provctx; PROV_DIGEST digest; /* MAC context for the main digest */ EVP_MAC_CTX *P_hash; /* MAC context for SHA1 for the MD5/SHA-1 combined PRF */ EVP_MAC_CTX *P_sha1; /* Secret value to use for PRF */ unsigned char *sec; size_t seclen; /* Buffer of concatenated seeds from seed2 to seed5 data */ unsigned char seed[TLS1_PRF_MAXBUF]; size_t seedlen; unsigned char *qat_userLabel; size_t qat_userLabel_len; EVP_PKEY_CTX *pctx; EVP_PKEY_CTX *sw_ctx; } QAT_TLS_PRF; struct evp_pkey_ctx_st { /* Actual operation */ int operation; /* * Library context, property query, keytype and keymgmt associated with * this context */ OSSL_LIB_CTX *libctx; char *propquery; const char *keytype; /* If |pkey| below is set, this field is always a reference to its keymgmt */ EVP_KEYMGMT *keymgmt; union { struct { void *genctx; } keymgmt; struct { EVP_KEYEXCH *exchange; /* * Opaque ctx returned from a providers exchange algorithm * implementation OSSL_FUNC_keyexch_newctx() */ void *algctx; } kex; struct { EVP_SIGNATURE *signature; /* * Opaque ctx returned from a providers signature algorithm * implementation OSSL_FUNC_signature_newctx() */ void *algctx; } sig; struct { EVP_ASYM_CIPHER *cipher; /* * Opaque ctx returned from a providers asymmetric cipher algorithm * implementation OSSL_FUNC_asym_cipher_newctx() */ void *algctx; } ciph; struct { EVP_KEM *kem; /* * Opaque ctx returned from a providers KEM algorithm * implementation OSSL_FUNC_kem_newctx() */ void *algctx; } encap; } op; /* * Cached parameters. Inits of operations that depend on these should * call evp_pkey_ctx_use_delayed_data() when the operation has been set * up properly. */ struct { /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */ char *dist_id_name; /* The name used with EVP_PKEY_CTX_ctrl_str() */ void *dist_id; /* The distinguishing ID itself */ size_t dist_id_len; /* The length of the distinguishing ID */ /* Indicators of what has been set. Keep them together! */ unsigned int dist_id_set : 1; } cached_parameters; /* Application specific data, usually used by the callback */ void *app_data; /* Keygen callback */ EVP_PKEY_gen_cb *pkey_gencb; /* implementation specific keygen data */ int *keygen_info; int keygen_info_count; /* Legacy fields below */ /* EVP_PKEY identity */ int legacy_keytype; /* Method associated with this operation */ const EVP_PKEY_METHOD *pmeth; /* Engine that implements this method or NULL if builtin */ ENGINE *engine; /* Key: may be NULL */ EVP_PKEY *pkey; /* Peer key for key agreement, may be NULL */ EVP_PKEY *peerkey; /* Algorithm specific data */ void *data; /* Indicator if digest_custom needs to be called */ unsigned int flag_call_digest_custom:1; /* * Used to support taking custody of memory in the case of a provider being * used with the deprecated EVP_PKEY_CTX_set_rsa_keygen_pubexp() API. This * member should NOT be used for any other purpose and should be removed * when said deprecated API is excised completely. */ BIGNUM *rsa_pubexp; } /* EVP_PKEY_CTX */ ; # endif /* ENABLE_QAT_HW_PRF */ #endif qatengine-1.9.0/qat_prov_rsa.c000066400000000000000000000157171500416242000163450ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_rsa.c * * This file provides an implementation to qatprovider RSA operations * *****************************************************************************/ #include #include #include "qat_utils.h" #include "qat_prov_rsa.h" #include "e_qat.h" #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" extern int qat_fips_key_zeroize; #endif void qat_rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo) { /* free pp and pinfo only */ BN_clear_free(pinfo->pp); OPENSSL_free(pinfo); } void qat_rsa_multip_info_free(RSA_PRIME_INFO *pinfo) { /* free a RSA_PRIME_INFO structure */ BN_clear_free(pinfo->r); BN_clear_free(pinfo->d); BN_clear_free(pinfo->t); qat_rsa_multip_info_free_ex(pinfo); } static int qat_prov_rsa_finish(RSA *rsa) { int i; RSA_PRIME_INFO *pinfo; for (i = 0; i < sk_RSA_PRIME_INFO_num(rsa->prime_infos); i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_MONT_CTX_free(pinfo->m); } BN_MONT_CTX_free(rsa->_method_mod_n); BN_MONT_CTX_free(rsa->_method_mod_p); BN_MONT_CTX_free(rsa->_method_mod_q); return 1; } int QAT_RSA_bits(const RSA *r) { return BN_num_bits(r->n); } int QAT_RSA_size(const RSA *r) { return BN_num_bytes(r->n); } int QAT_RSA_up_ref(RSA *r) { int i; # if OPENSSL_VERSION_NUMBER < 0x30200000 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) return 0; # else if (QAT_CRYPTO_UP_REF(&r->references, &i) <= 0) return 0; # endif if(i < 2) { WARN("refcount error"); return 0; } return i > 1 ? 1 : 0; } void QAT_RSA_free(RSA *r) { #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; #endif int i; if (r == NULL) return; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_DOWN_REF(&r->references, &i, r->lock); # else QAT_CRYPTO_DOWN_REF(&r->references, &i); # endif if (i > 0) return; if(i < 0) { WARN("refcount error"); return; } if (r->meth != NULL) qat_prov_rsa_finish(r); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_THREAD_lock_free(r->lock); # endif BN_free(r->n); BN_free(r->e); BN_clear_free(r->d); BN_clear_free(r->p); BN_clear_free(r->q); BN_clear_free(r->dmp1); BN_clear_free(r->dmq1); BN_clear_free(r->iqmp); RSA_PSS_PARAMS_free(r->pss); sk_RSA_PRIME_INFO_pop_free(r->prime_infos, qat_rsa_multip_info_free); BN_BLINDING_free(r->blinding); BN_BLINDING_free(r->mt_blinding); OPENSSL_free(r); #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif } int QAT_RSA_test_flags(const RSA *r, int flags) { return r->flags & flags; } void QAT_RSA_clear_flags(RSA *r, int flags) { r->flags &= ~flags; } void QAT_RSA_set_flags(RSA *r, int flags) { r->flags |= flags; } const BIGNUM *QAT_RSA_get0_n(const RSA *r) { return r->n; } const BIGNUM *QAT_RSA_get0_e(const RSA *r) { return r->e; } const BIGNUM *QAT_RSA_get0_d(const RSA *r) { return r->d; } int QAT_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) { /* If the fields p and q in r are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) return 0; if (p != NULL) { BN_clear_free(r->p); r->p = p; BN_set_flags(r->p, BN_FLG_CONSTTIME); } if (q != NULL) { BN_clear_free(r->q); r->q = q; BN_set_flags(r->q, BN_FLG_CONSTTIME); } r->dirty_cnt++; return 1; } int QAT_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((r->dmp1 == NULL && dmp1 == NULL) || (r->dmq1 == NULL && dmq1 == NULL) || (r->iqmp == NULL && iqmp == NULL)) return 0; if (dmp1 != NULL) { BN_clear_free(r->dmp1); r->dmp1 = dmp1; BN_set_flags(r->dmp1, BN_FLG_CONSTTIME); } if (dmq1 != NULL) { BN_clear_free(r->dmq1); r->dmq1 = dmq1; BN_set_flags(r->dmq1, BN_FLG_CONSTTIME); } if (iqmp != NULL) { BN_clear_free(r->iqmp); r->iqmp = iqmp; BN_set_flags(r->iqmp, BN_FLG_CONSTTIME); } r->dirty_cnt++; return 1; } int QAT_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { /* If the fields n and e in r are NULL, the corresponding input * parameters MUST be non-NULL for n and e. d may be * left NULL (in case only the public key is used). */ if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) return 0; if (n != NULL) { BN_free(r->n); r->n = n; } if (e != NULL) { BN_free(r->e); r->e = e; } if (d != NULL) { BN_clear_free(r->d); r->d = d; BN_set_flags(r->d, BN_FLG_CONSTTIME); } r->dirty_cnt++; return 1; } #endif qatengine-1.9.0/qat_prov_rsa.h000066400000000000000000000212641500416242000163440ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_rsa.h * * This file provides an interface to qatprovider RSA operations * *****************************************************************************/ #ifndef QAT_PROVIDER_RSA_H # define QAT_PROVIDER_RSA_H #include #include #include #include "e_qat.h" typedef struct{ int hash_algorithm_nid; struct { int algorithm_nid; /* Currently always NID_mgf1 */ int hash_algorithm_nid; } mask_gen; int salt_len; int trailer_field; } QAT_RSA_PSS_PARAMS_30; struct rsa_st{ /* * #legacy * The first field is used to pickup errors where this is passed * instead of an EVP_PKEY. It is always zero. * THIS MUST REMAIN THE FIRST FIELD. */ int dummy_zero; OSSL_LIB_CTX *libctx; int32_t version; const RSA_METHOD *meth; /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; BIGNUM *n; BIGNUM *e; BIGNUM *d; BIGNUM *p; BIGNUM *q; BIGNUM *dmp1; BIGNUM *dmq1; BIGNUM *iqmp; /* * If a PSS only key this contains the parameter restrictions. * There are two structures for the same thing, used in different cases. */ /* This is used uniquely by OpenSSL provider implementations. */ QAT_RSA_PSS_PARAMS_30 pss_params; /* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */ RSA_PSS_PARAMS *pss; /* for multi-prime RSA, defined in RFC 8017 */ STACK_OF(RSA_PRIME_INFO) *prime_infos; /* Be careful using this if the RSA structure is shared */ CRYPTO_EX_DATA ex_data; CRYPTO_REF_COUNT references; //CRYPTO_REF_COUNT references; int flags; /* Used to cache montgomery values */ BN_MONT_CTX *_method_mod_n; BN_MONT_CTX *_method_mod_p; BN_MONT_CTX *_method_mod_q; BN_BLINDING *blinding; BN_BLINDING *mt_blinding; # if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif int dirty_cnt; }; typedef struct rsa_st RSA; struct rsa_meth_st { char *name; int (*rsa_pub_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int (*rsa_pub_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int (*rsa_priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int (*rsa_priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); /* Can be null */ int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); /* Can be null */ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); /* called at new */ int (*init) (RSA *rsa); /* called at free */ int (*finish) (RSA *rsa); /* RSA_METHOD_FLAG_* things */ int flags; /* may be needed! */ char *app_data; /* * New sign and verify functions: some libraries don't allow arbitrary * data to be signed/verified: this allows them to be used. Note: for * this to work the RSA_public_decrypt() and RSA_private_encrypt() should * *NOT* be used. RSA_sign(), RSA_verify() should be used instead. */ int (*rsa_sign) (int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa); int (*rsa_verify) (int dtype, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); /* * If this callback is NULL, the builtin software RSA key-gen will be * used. This is for behavioural compatibility whilst the code gets * rewired, but one day it would be nice to assume there are no such * things as "builtin software" implementations. */ int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); int (*rsa_multi_prime_keygen) (RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb); }; typedef struct rsa_meth_st RSA_METHOD; typedef struct { OSSL_LIB_CTX *libctx; RSA *rsa; int pad_mode; int operation; /* OAEP message digest */ EVP_MD *oaep_md; /* message digest for MGF1 */ EVP_MD *mgf1_md; /* OAEP label */ unsigned char *oaep_label; size_t oaep_labellen; /* TLS padding */ unsigned int client_version; unsigned int alt_version; /* PKCS#1 v1.5 decryption mode */ unsigned int implicit_rejection; } QAT_PROV_RSA_ENC_DEC_CTX; typedef struct { OSSL_LIB_CTX *libctx; char *propq; RSA *rsa; int operation; /* * Flag to determine if the hash function can be changed (1) or not (0) * Because it's dangerous to change during a DigestSign or DigestVerify * operation, this flag is cleared by their Init function, and set again * by their Final function. */ unsigned int flag_allow_md : 1; unsigned int mgf1_md_set : 1; /* main digest */ EVP_MD *md; EVP_MD_CTX *mdctx; int mdnid; char mdname[50]; /* Purely informational */ /* RSA padding mode */ int pad_mode; /* message digest for MGF1 */ EVP_MD *mgf1_md; int mgf1_mdnid; char mgf1_mdname[50]; /* Purely informational */ /* PSS salt length */ int saltlen; /* Minimum salt length or -1 if no PSS parameter restriction */ int min_saltlen; /* Temp buffer */ unsigned char *tbuf; /* OAEP message digest */ EVP_MD *oaep_md; /* OAEP label */ unsigned char *oaep_label; size_t oaep_labellen; /* TLS padding */ unsigned int client_version; unsigned int alt_version; } QAT_PROV_RSA_CTX; typedef struct rsa_prime_info_st { BIGNUM *r; BIGNUM *d; BIGNUM *t; /* save product of primes prior to this one */ BIGNUM *pp; BN_MONT_CTX *m; } RSA_PRIME_INFO; DEFINE_STACK_OF(RSA_PRIME_INFO) void qat_rsa_multip_info_free_ex(RSA_PRIME_INFO *pinfo); void qat_rsa_multip_info_free(RSA_PRIME_INFO *pinfo); int QAT_RSA_bits(const RSA *r); int QAT_RSA_size(const RSA *r); void QAT_RSA_set_flags(RSA *r, int flags); void QAT_RSA_clear_flags(RSA *r, int flags); int QAT_RSA_test_flags(const RSA *r, int flags); const BIGNUM *QAT_RSA_get0_n(const RSA *r); const BIGNUM *QAT_RSA_get0_e(const RSA *r); const BIGNUM *QAT_RSA_get0_d(const RSA *r); int QAT_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); int QAT_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); int QAT_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); int QAT_RSA_up_ref(RSA *r); void QAT_RSA_free(RSA *r); int QAT_PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen, const EVP_MD *dgst); #endif /* QAT_PROVIDER_RSA_H */ qatengine-1.9.0/qat_prov_rsa_enc_dec.c000066400000000000000000001020521500416242000177720ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2024-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_rsa_enc_dec.c * * This file provides an implementation to qatprovider RSA Encryption and Decryption operations * *****************************************************************************/ # include # include # include # include # include # include # include # include # include # include # include "e_qat.h" # include "qat_provider.h" # include "qat_prov_rsa.h" # include "qat_utils.h" # include "qat_constant_time.h" # ifdef QAT_HW # include "qat_hw_rsa.h" # endif #ifdef QAT_SW #include "qat_sw_rsa.h" #endif # define QAT_MAX_NAME_SIZE 50/* Algorithm name */ # define QAT_MAX_PROPQUERY_SIZE 256/* Property query strings */ #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) static OSSL_ITEM qat_padding_item[] = { {RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15}, {RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE}, {RSA_PKCS1_OAEP_PADDING, OSSL_PKEY_RSA_PAD_MODE_OAEP}, {RSA_PKCS1_OAEP_PADDING, "oeap"}, {RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931}, {0, NULL} }; static void *qat_prov_rsa_newctx(void *provctx); static int qat_prov_rsa_encrypt_init(void *ctx, void *rsa, const OSSL_PARAM params[]); static int qat_prov_rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen); static int qat_prov_rsa_decrypt_init(void *ctx, void *rsa, const OSSL_PARAM params[]); static int qat_prov_rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen); static void qat_prov_rsa_freectx(void *vprsactx); static void *qat_prov_rsa_dupctx(void *vprsactx); static int qat_prov_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM * params); static const OSSL_PARAM *qat_prov_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx); static int qat_prov_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]); static const OSSL_PARAM *qat_prov_rsa_settable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx); typedef struct qat_evp_asym_cipher_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT refcnt; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_asym_cipher_newctx_fn *newctx; OSSL_FUNC_asym_cipher_encrypt_init_fn *encrypt_init; OSSL_FUNC_asym_cipher_encrypt_fn *encrypt; OSSL_FUNC_asym_cipher_decrypt_init_fn *decrypt_init; OSSL_FUNC_asym_cipher_decrypt_fn *decrypt; OSSL_FUNC_asym_cipher_freectx_fn *freectx; OSSL_FUNC_asym_cipher_dupctx_fn *dupctx; OSSL_FUNC_asym_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_asym_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_asym_cipher_settable_ctx_params_fn *settable_ctx_params; } QAT_EVP_ASYM_CIPHER; static QAT_EVP_ASYM_CIPHER get_default_rsa_asym_cipher() { static QAT_EVP_ASYM_CIPHER s_asym_cipher; static int initilazed = 0; if (!initilazed) { QAT_EVP_ASYM_CIPHER *asym_cipher = (QAT_EVP_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, "RSA", "provider=default"); if (asym_cipher) { s_asym_cipher = *asym_cipher; EVP_ASYM_CIPHER_free((EVP_ASYM_CIPHER *)asym_cipher); initilazed = 1; } else { WARN("EVP_ASYM_CIPHER_fetch from default provider failed"); } } return s_asym_cipher; } static void *qat_prov_rsa_newctx(void *provctx) { QAT_PROV_RSA_ENC_DEC_CTX *ctx; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(QAT_PROV_RSA_ENC_DEC_CTX)); if (ctx == NULL) return NULL; ctx->libctx = prov_libctx_of(provctx); return ctx; } int qat_rsa_check_key(OSSL_LIB_CTX * ctx, const RSA *rsa, int operation) { int protect = 0; switch (operation) { case EVP_PKEY_OP_SIGN: protect = 1; case EVP_PKEY_OP_VERIFY: break; case EVP_PKEY_OP_ENCAPSULATE: case EVP_PKEY_OP_ENCRYPT: protect = 1; case EVP_PKEY_OP_VERIFYRECOVER: case EVP_PKEY_OP_DECAPSULATE: case EVP_PKEY_OP_DECRYPT: if (QAT_RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSASSAPSS) { QATerr(ERR_LIB_PROV, QAT_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } break; default: QATerr(ERR_LIB_PROV, QAT_R_INTERNAL_ERROR); return 0; } # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) if (qat_securitycheck_enabled(ctx)) { int sz = QAT_RSA_bits(rsa); if (protect ? (sz < 2048) : (sz < 1024)) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_KEY_LENGTH); return 0; } } # else (void)protect; # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ return 1; } int qat_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX * libctx, unsigned char *to, int tlen, const unsigned char *from, int flen, const unsigned char *param, int plen, const EVP_MD *md, const EVP_MD *mgf1md) { int rv = 0; int i, emlen = tlen - 1; unsigned char *db, *seed; unsigned char *dbmask = NULL; unsigned char seedmask[EVP_MAX_MD_SIZE]; int mdlen, dbmask_len = 0; if (md == NULL) { md = EVP_sha1(); } if (mgf1md == NULL) mgf1md = md; mdlen = EVP_MD_get_size(md); if (mdlen <= 0) { QATerr(ERR_LIB_RSA, QAT_R_INVALID_LENGTH); return 0; } if (flen > emlen - 2 * mdlen - 1) { QATerr(ERR_LIB_RSA, QAT_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return 0; } if (emlen < 2 * mdlen + 1) { QATerr(ERR_LIB_RSA, QAT_R_KEY_SIZE_TOO_SMALL); return 0; } to[0] = 0; seed = to + 1; db = to + mdlen + 1; if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) goto err; memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); db[emlen - flen - mdlen - 1] = 0x01; memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); if (RAND_bytes_ex(libctx, seed, mdlen, 0) <= 0) goto err; dbmask_len = emlen - mdlen; dbmask = OPENSSL_malloc(dbmask_len); if (dbmask == NULL) { QATerr(ERR_LIB_RSA, QAT_R_MALLOC_FAILURE); goto err; } if (QAT_PKCS1_MGF1(dbmask, dbmask_len, seed, mdlen, mgf1md) < 0) goto err; for (i = 0; i < dbmask_len; i++) db[i] ^= dbmask[i]; if (QAT_PKCS1_MGF1(seedmask, mdlen, db, dbmask_len, mgf1md) < 0) goto err; for (i = 0; i < mdlen; i++) seed[i] ^= seedmask[i]; rv = 1; err: OPENSSL_cleanse(seedmask, sizeof(seedmask)); OPENSSL_clear_free(dbmask, dbmask_len); return rv; } /****************************************************************************** * * function: * qat_rsa_public_encrypt(int flen, const unsigned char *from, * unsigned char *to, RSA *rsa, int padding) * * qat_rsa_public_encrypt - RSA public key encryption using QAT engine. * * @param flen [IN] - Length of the input data (in bytes) to be encrypted. * @param from [IN] - Pointer to the input data to be encrypted. * @param to [IN] - Pointer to the output buffer. * @param rsa [IN] - RSA key structure containing the public key. * @param padding [IN] - Padding mode to be used for encryption. * * description: * This function performs RSA public key encryption. Depending on the * configuration, it may offload the encryption operation to hardware (QAT) * or software (QAT_SW) if offloading is enabled. The result is stored in * the output buffer provided. * * returns: * - The size of the decrypted data on success. * - 0 or a negative value on error. ******************************************************************************/ static int qat_rsa_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int ret = 0; #ifdef ENABLE_QAT_HW_RSA if (qat_hw_rsa_offload) ret = qat_rsa_pub_enc(flen, from, to, rsa, padding); #endif #ifdef ENABLE_QAT_SW_RSA if (qat_sw_rsa_offload) ret = multibuff_rsa_pub_enc(flen, from, to, rsa, padding); #endif return ret; } /****************************************************************************** * * function: * qat_rsa_private_decrypt(int flen, const unsigned char *from, * unsigned char *to, RSA *rsa, int padding) * * qat_rsa_private_decrypt - RSA private key decryption using QAT engine. * * @param flen [IN] - Length of the encrypted input data to be decrypted. * @param from [IN] - Pointer to the encrypted input data. * @param to [IN] - Pointer to the output buffer. * @param rsa [IN] - RSA key structure containing the private key. * @param padding [IN] - Padding mode to be used for decryption. * * description: * This function performs RSA private key decryption. Depending on the * configuration, it may offload the decryption operation to hardware (QAT) * or software (QAT_SW) if offloading is enabled. The result is * stored in the output buffer provided. * * returns: * - The size of the decrypted data on success. * - 0 or a negative value on error. ******************************************************************************/ static int qat_rsa_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int ret = 0; #ifdef ENABLE_QAT_HW_RSA if (qat_hw_rsa_offload) ret = qat_rsa_priv_dec(flen, from, to, rsa, padding); #endif #ifdef ENABLE_QAT_SW_RSA if (qat_sw_rsa_offload) ret = multibuff_rsa_priv_dec(flen, from, to, rsa, padding); #endif return ret; } static int qat_prov_rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { QAT_PROV_RSA_ENC_DEC_CTX *ctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; int ret; if (!qat_prov_is_running()) return 0; if (out == NULL) { size_t len = QAT_RSA_size(ctx->rsa); if (len == 0) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_KEY); return 0; } *outlen = len; return 1; } if (ctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { int rsasize = QAT_RSA_size(ctx->rsa); unsigned char *tbuf; if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) { QATerr(ERR_LIB_PROV, QAT_R_MALLOC_FAILURE); return 0; } if (ctx->oaep_md == NULL) { ctx->oaep_md = EVP_MD_fetch(ctx->libctx, "SHA-1", NULL); if (ctx->oaep_md == NULL) { OPENSSL_free(tbuf); QATerr(ERR_LIB_PROV, QAT_R_INTERNAL_ERROR); return 0; } } ret = qat_rsa_padding_add_PKCS1_OAEP_mgf1_ex(ctx->libctx, tbuf, rsasize, in, inlen, ctx->oaep_label, ctx->oaep_labellen, ctx->oaep_md, ctx->mgf1_md); if (!ret) { OPENSSL_free(tbuf); return 0; } if (qat_hw_rsa_offload || qat_sw_rsa_offload) { ret = qat_rsa_public_encrypt(rsasize, tbuf, out, ctx->rsa, RSA_NO_PADDING); } else { typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen); fun_ptr fun = get_default_rsa_asym_cipher().encrypt; if (!fun) return 0; return fun(vprsactx, out, outlen, outsize, in, inlen); } OPENSSL_free(tbuf); } else { if (qat_hw_rsa_offload || qat_sw_rsa_offload) { ret = qat_rsa_public_encrypt(inlen, in, out, ctx->rsa, ctx->pad_mode); } else { typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen); fun_ptr fun = get_default_rsa_asym_cipher().encrypt; if (!fun) return 0; return fun(vprsactx, out, outlen, outsize, in, inlen); } } if (ret < 0) return ret; *outlen = ret; return 1; } int qat_rsa_padding_check_PKCS1_type_2_TLS(OSSL_LIB_CTX * libctx, unsigned char *to, size_t tlen, const unsigned char *from, size_t flen, int client_version, int alt_version) { unsigned int i, good, version_good; unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; /* * If these checks fail then either the message in publicly invalid, or * we've been called incorrectly. We can fail immediately. */ if (flen < RSA_PKCS1_PADDING_SIZE + SSL_MAX_MASTER_KEY_LENGTH || tlen < SSL_MAX_MASTER_KEY_LENGTH) { QATerr(ERR_LIB_RSA, QAT_R_PKCS_DECODING_ERROR); return -1; } /* * Generate a random premaster secret to use in the event that we fail * to decrypt. */ if (RAND_priv_bytes_ex(libctx, rand_premaster_secret, sizeof(rand_premaster_secret), 0) <= 0) { QATerr(ERR_LIB_RSA, QAT_R_INTERNAL_ERROR); return -1; } good = qat_constant_time_is_zero(from[0]); good &= qat_constant_time_eq(from[1], 2); for (i = 2; i < flen - SSL_MAX_MASTER_KEY_LENGTH - 1; i++) good &= ~qat_constant_time_is_zero_8(from[i]); good &= qat_constant_time_is_zero_8(from[flen - SSL_MAX_MASTER_KEY_LENGTH - 1]); version_good = qat_constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH], (client_version >> 8) & 0xff); version_good &= qat_constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH + 1], client_version & 0xff); if (alt_version > 0) { unsigned int workaround_good; workaround_good = qat_constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH], (alt_version >> 8) & 0xff); workaround_good &= qat_constant_time_eq(from[flen - SSL_MAX_MASTER_KEY_LENGTH + 1], alt_version & 0xff); version_good |= workaround_good; } good &= version_good; for (i = 0; i < SSL_MAX_MASTER_KEY_LENGTH; i++) { to[i] = qat_constant_time_select_8(good, from[flen - SSL_MAX_MASTER_KEY_LENGTH + i], rand_premaster_secret[i]); } return SSL_MAX_MASTER_KEY_LENGTH; } static int qat_prov_rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { QAT_PROV_RSA_ENC_DEC_CTX *ctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; int ret; size_t len = QAT_RSA_size(ctx->rsa); if (!qat_prov_is_running()) return 0; if (ctx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { if (out == NULL) { *outlen = SSL_MAX_MASTER_KEY_LENGTH; return 1; } if (outsize < SSL_MAX_MASTER_KEY_LENGTH) { QATerr(ERR_LIB_PROV, QAT_R_BAD_LENGTH); return 0; } } else { if (out == NULL) { if (len == 0) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_KEY); return 0; } *outlen = len; return 1; } if (outsize < len) { QATerr(ERR_LIB_PROV, QAT_R_BAD_LENGTH); return 0; } } if (ctx->pad_mode == RSA_PKCS1_OAEP_PADDING || ctx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { unsigned char *tbuf; if ((tbuf = OPENSSL_malloc(len)) == NULL) { QATerr(ERR_LIB_PROV, QAT_R_MALLOC_FAILURE); return 0; } if (qat_hw_rsa_offload || qat_sw_rsa_offload) { ret = qat_rsa_private_decrypt(inlen, in, tbuf, ctx->rsa, RSA_NO_PADDING); } else { typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen); fun_ptr fun = get_default_rsa_asym_cipher().decrypt; if (!fun) return 0; return fun(vprsactx, out, outlen, outsize, in, inlen); } /* * With no padding then, on success ret should be len, otherwise an * error occurred (non-constant time) */ if (ret != (int)len) { OPENSSL_free(tbuf); QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_DECRYPT); return 0; } if (ctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { if (ctx->oaep_md == NULL) { ctx->oaep_md = EVP_MD_fetch(ctx->libctx, "SHA-1", NULL); if (ctx->oaep_md == NULL) { OPENSSL_free(tbuf); QATerr(ERR_LIB_PROV, QAT_R_INTERNAL_ERROR); return 0; } } ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, outsize, tbuf, len, len, ctx->oaep_label, ctx->oaep_labellen, ctx->oaep_md, ctx->mgf1_md); } else { if (ctx->client_version <= 0) { QATerr(ERR_LIB_PROV, QAT_R_BAD_TLS_CLIENT_VERSION); OPENSSL_free(tbuf); return 0; } ret = qat_rsa_padding_check_PKCS1_type_2_TLS(ctx->libctx, out, outsize, tbuf, len, ctx->client_version, ctx->alt_version); } OPENSSL_free(tbuf); } else { if (qat_hw_rsa_offload || qat_sw_rsa_offload) { ret = qat_rsa_private_decrypt(inlen, in, out, ctx->rsa, ctx->pad_mode); } else { typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen); fun_ptr fun = get_default_rsa_asym_cipher().decrypt; if (!fun) return 0; return fun(vprsactx, out, outlen, outsize, in, inlen); } } *outlen = qat_constant_time_select_s(qat_constant_time_msb_s(ret), *outlen, ret); ret = qat_constant_time_select_int(qat_constant_time_msb(ret), 0, 1); return ret; } static void qat_prov_rsa_freectx(void *vprsactx) { QAT_PROV_RSA_ENC_DEC_CTX *ctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; QAT_RSA_free(ctx->rsa); EVP_MD_free(ctx->oaep_md); EVP_MD_free(ctx->mgf1_md); OPENSSL_free(ctx->oaep_label); OPENSSL_free(ctx); } static void *qat_prov_rsa_dupctx(void *vprsactx) { QAT_PROV_RSA_ENC_DEC_CTX *srcctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; QAT_PROV_RSA_ENC_DEC_CTX *dstctx; if (!qat_prov_is_running()) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; *dstctx = *srcctx; if (dstctx->rsa != NULL && !QAT_RSA_up_ref(dstctx->rsa)) { OPENSSL_free(dstctx); return NULL; } if (dstctx->oaep_md != NULL && !EVP_MD_up_ref(dstctx->oaep_md)) { QAT_RSA_free(dstctx->rsa); OPENSSL_free(dstctx); return NULL; } if (dstctx->mgf1_md != NULL && !EVP_MD_up_ref(dstctx->mgf1_md)) { QAT_RSA_free(dstctx->rsa); EVP_MD_free(dstctx->oaep_md); OPENSSL_free(dstctx); return NULL; } return dstctx; } static int qat_prov_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM * params) { QAT_PROV_RSA_ENC_DEC_CTX *ctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; OSSL_PARAM *p; if (ctx == NULL) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); if (p != NULL) switch (p->data_type) { case OSSL_PARAM_INTEGER: if (!OSSL_PARAM_set_int(p, ctx->pad_mode)) return 0; break; case OSSL_PARAM_UTF8_STRING: { int i; char *word = NULL; for (i = 0; qat_padding_item[i].id != 0; i++) { if (ctx->pad_mode == (int)qat_padding_item[i].id) { word = qat_padding_item[i].ptr; break; } } if (word != NULL) { if (!OSSL_PARAM_set_utf8_string(p, word)) return 0; } else { QATerr(ERR_LIB_PROV, QAT_R_INTERNAL_ERROR); } } break; default: return 0; } p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, ctx->oaep_md == NULL ? "" : EVP_MD_get0_name(ctx-> oaep_md))) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST); if (p != NULL) { EVP_MD *mgf1_md = ctx->mgf1_md == NULL ? ctx->oaep_md : ctx->mgf1_md; if (!OSSL_PARAM_set_utf8_string(p, mgf1_md == NULL ? "" : EVP_MD_get0_name(mgf1_md))) return 0; } p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL); if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, ctx->oaep_label, ctx->oaep_labellen)) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->client_version)) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->alt_version)) return 0; return 1; } static const OSSL_PARAM qat_rsa_known_gettable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_DEFN(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR, NULL, 0), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), OSSL_PARAM_END }; static const OSSL_PARAM *qat_prov_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx) { return qat_rsa_known_gettable_ctx_params; } static int qat_prov_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { QAT_PROV_RSA_ENC_DEC_CTX *ctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; const OSSL_PARAM *p; char mdname[QAT_MAX_NAME_SIZE]; char mdprops[QAT_MAX_PROPQUERY_SIZE] = { '\0' }; char *str = NULL; if (ctx == NULL) return 0; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); if (p != NULL) { str = mdname; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname))) return 0; p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS); if (p != NULL) { str = mdprops; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) return 0; } EVP_MD_free(ctx->oaep_md); ctx->oaep_md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); if (ctx->oaep_md == NULL) return 0; } p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); if (p != NULL) { int pad_mode = 0; switch (p->data_type) { case OSSL_PARAM_INTEGER: if (!OSSL_PARAM_get_int(p, &pad_mode)) return 0; break; case OSSL_PARAM_UTF8_STRING: { int i; if (p->data == NULL) return 0; for (i = 0; qat_padding_item[i].id != 0; i++) { if (strcmp(p->data, qat_padding_item[i].ptr) == 0) { pad_mode = qat_padding_item[i].id; break; } } } break; default: return 0; } if (pad_mode == RSA_PKCS1_PSS_PADDING) return 0; if (pad_mode == RSA_PKCS1_OAEP_PADDING && ctx->oaep_md == NULL) { ctx->oaep_md = EVP_MD_fetch(ctx->libctx, "SHA1", mdprops); if (ctx->oaep_md == NULL) return 0; } ctx->pad_mode = pad_mode; } p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST); if (p != NULL) { str = mdname; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname))) return 0; p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS); if (p != NULL) { str = mdprops; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) return 0; } else { str = NULL; } EVP_MD_free(ctx->mgf1_md); ctx->mgf1_md = EVP_MD_fetch(ctx->libctx, mdname, str); if (ctx->mgf1_md == NULL) return 0; } p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL); if (p != NULL) { void *tmp_label = NULL; size_t tmp_labellen; if (!OSSL_PARAM_get_octet_string(p, &tmp_label, 0, &tmp_labellen)) return 0; OPENSSL_free(ctx->oaep_label); ctx->oaep_label = (unsigned char *)tmp_label; ctx->oaep_labellen = tmp_labellen; } p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION); if (p != NULL) { unsigned int client_version; if (!OSSL_PARAM_get_uint(p, &client_version)) return 0; ctx->client_version = client_version; } p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION); if (p != NULL) { unsigned int alt_version; if (!OSSL_PARAM_get_uint(p, &alt_version)) return 0; ctx->alt_version = alt_version; } return 1; } static const OSSL_PARAM qat_rsa_known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, NULL, 0), OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), OSSL_PARAM_END }; static const OSSL_PARAM *qat_prov_rsa_settable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx) { return qat_rsa_known_settable_ctx_params; } static int qat_prov_rsa_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[], int operation) { QAT_PROV_RSA_ENC_DEC_CTX *ctx = (QAT_PROV_RSA_ENC_DEC_CTX *) vprsactx; if (!qat_prov_is_running() || ctx == NULL || vrsa == NULL) return 0; if (!qat_rsa_check_key(ctx->libctx, vrsa, operation)) return 0; if (!QAT_RSA_up_ref(vrsa)) return 0; QAT_RSA_free(ctx->rsa); ctx->rsa = vrsa; ctx->operation = operation; switch (QAT_RSA_test_flags(ctx->rsa, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: ctx->pad_mode = RSA_PKCS1_PADDING; break; default: QATerr(ERR_LIB_PROV, QAT_R_INTERNAL_ERROR); return 0; } return qat_prov_rsa_set_ctx_params(ctx, params); } static int qat_prov_rsa_encrypt_init(void *ctx, void *rsa, const OSSL_PARAM params[]) { return qat_prov_rsa_init(ctx, rsa, params, EVP_PKEY_OP_ENCRYPT); } static int qat_prov_rsa_decrypt_init(void *ctx, void *rsa, const OSSL_PARAM params[]) { return qat_prov_rsa_init(ctx, rsa, params, EVP_PKEY_OP_DECRYPT); } const OSSL_DISPATCH qat_rsa_asym_cipher_functions[] = { {OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))qat_prov_rsa_newctx}, {OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))qat_prov_rsa_encrypt_init}, {OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))qat_prov_rsa_encrypt}, {OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))qat_prov_rsa_decrypt_init}, {OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))qat_prov_rsa_decrypt}, {OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))qat_prov_rsa_freectx}, {OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))qat_prov_rsa_dupctx}, {OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS, (void (*)(void))qat_prov_rsa_get_ctx_params}, {OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))qat_prov_rsa_gettable_ctx_params}, {OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS, (void (*)(void))qat_prov_rsa_set_ctx_params}, {OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))qat_prov_rsa_settable_ctx_params}, {0, NULL} }; #endif /* ENABLE_QAT_HW_RSA */ qatengine-1.9.0/qat_prov_sha2.c000066400000000000000000000266001500416242000164060ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sha2.c * * This file provides an implementation to qatprovider SHA2 operations * *****************************************************************************/ #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) # include # include # include # include # include # include # include "qat_sw_sha2.h" # include "qat_provider.h" # include "qat_utils.h" # include "qat_evp.h" # include "e_qat.h" /* * Forward declaration of any unique methods implemented here. This is not strictly * necessary for the compiler, but provides an assurance that the signatures * of the functions in the dispatch table are correct. */ static OSSL_FUNC_digest_init_fn qat_sha2_init; static OSSL_FUNC_digest_update_fn qat_sha2_update; static OSSL_FUNC_digest_final_fn qat_sha2_final; static int qat_sha2_init(void *vctx, ossl_unused const OSSL_PARAM params[]) { QAT_SHA2_CTX *ctx = (QAT_SHA2_CTX *) vctx; if (!qat_prov_is_running()) return 0; /* The newctx() handles most of the ctx fixed setup. */ memset(ctx->h, 0, sizeof(ctx->h)); if (!mb_qat_SHA2_init(ctx)) { WARN("QAT sha2 ctx init failed!\n"); return 0; } return 1; } static int qat_sha2_update(void *vctx, const unsigned char *inp, size_t len) { # ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; # endif QAT_SHA2_CTX *ctx = (QAT_SHA2_CTX *) vctx; if (!qat_prov_is_running()) return 0; return mb_qat_SHA2_update(ctx, inp, len); # ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; # endif } static int qat_sha2_final(void *vctx, unsigned char *out, size_t *outl, size_t outsz) { # ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; # endif int ret = 1; QAT_SHA2_CTX *ctx = (QAT_SHA2_CTX *) vctx; if (!qat_prov_is_running()) return 0; *outl = ctx->md_size; if (outsz > 0) { ret = mb_qat_SHA2_final(ctx, out); } # ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; # endif return ret; } static const OSSL_PARAM qat_sha2_default_known_gettable_params[] = { OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_SIZE, NULL), OSSL_PARAM_int(OSSL_DIGEST_PARAM_XOF, NULL), OSSL_PARAM_int(OSSL_DIGEST_PARAM_ALGID_ABSENT, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_sha2_default_gettable_params(void *provctx) { return qat_sha2_default_known_gettable_params; } static int qat_sha2_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz, unsigned long flags) { OSSL_PARAM *p = NULL; p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blksz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, paramsz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOF); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_DIGEST_FLAG_XOF) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_ALGID_ABSENT); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_DIGEST_FLAG_ALGID_ABSENT) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static void set_ctx_md_type(QAT_SHA2_CTX *ctx, int bitlen) { switch (bitlen) { case 224: ctx->md_type = NID_sha224; break; case 256: ctx->md_type = NID_sha256; break; case 384: ctx->md_type = NID_sha384; break; case 512: ctx->md_type = NID_sha512; break; } } # define PROV_DISPATCH_FUNC_SHA2_GET_PARAMS(name) \ { OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))qat_##name##_get_params }, \ { OSSL_FUNC_DIGEST_GETTABLE_PARAMS, \ (void (*)(void))qat_sha2_default_gettable_params } # define PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END \ { 0, NULL } \ }; # define PROV_FUNC_SHA2_GET_PARAM(name, blksize, dgstsize, flags) \ static OSSL_FUNC_digest_get_params_fn qat_##name##_get_params; \ static int qat_##name##_get_params(OSSL_PARAM params[]) \ { \ return qat_sha2_default_get_params(params, blksize, dgstsize, flags); \ } # define PROV_DISPATCH_FUNC_DIGEST_FREE_DUP(name, blksize) \ static void qat_##name##_freectx(void *vctx) \ { \ QAT_SHA2_CTX *ctx = (QAT_SHA2_CTX *)vctx; \ \ mb_qat_sha2_cleanup(ctx); \ \ } \ static void *qat_##name##_dupctx(void *ctx) \ { \ QAT_SHA2_CTX *in = (QAT_SHA2_CTX *)ctx; \ QAT_SHA2_CTX *ret = qat_prov_is_running() ? \ OPENSSL_malloc(sizeof(*ret)) \ : NULL; \ if (ret != NULL) \ *ret = *in; \ return ret; \ } # define PROV_FUNC_SHA2_COMMON(name, bitlen, blksize, dgstsize, flags) \ PROV_FUNC_SHA2_GET_PARAM(name, blksize, dgstsize, flags) \ PROV_DISPATCH_FUNC_DIGEST_FREE_DUP(name, blksize) \ const OSSL_DISPATCH qat_##name##_functions[] = { \ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))qat_##name##_newctx }, \ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))qat_sha2_update }, \ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))qat_sha2_final }, \ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))qat_##name##_freectx }, \ { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))qat_##name##_dupctx }, \ PROV_DISPATCH_FUNC_SHA2_GET_PARAMS(name) # define PROV_FUNC_SHA2(name, bitlen, blksize, dgstsize, flags) \ PROV_FUNC_SHA2_COMMON(name, bitlen, blksize, dgstsize, flags), \ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))qat_sha2_init }, \ PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END # define SHA2_NEW_CTX(name, bitlen, blksize, dgstsize, pad_val, sha_name) \ static OSSL_FUNC_digest_newctx_fn qat_##name##_newctx; \ static void *qat_##name##_newctx(void *provctx) \ { \ QAT_SHA2_CTX *ctx = qat_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ : NULL; \ \ if (ctx == NULL) \ return NULL; \ \ set_ctx_md_type(ctx, bitlen); \ ctx->block_size = blksize; \ ctx->md_size = dgstsize; \ return ctx; \ } \ # define QAT_PROVIDER_SHA2_IMPLEMENTION(bitlen, blksize, dgstsize, flags, \ sha_name) \ SHA2_NEW_CTX(sha##bitlen, bitlen, blksize, dgstsize, '\x06', sha_name) \ PROV_FUNC_SHA2(sha##bitlen, bitlen, blksize, dgstsize, flags) /* qat_sha224_functions */ QAT_PROVIDER_SHA2_IMPLEMENTION(224, QAT_SHA256_CBLOCK, QAT_SHA224_DIGEST_LENGTH, SHA2_FLAGS, "SHA-224") /* qat_sha256_functions */ QAT_PROVIDER_SHA2_IMPLEMENTION(256, QAT_SHA256_CBLOCK, QAT_SHA256_DIGEST_LENGTH, SHA2_FLAGS, "SHA2-256") /* qat_sha384_functions */ QAT_PROVIDER_SHA2_IMPLEMENTION(384, QAT_SHA512_CBLOCK, QAT_SHA384_DIGEST_LENGTH, SHA2_FLAGS, "SHA-384") /* qat_sha512_functions */ QAT_PROVIDER_SHA2_IMPLEMENTION(512, QAT_SHA512_CBLOCK, QAT_SHA512_DIGEST_LENGTH, SHA2_FLAGS, "SHA-512") #endif /* ENABLE_QAT_FIPS && ENABLE_QAT_SW_SHA2 */ qatengine-1.9.0/qat_prov_sha3.c000066400000000000000000000346141500416242000164130ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sha3.c * * This file provides an implementation to qatprovider SHA3 operations * *****************************************************************************/ #ifdef ENABLE_QAT_HW_SHA3 # include # include # include # include # include # include # include # include "qat_hw_sha3.h" # include "qat_provider.h" # include "qat_utils.h" # include "qat_evp.h" # include "e_qat.h" # define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT # define PROV_DIGEST_FLAG_XOF 0x0001 #define PROV_DIGEST_FLAG_ALGID_ABSENT 0x0002 # define SHA3_MDSIZE(bitlen) (bitlen / 8) # define SHA3_BLOCKSIZE(bitlen) (KECCAK1600_WIDTH - bitlen * 2) / 8 /* * Forward declaration of any unique methods implemented here. This is not strictly * necessary for the compiler, but provides an assurance that the signatures * of the functions in the dispatch table are correct. */ static OSSL_FUNC_digest_init_fn qat_keccak_init; static OSSL_FUNC_digest_update_fn qat_keccak_update; static OSSL_FUNC_digest_final_fn qat_keccak_final; static OSSL_FUNC_digest_freectx_fn qat_keccak_freectx; static OSSL_FUNC_digest_dupctx_fn qat_keccak_dupctx; static int qat_keccak_init(void *vctx, ossl_unused const OSSL_PARAM params[]) { QAT_KECCAK1600_CTX *ctx = (QAT_KECCAK1600_CTX *)vctx; if (!qat_prov_is_running()) return 0; #ifdef ENABLE_QAT_FIPS memset(ctx->qctx, 0, sizeof(qat_sha3_ctx)); #endif /* The newctx() handles most of the ctx fixed setup. */ memset(ctx->A, 0, sizeof(ctx->A)); ctx->bufsz = 0; #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD if (!EVP_MD_up_ref(ctx->sw_md)) return 0; #endif if (!qat_sha3_init(ctx)){ WARN("QAT sha3 ctx init failed!\n"); return 0; } return 1; } static int qat_keccak_update(void *vctx, const unsigned char *inp, size_t len) { #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif int ret = 0; QAT_KECCAK1600_CTX *ctx = vctx; if (!qat_prov_is_running()) goto end; ret = qat_sha3_update(ctx, inp, len); end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static int qat_keccak_final(void *vctx, unsigned char *out, size_t *outl, size_t outsz) { #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 1; #endif int ret = 1; QAT_KECCAK1600_CTX *ctx = vctx; if (!qat_prov_is_running()) { ret = 0; goto end; } *outl = ctx->md_size; if (outsz > 0){ ret = qat_sha3_final(ctx, out); } end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static QAT_PROV_SHA3_METHOD sha3_generic_md ={ NULL, NULL }; static void set_ctx_md_type(QAT_KECCAK1600_CTX *ctx, int bitlen){ switch (bitlen){ case 224: ctx->md_type = NID_sha3_224; break; case 256: ctx->md_type = NID_sha3_256; break; case 384: ctx->md_type = NID_sha3_384; break; case 512: ctx->md_type = NID_sha3_512; break; } } static void qat_keccak_freectx(void *vctx) { QAT_KECCAK1600_CTX *ctx = (QAT_KECCAK1600_CTX *)vctx; if (!qat_sha3_cleanup(ctx)){ WARN("qat sha3 ctx cleanup failed.\n"); } #ifndef ENABLE_QAT_HW_SMALL_PKT_OFFLOAD EVP_MD_CTX_free(ctx->sw_md_ctx); EVP_MD_free(ctx->sw_md); ctx->sw_md_ctx = NULL; ctx->sw_md = NULL; #endif OPENSSL_clear_free(ctx->qctx, sizeof(qat_sha3_ctx)); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *qat_keccak_dupctx(void *ctx) { QAT_KECCAK1600_CTX *in = (QAT_KECCAK1600_CTX *)ctx; QAT_KECCAK1600_CTX *ret = qat_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) : NULL; qat_sha3_copy(ret, in); if (ret != NULL) *ret = *in; return ret; } static const OSSL_PARAM qat_digest_default_known_gettable_params[] = { OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_SIZE, NULL), OSSL_PARAM_int(OSSL_DIGEST_PARAM_XOF, NULL), OSSL_PARAM_int(OSSL_DIGEST_PARAM_ALGID_ABSENT, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_digest_default_gettable_params(void *provctx) { return qat_digest_default_known_gettable_params; } static int qat_digest_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz, unsigned long flags) { OSSL_PARAM *p = NULL; p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blksz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, paramsz)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOF); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_DIGEST_FLAG_XOF) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_ALGID_ABSENT); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_DIGEST_FLAG_ALGID_ABSENT) != 0)) { QATerr(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } # define PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) \ { OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))qat_##name##_get_params }, \ { OSSL_FUNC_DIGEST_GETTABLE_PARAMS, \ (void (*)(void))qat_digest_default_gettable_params } # define PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END \ { 0, NULL } \ }; # define PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ static OSSL_FUNC_digest_get_params_fn qat_##name##_get_params; \ static int qat_##name##_get_params(OSSL_PARAM params[]) \ { \ return qat_digest_default_get_params(params, blksize, dgstsize, flags); \ } # define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags) \ PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ const OSSL_DISPATCH qat_##name##_functions[] = { \ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))qat_##name##_newctx }, \ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))qat_keccak_update }, \ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))qat_keccak_final }, \ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))qat_keccak_freectx }, \ { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))qat_keccak_dupctx }, \ PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) # define PROV_FUNC_SHA3_DIGEST(name, bitlen, blksize, dgstsize, flags) \ PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags), \ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))qat_keccak_init }, \ PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # define SHA3_NEW_CTX(name, bitlen, pad_val, sha_name) \ static OSSL_FUNC_digest_newctx_fn qat_##name##_newctx; \ static void *qat_##name##_newctx(void *provctx) \ { \ QAT_KECCAK1600_CTX *ctx = qat_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ : NULL; \ size_t bsz = SHA3_BLOCKSIZE(bitlen); \ \ if (ctx == NULL) \ return NULL; \ if (bsz <= sizeof(ctx->buf)) { \ memset(ctx->A, 0, sizeof(ctx->A)); \ ctx->bufsz = 0; \ ctx->block_size = bsz; \ ctx->md_size = bitlen / 8; \ ctx->pad = pad_val; \ } \ set_ctx_md_type(ctx, bitlen); \ ctx->qctx = OPENSSL_zalloc(sizeof(qat_sha3_ctx)); \ if (ctx->qctx == NULL) \ WARN("malloc failed.\n"); \ ctx->meth = sha3_generic_md; \ ctx->sw_md_ctx = EVP_MD_CTX_new(); \ if (ctx->sw_md_ctx == NULL) \ WARN("EVP_MD_CTX_new failed.\n"); \ ctx->sw_md = EVP_MD_fetch(NULL, sha_name, "provider=default"); \ if (ctx->sw_md == NULL) \ WARN("EVP_MD_fetch failed.\n"); \ if (!EVP_MD_up_ref(ctx->sw_md)) \ return NULL; \ return ctx; \ } #else # define SHA3_NEW_CTX(name, bitlen, pad_val, sha_name) \ static OSSL_FUNC_digest_newctx_fn qat_##name##_newctx; \ static void *qat_##name##_newctx(void *provctx) \ { \ QAT_KECCAK1600_CTX *ctx = qat_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ : NULL; \ size_t bsz = SHA3_BLOCKSIZE(bitlen); \ \ if (ctx == NULL) \ return NULL; \ if (bsz <= sizeof(ctx->buf)) { \ memset(ctx->A, 0, sizeof(ctx->A)); \ ctx->bufsz = 0; \ ctx->block_size = bsz; \ ctx->md_size = bitlen / 8; \ ctx->pad = pad_val; \ } \ set_ctx_md_type(ctx, bitlen); \ ctx->qctx = OPENSSL_zalloc(sizeof(qat_sha3_ctx)); \ if (ctx->qctx == NULL) \ WARN("malloc failed.\n"); \ ctx->meth = sha3_generic_md; \ return ctx; \ } #endif # define QAT_PROVIDER_SHA3_IMPLEMENTATION(bitlen, sha_name) \ SHA3_NEW_CTX(sha3_##bitlen, bitlen, '\x06', sha_name) \ PROV_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, \ SHA3_BLOCKSIZE(bitlen), SHA3_MDSIZE(bitlen), \ SHA3_FLAGS) /* qat_sha3_224 functions */ QAT_PROVIDER_SHA3_IMPLEMENTATION(224, "SHA3-224") /* qat_sha3_256 functions */ QAT_PROVIDER_SHA3_IMPLEMENTATION(256, "SHA3-256") /* qat_sha3_384 functions */ QAT_PROVIDER_SHA3_IMPLEMENTATION(384, "SHA3-384") /* qat_sha3_512 functions */ QAT_PROVIDER_SHA3_IMPLEMENTATION(512, "SHA3-512") #endif /* ENABLE_QAT_HW_SHA3 */ qatengine-1.9.0/qat_prov_sign_rsa.c000066400000000000000000002066471500416242000173710ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include "e_qat.h" #include "qat_provider.h" #include "qat_prov_rsa.h" #include "qat_utils.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #ifdef QAT_HW #include "qat_hw_rsa.h" #endif #ifdef QAT_SW #include "qat_sw_rsa.h" #endif # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) #define rsa_pss_restricted(prsactx) (prsactx->min_saltlen != -1) /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 #define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1 #define ASN1_SEQUENCE 0x30 #define ASN1_OCTET_STRING_ 0x04 #define ASN1_NULL 0x05 #define ASN1_OID 0x06 #define NID_mdc2 95 #define OSSL_DIGEST_NAME_MDC2 "MDC2" /* SHA OIDs are of the form: (2 16 840 1 101 3 4 2 |n|) */ #define ENCODE_DIGESTINFO_SHA(name, n, sz) \ static const unsigned char digestinfo_##name##_der[] = { \ ASN1_SEQUENCE, 0x11 + sz, \ ASN1_SEQUENCE, 0x0d, \ ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 2, n, \ ASN1_NULL, 0x00, \ ASN1_OCTET_STRING_, sz \ }; /* MD2, MD4 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */ #define ENCODE_DIGESTINFO_MD(name, n, sz) \ static const unsigned char digestinfo_##name##_der[] = { \ ASN1_SEQUENCE, 0x10 + sz, \ ASN1_SEQUENCE, 0x0c, \ ASN1_OID, 0x08, 1 * 40 + 2, 0x86, 0x48, 0x86, 0xf7, 0x0d, 2, n, \ ASN1_NULL, 0x00, \ ASN1_OCTET_STRING_, sz \ }; #define RSA_KEY_SIZE 8 #if defined(ENABLE_QAT_HW_RSA) || defined(ENABLE_QAT_SW_RSA) struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; OSSL_FUNC_signature_sign_fn *sign; OSSL_FUNC_signature_verify_init_fn *verify_init; OSSL_FUNC_signature_verify_fn *verify; OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; OSSL_FUNC_signature_verify_recover_fn *verify_recover; OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; OSSL_FUNC_signature_digest_sign_fn *digest_sign; OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; OSSL_FUNC_signature_digest_verify_fn *digest_verify; OSSL_FUNC_signature_freectx_fn *freectx; OSSL_FUNC_signature_dupctx_fn *dupctx; OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } /* EVP_SIGNATURE */; static EVP_SIGNATURE get_default_rsa_signature() { static EVP_SIGNATURE s_signature; static int initilazed = 0; if (!initilazed) { EVP_SIGNATURE *signature = (EVP_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "RSA", "provider=default"); if (signature) { s_signature = *signature; EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); initilazed = 1; } else { WARN("EVP_SIGNATURE_fetch from default provider failed"); } } return s_signature; } /* SHA-1 (1 3 14 3 2 26) */ static const unsigned char digestinfo_sha1_der[] = { ASN1_SEQUENCE, 0x0d + SHA_DIGEST_LENGTH, ASN1_SEQUENCE, 0x09, ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, 26, ASN1_NULL, 0x00, ASN1_OCTET_STRING_, SHA_DIGEST_LENGTH }; ENCODE_DIGESTINFO_SHA(sha256, 0x01, SHA256_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha384, 0x02, SHA384_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha512, 0x03, SHA512_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha224, 0x04, SHA224_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha512_224, 0x05, SHA224_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha512_256, 0x06, SHA256_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha3_224, 0x07, SHA224_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha3_256, 0x08, SHA256_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha3_384, 0x09, SHA384_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha3_512, 0x0a, SHA512_DIGEST_LENGTH) #define MD_CASE(name) \ case NID_##name: \ *len = sizeof(digestinfo_##name##_der); \ return digestinfo_##name##_der; #define MD_NID_CASE(name, sz) \ case NID_##name: \ return sz; static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static const OSSL_ITEM oaeppss_name_nid_map[] = { { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 }, { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 }, }; static OSSL_ITEM padding_item[] = { { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE }, { RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931 }, { RSA_PKCS1_PSS_PADDING, OSSL_PKEY_RSA_PAD_MODE_PSS }, { 0, NULL } }; static const QAT_RSA_PSS_PARAMS_30 default_RSASSA_PSS_params = { NID_sha1, /* default hashAlgorithm */ { NID_mgf1, /* default maskGenAlgorithm */ NID_sha1 /* default MGF1 hash */ }, 20, /* default saltLength */ 1 /* default trailerField (0xBC) */ }; static const OSSL_PARAM settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), OSSL_PARAM_END}; static const OSSL_PARAM settable_ctx_params_no_digest[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), OSSL_PARAM_END}; static int qat_rsa_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int ret = 0; #ifdef ENABLE_QAT_HW_RSA if (qat_hw_rsa_offload) ret = qat_rsa_priv_enc(flen, from, to, rsa, padding); #endif #ifdef ENABLE_QAT_SW_RSA if (qat_sw_rsa_offload) ret = multibuff_rsa_priv_enc(flen, from, to, rsa, padding); #endif return ret; } static int qat_rsa_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int ret = 0; #ifdef ENABLE_QAT_HW_RSA if (qat_hw_rsa_offload) ret = qat_rsa_pub_dec(flen, from, to, rsa, padding); #endif #ifdef ENABLE_QAT_SW_RSA if (qat_sw_rsa_offload) ret = multibuff_rsa_pub_dec(flen, from, to, rsa, padding); #endif return ret; } static int setup_tbuf(QAT_PROV_RSA_CTX *ctx) { if (ctx->tbuf != NULL) return 1; if ((ctx->tbuf = OPENSSL_malloc(QAT_RSA_size(ctx->rsa))) == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return 0; } return 1; } static void clean_tbuf(QAT_PROV_RSA_CTX *ctx) { if (ctx->tbuf != NULL) OPENSSL_cleanse(ctx->tbuf, QAT_RSA_size(ctx->rsa)); } static void free_tbuf(QAT_PROV_RSA_CTX *ctx) { clean_tbuf(ctx); OPENSSL_free(ctx->tbuf); ctx->tbuf = NULL; } static size_t rsa_get_md_size(const QAT_PROV_RSA_CTX *prsactx) { if (prsactx->md != NULL) return EVP_MD_size(prsactx->md); return 0; } QAT_RSA_PSS_PARAMS_30 *qat_rsa_get0_pss_params_30(RSA *r) { return &r->pss_params; } int qat_rsa_pss_params_30_is_unrestricted(const QAT_RSA_PSS_PARAMS_30 *rsa_pss_params) { static QAT_RSA_PSS_PARAMS_30 pss_params_cmp = { 0, }; return rsa_pss_params == NULL || memcmp(rsa_pss_params, &pss_params_cmp, sizeof(*rsa_pss_params)) == 0; } int qat_rsa_pss_params_30_hashalg(const QAT_RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.hash_algorithm_nid; return rsa_pss_params->hash_algorithm_nid; } int qat_rsa_pss_params_30_maskgenhashalg(const QAT_RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.hash_algorithm_nid; return rsa_pss_params->mask_gen.hash_algorithm_nid; } int qat_rsa_pss_params_30_saltlen(const QAT_RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.salt_len; return rsa_pss_params->salt_len; } static const char *nid2name(int meth, const OSSL_ITEM *items, size_t items_n) { size_t i; for (i = 0; i < items_n; i++) if (meth == (int)items[i].id) return items[i].ptr; return NULL; } const char *qat_rsa_oaeppss_nid2name(int md) { return nid2name(md, oaeppss_name_nid_map, OSSL_NELEM(oaeppss_name_nid_map)); } static int qat_rsa_check_padding(const QAT_PROV_RSA_CTX *prsactx, const char *mdname, const char *mgf1_mdname, int mdnid) { switch(prsactx->pad_mode) { case RSA_NO_PADDING: QATerr(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE); return 0; case RSA_X931_PADDING: if (RSA_X931_hash_id(mdnid) == -1) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST); return 0; } break; case RSA_PKCS1_PSS_PADDING: if (rsa_pss_restricted(prsactx)) if ((mdname != NULL && !EVP_MD_is_a(prsactx->md, mdname)) || (mgf1_mdname != NULL && !EVP_MD_is_a(prsactx->mgf1_md, mgf1_mdname))) { QATerr(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); return 0; } break; default: break; } return 1; } int qat_digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len) { size_t i; if (md == NULL) return NID_undef; for (i = 0; i < it_len; i++) if (EVP_MD_is_a(md, it[i].ptr)) return (int)it[i].id; return NID_undef; } int qat_digest_get_approved_nid(const EVP_MD *md) { static const OSSL_ITEM name_to_nid[] = { { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 }, { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 }, { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, }; return qat_digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid)); } int qat_digest_rsa_sign_get_md_nid(OSSL_LIB_CTX *ctx, const EVP_MD *md, int sha1_allowed) { return qat_digest_get_approved_nid(md); } static int qat_rsa_setup_mgf1_md(QAT_PROV_RSA_CTX *ctx, const char *mdname, const char *mdprops) { size_t len; EVP_MD *md = NULL; int mdnid; if (mdprops == NULL) mdprops = ctx->propq; if ((md = EVP_MD_fetch(ctx->libctx, mdname, mdprops)) == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s could not be fetched", mdname); return 0; } /* The default for mgf1 is SHA1 - so allow SHA1 */ if ((mdnid = qat_digest_rsa_sign_get_md_nid(ctx->libctx, md, 1)) <= 0 || !qat_rsa_check_padding(ctx, NULL, mdname, mdnid)) { if (mdnid <= 0) ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest=%s", mdname); EVP_MD_free(md); return 0; } len = OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); if (len >= sizeof(ctx->mgf1_mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s exceeds name buffer length", mdname); EVP_MD_free(md); return 0; } EVP_MD_free(ctx->mgf1_md); ctx->mgf1_md = md; ctx->mgf1_mdnid = mdnid; ctx->mgf1_md_set = 1; return 1; } static int qat_rsa_setup_md(QAT_PROV_RSA_CTX *ctx, const char *mdname, const char *mdprops) { if (mdprops == NULL) mdprops = ctx->propq; if (mdname != NULL) { EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); int md_nid = qat_digest_rsa_sign_get_md_nid(ctx->libctx, md, sha1_allowed); size_t mdname_len = strlen(mdname); if (md == NULL || md_nid <= 0 || !qat_rsa_check_padding(ctx, mdname, NULL, md_nid) || mdname_len >= sizeof(ctx->mdname)) { if (md == NULL) ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s could not be fetched", mdname); if (md_nid <= 0) ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest=%s", mdname); if (mdname_len >= sizeof(ctx->mdname)) ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s exceeds name buffer length", mdname); EVP_MD_free(md); return 0; } if (!ctx->mgf1_md_set) { if (!EVP_MD_up_ref(md)) { EVP_MD_free(md); return 0; } EVP_MD_free(ctx->mgf1_md); ctx->mgf1_md = md; ctx->mgf1_mdnid = md_nid; OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); } EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); ctx->mdctx = NULL; ctx->md = md; ctx->mdnid = md_nid; OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); } return 1; } static int qat_rsa_check_parameters(QAT_PROV_RSA_CTX *prsactx, int min_saltlen) { if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) { int max_saltlen; /* See if minimum salt length exceeds maximum possible */ max_saltlen = QAT_RSA_size(prsactx->rsa) - EVP_MD_size(prsactx->md); if ((QAT_RSA_bits(prsactx->rsa) & 0x7) == 1) max_saltlen--; if (min_saltlen < 0 || min_saltlen > max_saltlen) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return 0; } prsactx->min_saltlen = min_saltlen; } return 1; } int QAT_RSA_sign_ASN1_OCTET_STRING(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { ASN1_OCTET_STRING sig; int i, j, ret = 1; unsigned char *p, *s; sig.type = V_ASN1_OCTET_STRING; sig.length = m_len; sig.data = (unsigned char *)m; i = i2d_ASN1_OCTET_STRING(&sig, NULL); j = QAT_RSA_size(rsa); if (i > (j - RSA_PKCS1_PADDING_SIZE)) { QATerr(ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return 0; } s = OPENSSL_malloc((unsigned int)j + 1); if (s == NULL) { QATerr(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return 0; } p = s; i2d_ASN1_OCTET_STRING(&sig, &p); i = qat_rsa_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); if (i <= 0) ret = 0; else *siglen = i; OPENSSL_clear_free(s, (unsigned int)j + 1); return ret; } int QAT_PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen, const EVP_MD *dgst) { long i, outlen = 0; unsigned char cnt[4]; EVP_MD_CTX *c = EVP_MD_CTX_new(); unsigned char md[EVP_MAX_MD_SIZE]; int mdlen; int rv = -1; if (c == NULL) goto err; mdlen = EVP_MD_get_size(dgst); if (mdlen < 0) goto err; /* step 4 */ for (i = 0; outlen < len; i++) { /* step 4a: D = I2BS(counter, 4) */ cnt[0] = (unsigned char)((i >> 24) & 255); cnt[1] = (unsigned char)((i >> 16) & 255); cnt[2] = (unsigned char)((i >> 8)) & 255; cnt[3] = (unsigned char)(i & 255); /* step 4b: T =T || hash(mgfSeed || D) */ if (!EVP_DigestInit_ex(c, dgst, NULL) || !EVP_DigestUpdate(c, seed, seedlen) || !EVP_DigestUpdate(c, cnt, 4)) goto err; if (outlen + mdlen <= len) { if (!EVP_DigestFinal_ex(c, mask + outlen, NULL)) goto err; outlen += mdlen; } else { if (!EVP_DigestFinal_ex(c, md, NULL)) goto err; memcpy(mask + outlen, md, len - outlen); outlen = len; } } rv = 0; err: OPENSSL_cleanse(md, sizeof(md)); EVP_MD_CTX_free(c); return rv; } int QAT_RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; unsigned char *H, *salt = NULL, *p; EVP_MD_CTX *ctx = NULL; if (mgf1Hash == NULL) mgf1Hash = Hash; hLen = EVP_MD_get_size(Hash); if (hLen < 0) goto err; /*- * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is maximized * -3 same as above (on signing) * -N reserved */ if (sLen == RSA_PSS_SALTLEN_DIGEST) { sLen = hLen; } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) { sLen = RSA_PSS_SALTLEN_MAX; } else if (sLen < RSA_PSS_SALTLEN_MAX) { QATerr(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = QAT_RSA_size(rsa); if (MSBits == 0) { *EM++ = 0; emLen--; } if (emLen < hLen + 2) { QATerr(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen == RSA_PSS_SALTLEN_MAX) { sLen = emLen - hLen - 2; } else if (sLen > emLen - hLen - 2) { QATerr(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; } if (sLen > 0) { salt = OPENSSL_malloc(sLen); if (salt == NULL) { QATerr(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (RAND_bytes_ex(rsa->libctx, salt, sLen, 0) <= 0) goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; ctx = EVP_MD_CTX_new(); if (ctx == NULL) goto err; if (!EVP_DigestInit_ex(ctx, Hash, NULL) || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) || !EVP_DigestUpdate(ctx, mHash, hLen)) goto err; if (sLen && !EVP_DigestUpdate(ctx, salt, sLen)) goto err; if (!EVP_DigestFinal_ex(ctx, H, NULL)) goto err; /* Generate dbMask in place then perform XOR on it */ if (QAT_PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) goto err; p = EM; /* * Initial PS XORs with all zeroes which is a NOP so just update pointer. * Note from a test above this value is guaranteed to be non-negative. */ p += emLen - sLen - hLen - 2; *p++ ^= 0x1; if (sLen > 0) { for (i = 0; i < sLen; i++) *p++ ^= salt[i]; } if (MSBits) EM[0] &= 0xFF >> (8 - MSBits); /* H is already in place so just set final 0xbc */ EM[emLen - 1] = 0xbc; ret = 1; err: EVP_MD_CTX_free(ctx); OPENSSL_clear_free(salt, (size_t)sLen); /* salt != NULL implies sLen > 0 */ return ret; } int QAT_RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, const EVP_MD *Hash, const EVP_MD *mgf1Hash, const unsigned char *EM, int sLen) { int i; int ret = 0; int hLen, maskedDBLen, MSBits, emLen; const unsigned char *H; unsigned char *DB = NULL; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); unsigned char H_[EVP_MAX_MD_SIZE]; if (ctx == NULL) goto err; if (mgf1Hash == NULL) mgf1Hash = Hash; hLen = EVP_MD_get_size(Hash); if (hLen < 0) goto err; /*- * Negative sLen has special meanings: * -1 sLen == hLen * -2 salt length is autorecovered from signature * -3 salt length is maximized * -N reserved */ if (sLen == RSA_PSS_SALTLEN_DIGEST) { sLen = hLen; } else if (sLen < RSA_PSS_SALTLEN_MAX) { QATerr(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; emLen = QAT_RSA_size(rsa); if (EM[0] & (0xFF << MSBits)) { QATerr(ERR_LIB_RSA, RSA_R_FIRST_OCTET_INVALID); goto err; } if (MSBits == 0) { EM++; emLen--; } if (emLen < hLen + 2) { QATerr(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE); goto err; } if (sLen == RSA_PSS_SALTLEN_MAX) { sLen = emLen - hLen - 2; } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ QATerr(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE); goto err; } if (EM[emLen - 1] != 0xbc) { QATerr(ERR_LIB_RSA, RSA_R_LAST_OCTET_INVALID); goto err; } maskedDBLen = emLen - hLen - 1; H = EM + maskedDBLen; DB = OPENSSL_malloc(maskedDBLen); if (DB == NULL) { QATerr(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } if (QAT_PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) goto err; for (i = 0; i < maskedDBLen; i++) DB[i] ^= EM[i]; if (MSBits) DB[0] &= 0xFF >> (8 - MSBits); for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; if (DB[i++] != 0x1) { QATerr(ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED); goto err; } if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) { ERR_raise_data(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED, "expected: %d retrieved: %d", sLen, maskedDBLen - i); goto err; } if (!EVP_DigestInit_ex(ctx, Hash, NULL) || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes)) || !EVP_DigestUpdate(ctx, mHash, hLen)) goto err; if (maskedDBLen - i) { if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i)) goto err; } if (!EVP_DigestFinal_ex(ctx, H_, NULL)) goto err; if (memcmp(H_, H, hLen)) { QATerr(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); ret = 0; } else { ret = 1; } err: OPENSSL_free(DB); EVP_MD_CTX_free(ctx); return ret; } const unsigned char *qat_rsa_digestinfo_encoding(int md_nid, size_t *len) { switch (md_nid) { MD_CASE(sha1) MD_CASE(sha224) MD_CASE(sha256) MD_CASE(sha384) MD_CASE(sha512) MD_CASE(sha512_224) MD_CASE(sha512_256) MD_CASE(sha3_224) MD_CASE(sha3_256) MD_CASE(sha3_384) MD_CASE(sha3_512) default: return NULL; } } static int digest_sz_from_nid(int nid) { switch (nid) { MD_NID_CASE(sha1, SHA_DIGEST_LENGTH) MD_NID_CASE(sha224, SHA224_DIGEST_LENGTH) MD_NID_CASE(sha256, SHA256_DIGEST_LENGTH) MD_NID_CASE(sha384, SHA384_DIGEST_LENGTH) MD_NID_CASE(sha512, SHA512_DIGEST_LENGTH) MD_NID_CASE(sha512_224, SHA224_DIGEST_LENGTH) MD_NID_CASE(sha512_256, SHA256_DIGEST_LENGTH) MD_NID_CASE(sha3_224, SHA224_DIGEST_LENGTH) MD_NID_CASE(sha3_256, SHA256_DIGEST_LENGTH) MD_NID_CASE(sha3_384, SHA384_DIGEST_LENGTH) MD_NID_CASE(sha3_512, SHA512_DIGEST_LENGTH) default: return 0; } } /* * Encodes a DigestInfo prefix of hash |type| and digest |m|, as * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This * encodes the DigestInfo (T and tLen) but does not add the padding. * * On success, it returns one and sets |*out| to a newly allocated buffer * containing the result and |*out_len| to its length. The caller must free * |*out| with OPENSSL_free(). Otherwise, it returns zero. */ static int encode_pkcs1(unsigned char **out, size_t *out_len, int type, const unsigned char *m, size_t m_len) { size_t di_prefix_len, dig_info_len; const unsigned char *di_prefix; unsigned char *dig_info; if (type == NID_undef) { QATerr(ERR_LIB_RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } di_prefix = qat_rsa_digestinfo_encoding(type, &di_prefix_len); if (di_prefix == NULL) { QATerr(ERR_LIB_RSA, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return 0; } dig_info_len = di_prefix_len + m_len; dig_info = OPENSSL_malloc(dig_info_len); if (dig_info == NULL) { QATerr(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); return 0; } memcpy(dig_info, di_prefix, di_prefix_len); memcpy(dig_info + di_prefix_len, m, m_len); *out = dig_info; *out_len = dig_info_len; return 1; } int QAT_RSA_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { int encrypt_len, ret = 0; size_t encoded_len = 0; unsigned char *tmps = NULL; const unsigned char *encoded = NULL; /* Compute the encoded digest. */ if (type == NID_md5_sha1) { /* * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and * earlier. It has no DigestInfo wrapper but otherwise is * RSASSA-PKCS1-v1_5. */ if (m_len != SSL_SIG_LENGTH) { QATerr(ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } encoded_len = SSL_SIG_LENGTH; encoded = m; } else { if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len)) goto err; encoded = tmps; } if (encoded_len + RSA_PKCS1_PADDING_SIZE > (size_t)QAT_RSA_size(rsa)) { QATerr(ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); goto err; } encrypt_len = qat_rsa_private_encrypt((int)encoded_len, encoded, sigret, rsa, RSA_PKCS1_PADDING); if (encrypt_len <= 0) goto err; *siglen = encrypt_len; ret = 1; err: OPENSSL_clear_free(tmps, encoded_len); return ret; } int QAT_RSA_verify(int type, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa) { int len, ret = 0; size_t decrypt_len, encoded_len = 0; unsigned char *decrypt_buf = NULL, *encoded = NULL; if (siglen != (size_t)QAT_RSA_size(rsa)) { QATerr(ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH); return 0; } /* Recover the encoded digest. */ decrypt_buf = OPENSSL_malloc(siglen); if (decrypt_buf == NULL) { QATerr(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); goto err; } len = qat_rsa_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa, RSA_PKCS1_PADDING); if (len <= 0) goto err; decrypt_len = len; if (type == NID_md5_sha1) { /* * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and * earlier. It has no DigestInfo wrapper but otherwise is * RSASSA-PKCS1-v1_5. */ if (decrypt_len != SSL_SIG_LENGTH) { QATerr(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } if (rm != NULL) { memcpy(rm, decrypt_buf, SSL_SIG_LENGTH); *prm_len = SSL_SIG_LENGTH; } else { if (m_len != SSL_SIG_LENGTH) { QATerr(ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) { QATerr(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } } } else if (type == NID_mdc2 && decrypt_len == 2 + 16 && decrypt_buf[0] == 0x04 && decrypt_buf[1] == 0x10) { /* * Oddball MDC2 case: signature can be OCTET STRING. check for correct * tag and length octets. */ if (rm != NULL) { memcpy(rm, decrypt_buf + 2, 16); *prm_len = 16; } else { if (m_len != 16) { QATerr(ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } if (memcmp(m, decrypt_buf + 2, 16) != 0) { QATerr(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } } } else { /* * If recovering the digest, extract a digest-sized output from the end * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption * output as in a standard verification. */ if (rm != NULL) { len = digest_sz_from_nid(type); if (len <= 0) goto err; m_len = (unsigned int)len; if (m_len > decrypt_len) { QATerr(ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH); goto err; } m = decrypt_buf + decrypt_len - m_len; } /* Construct the encoded digest and ensure it matches. */ if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len)) goto err; if (encoded_len != decrypt_len || memcmp(encoded, decrypt_buf, encoded_len) != 0) { QATerr(ERR_LIB_RSA, RSA_R_BAD_SIGNATURE); goto err; } /* Output the recovered digest. */ if (rm != NULL) { memcpy(rm, m, m_len); *prm_len = m_len; } } ret = 1; err: OPENSSL_clear_free(encoded, encoded_len); OPENSSL_clear_free(decrypt_buf, siglen); return ret; } static int qat_signature_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; const OSSL_PARAM *p; int pad_mode; int saltlen; char mdname[50] = "", *pmdname = NULL; char mdprops[256] = "", *pmdprops = NULL; char mgf1mdname[50] = "", *pmgf1mdname = NULL; char mgf1mdprops[256] = "", *pmgf1mdprops = NULL; if (prsactx == NULL) return 0; if (params == NULL) return 1; pad_mode = prsactx->pad_mode; saltlen = prsactx->saltlen; p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); /* Not allowed during certain operations */ if (p != NULL && !prsactx->flag_allow_md) return 0; if (p != NULL) { const OSSL_PARAM *propsp = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PROPERTIES); pmdname = mdname; if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) return 0; if (propsp != NULL) { pmdprops = mdprops; if (!OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE); if (p != NULL) { const char *err_extra_text = NULL; switch (p->data_type) { case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ if (!OSSL_PARAM_get_int(p, &pad_mode)) return 0; break; case OSSL_PARAM_UTF8_STRING: { int i; if (p->data == NULL) return 0; for (i = 0; padding_item[i].id != 0; i++) { if (strcmp(p->data, padding_item[i].ptr) == 0) { pad_mode = padding_item[i].id; break; } } } break; default: return 0; } switch (pad_mode) { case RSA_PKCS1_OAEP_PADDING: /* * OAEP padding is for asymmetric cipher only so is not compatible * with signature use. */ err_extra_text = "OAEP padding not allowed for signing / verifying"; goto bad_pad; case RSA_PKCS1_PSS_PADDING: if ((prsactx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)) == 0) { err_extra_text = "PSS padding only allowed for sign and verify operations"; goto bad_pad; } break; case RSA_PKCS1_PADDING: err_extra_text = "PKCS#1 padding not allowed with RSA-PSS"; goto cont; case RSA_NO_PADDING: err_extra_text = "No padding not allowed with RSA-PSS"; goto cont; case RSA_X931_PADDING: err_extra_text = "X.931 padding not allowed with RSA-PSS"; cont: if (QAT_RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSA) break; /* FALLTHRU */ default: bad_pad: if (err_extra_text == NULL) QATerr(ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); else ERR_raise_data(ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE, err_extra_text); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN); if (p != NULL) { if (pad_mode != RSA_PKCS1_PSS_PADDING) { ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED, "PSS saltlen can only be specified if " "PSS padding has been specified first"); return 0; } switch (p->data_type) { case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ if (!OSSL_PARAM_get_int(p, &saltlen)) return 0; break; case OSSL_PARAM_UTF8_STRING: if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST) == 0) saltlen = RSA_PSS_SALTLEN_DIGEST; else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_MAX) == 0) saltlen = RSA_PSS_SALTLEN_MAX; else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0) saltlen = RSA_PSS_SALTLEN_AUTO; else saltlen = atoi(p->data); break; default: return 0; } /* * RSA_PSS_SALTLEN_MAX seems curiously named in this check. * Contrary to what it's name suggests, it's the currently * lowest saltlen number possible. */ if (saltlen < RSA_PSS_SALTLEN_MAX) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return 0; } if (rsa_pss_restricted(prsactx)) { switch (saltlen) { case RSA_PSS_SALTLEN_AUTO: if (prsactx->operation == EVP_PKEY_OP_VERIFY) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "Cannot use autodetected salt length"); return 0; } break; case RSA_PSS_SALTLEN_DIGEST: if (prsactx->min_saltlen > EVP_MD_size(prsactx->md)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL, "Should be more than %d, but would be " "set to match digest size (%d)", prsactx->min_saltlen, EVP_MD_size(prsactx->md)); return 0; } break; default: if (saltlen >= 0 && saltlen < prsactx->min_saltlen) { ERR_raise_data(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL, "Should be more than %d, " "but would be set to %d", prsactx->min_saltlen, saltlen); return 0; } } } } p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST); if (p != NULL) { const OSSL_PARAM *propsp = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES); pmgf1mdname = mgf1mdname; if (!OSSL_PARAM_get_utf8_string(p, &pmgf1mdname, sizeof(mgf1mdname))) return 0; if (propsp != NULL) { pmgf1mdprops = mgf1mdprops; if (!OSSL_PARAM_get_utf8_string(propsp, &pmgf1mdprops, sizeof(mgf1mdprops))) return 0; } if (pad_mode != RSA_PKCS1_PSS_PADDING) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_MGF1_MD); return 0; } } prsactx->saltlen = saltlen; prsactx->pad_mode = pad_mode; if (prsactx->md == NULL && pmdname == NULL && pad_mode == RSA_PKCS1_PSS_PADDING) pmdname = RSA_DEFAULT_DIGEST_NAME; if (pmgf1mdname != NULL && !qat_rsa_setup_mgf1_md(prsactx, pmgf1mdname, pmgf1mdprops)) return 0; if (pmdname != NULL) { if (!qat_rsa_setup_md(prsactx, pmdname, pmdprops)) return 0; } else { if (!qat_rsa_check_padding(prsactx, NULL, NULL, prsactx->mdnid)) return 0; } return 1; } static void *qat_signature_rsa_newctx(void *provctx, const char *propq) { QAT_PROV_RSA_CTX *prsactx = NULL; char *propq_copy = NULL; if ((prsactx = OPENSSL_zalloc(sizeof(QAT_PROV_RSA_CTX))) == NULL || (propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL)) { OPENSSL_free(prsactx); QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } prsactx->libctx = prov_libctx_of(provctx); prsactx->flag_allow_md = 1; prsactx->propq = propq_copy; return prsactx; } static void qat_signature_rsa_freectx(void *vprsactx) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; if (prsactx == NULL) return; EVP_MD_CTX_free(prsactx->mdctx); EVP_MD_free(prsactx->md); EVP_MD_free(prsactx->mgf1_md); OPENSSL_free(prsactx->propq); free_tbuf(prsactx); QAT_RSA_free((RSA*)prsactx->rsa); OPENSSL_clear_free(prsactx, sizeof(*prsactx)); return; } static int qat_rsa_signverify_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[], int operation) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; if (!qat_prov_is_running()) return 0; if (prsactx == NULL || vrsa == NULL) return 0; if (!QAT_RSA_up_ref(vrsa)) return 0; QAT_RSA_free(prsactx->rsa); prsactx->rsa = vrsa; prsactx->operation = operation; if (!qat_signature_rsa_set_ctx_params(prsactx, params)) return 0; /* Maximum for sign, auto for verify */ prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; prsactx->min_saltlen = -1; switch (QAT_RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: prsactx->pad_mode = RSA_PKCS1_PADDING; break; case RSA_FLAG_TYPE_RSASSAPSS: prsactx->pad_mode = RSA_PKCS1_PSS_PADDING; { const QAT_RSA_PSS_PARAMS_30 *pss = qat_rsa_get0_pss_params_30(prsactx->rsa); if (!qat_rsa_pss_params_30_is_unrestricted(pss)) { int md_nid = qat_rsa_pss_params_30_hashalg(pss); int mgf1md_nid = qat_rsa_pss_params_30_maskgenhashalg(pss); int min_saltlen = qat_rsa_pss_params_30_saltlen(pss); const char *mdname, *mgf1mdname; size_t len; mdname = qat_rsa_oaeppss_nid2name(md_nid); mgf1mdname = qat_rsa_oaeppss_nid2name(mgf1md_nid); if (mdname == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "PSS restrictions lack hash algorithm"); return 0; } if (mgf1mdname == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "PSS restrictions lack MGF1 hash algorithm"); return 0; } len = OPENSSL_strlcpy(prsactx->mdname, mdname, sizeof(prsactx->mdname)); if (len >= sizeof(prsactx->mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "hash algorithm name too long"); return 0; } len = OPENSSL_strlcpy(prsactx->mgf1_mdname, mgf1mdname, sizeof(prsactx->mgf1_mdname)); if (len >= sizeof(prsactx->mgf1_mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "MGF1 hash algorithm name too long"); return 0; } prsactx->saltlen = min_saltlen; /* call rsa_setup_mgf1_md before rsa_setup_md to avoid duplication */ return qat_rsa_setup_mgf1_md(prsactx, mgf1mdname, prsactx->propq) && qat_rsa_setup_md(prsactx, mdname, prsactx->propq) && qat_rsa_check_parameters(prsactx, min_saltlen); } } break; default: QATerr(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } return 1; } static int qat_signature_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { DEBUG("qat_rsa_sign_init.\n"); if (!qat_prov_is_running()) return 0; return qat_rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_SIGN); } static int qat_signature_rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; int ret = 0; size_t rsasize = QAT_RSA_size(prsactx->rsa); size_t mdsize = rsa_get_md_size(prsactx); #ifdef ENABLE_QAT_FIPS int key_size = rsasize * RSA_KEY_SIZE; if (key_size < FIPS_RSA_SIGN_MIN_SIZE || key_size > FIPS_RSA_MAX_SIZE) { INFO("%d is FIPS non approved size\n", key_size); goto end; } qat_fips_service_indicator = 1; #endif if (!qat_prov_is_running()) goto end; if (sig == NULL) { *siglen = rsasize; ret = 1; goto end; } if (sigsize < rsasize) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE, "is %zu, should be at least %zu", sigsize, rsasize); goto end; } if (mdsize != 0) { if (tbslen != mdsize) { QATerr(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); goto end; } if (EVP_MD_is_a(prsactx->md, OSSL_DIGEST_NAME_MDC2)) { unsigned int sltmp; if (prsactx->pad_mode != RSA_PKCS1_PADDING) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, "only PKCS#1 padding supported with MDC2"); goto end; } ret = QAT_RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp, prsactx->rsa); if (ret <= 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } ret = sltmp; goto end; } switch (prsactx->pad_mode) { case RSA_X931_PADDING: if ((size_t)QAT_RSA_size(prsactx->rsa) < tbslen + 1) { ERR_raise_data(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL, "RSA key size = %d, expected minimum = %d", QAT_RSA_size(prsactx->rsa), tbslen + 1); goto end; } if (!setup_tbuf(prsactx)) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); goto end; } memcpy(prsactx->tbuf, tbs, tbslen); prsactx->tbuf[tbslen] = RSA_X931_hash_id(prsactx->mdnid); ret = qat_rsa_private_encrypt(tbslen + 1, prsactx->tbuf, sig, prsactx->rsa, RSA_X931_PADDING); clean_tbuf(prsactx); break; case RSA_PKCS1_PADDING: { unsigned int sltmp; ret = QAT_RSA_sign(prsactx->mdnid, tbs, tbslen, sig, &sltmp, prsactx->rsa); if (ret <= 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } ret = sltmp; } break; case RSA_PKCS1_PSS_PADDING: /* Check PSS restrictions */ if (rsa_pss_restricted(prsactx)) { switch (prsactx->saltlen) { case RSA_PSS_SALTLEN_DIGEST: if (prsactx->min_saltlen > EVP_MD_size(prsactx->md)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL, "minimum salt length set to %d, " "but the digest only gives %d", prsactx->min_saltlen, EVP_MD_size(prsactx->md)); goto end; } /* FALLTHRU */ default: if (prsactx->saltlen >= 0 && prsactx->saltlen < prsactx->min_saltlen) { ERR_raise_data(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL, "minimum salt length set to %d, but the" "actual salt length is only set to %d", prsactx->min_saltlen, prsactx->saltlen); goto end; } break; } } if (!setup_tbuf(prsactx)) goto end; if (!QAT_RSA_padding_add_PKCS1_PSS_mgf1(prsactx->rsa, prsactx->tbuf, tbs, prsactx->md, prsactx->mgf1_md, prsactx->saltlen)) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } if (qat_hw_rsa_offload || qat_sw_rsa_offload) { ret = qat_rsa_private_encrypt(QAT_RSA_size(prsactx->rsa), prsactx->tbuf, sig, prsactx->rsa, RSA_NO_PADDING); } else { typedef int (*fun_ptr)(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen); fun_ptr fun = get_default_rsa_signature().sign; if (!fun) return 0; return fun(vprsactx, sig, siglen, sigsize, tbs, tbslen); } clean_tbuf(prsactx); break; default: ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, "Only X.931, PKCS#1 v1.5 or PSS padding allowed"); goto end; } } else { if (qat_hw_rsa_offload || qat_sw_rsa_offload) { ret = qat_rsa_private_encrypt(tbslen, tbs, sig, prsactx->rsa, prsactx->pad_mode); } else { typedef int (*fun_ptr)(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen); fun_ptr fun = get_default_rsa_signature().sign; if (!fun) return 0; return fun(vprsactx, sig, siglen, sigsize, tbs, tbslen); } } end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif if (ret <= 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } if (sig != NULL) *siglen = ret; return 1; } static int qat_signature_rsa_verify_recover_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { DEBUG("qat_rsa_verify_recover_init.\n"); if (!qat_prov_is_running()) return 0; return qat_rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFYRECOVER); } static int qat_signature_rsa_verify_recover(void *vprsactx, unsigned char *rout, size_t *routlen, size_t routsize, const unsigned char *sig, size_t siglen) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; int ret; if (!qat_prov_is_running()) return 0; if (rout == NULL) { *routlen = QAT_RSA_size(prsactx->rsa); return 1; } if (prsactx->md != NULL) { switch (prsactx->pad_mode) { case RSA_X931_PADDING: if (!setup_tbuf(prsactx)) return 0; ret = qat_rsa_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, RSA_X931_PADDING); if (ret < 1) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } ret--; if (prsactx->tbuf[ret] != RSA_X931_hash_id(prsactx->mdnid)) { QATerr(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH); return 0; } if (ret != EVP_MD_size(prsactx->md)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH, "Should be %d, but got %d", EVP_MD_size(prsactx->md), ret); return 0; } *routlen = ret; if (rout != prsactx->tbuf) { if (routsize < (size_t)ret) { ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL, "buffer size is %d, should be %d", routsize, ret); return 0; } memcpy(rout, prsactx->tbuf, ret); } break; case RSA_PKCS1_PADDING: { size_t sltmp; ret = QAT_RSA_verify(prsactx->mdnid, NULL, 0, rout, &sltmp, sig, siglen, prsactx->rsa); if (ret <= 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } ret = sltmp; } break; default: ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, "Only X.931 or PKCS#1 v1.5 padding allowed"); return 0; } } else { ret = qat_rsa_public_decrypt(siglen, sig, rout, prsactx->rsa, prsactx->pad_mode); if (ret < 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } } *routlen = ret; return 1; } static int qat_signature_rsa_verify_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { DEBUG("qat_rsa_verify_init.\n"); if (!qat_prov_is_running()) return 0; return qat_rsa_signverify_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFY); } static int qat_signature_rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; size_t rslen = 0; int ret = 0; #ifdef ENABLE_QAT_FIPS size_t rsasize = QAT_RSA_size(prsactx->rsa); int key_size = rsasize * RSA_KEY_SIZE; if (key_size != FIPS_RSA_VER_MIN_SIZE) { if (key_size < FIPS_RSA_SIGN_MIN_SIZE || key_size > FIPS_RSA_MAX_SIZE) { INFO("%d is FIPS non approved size\n", key_size); goto end; } qat_fips_service_indicator = 1; } else { INFO("Given Key size %d is Allowed. But, FIPS non-approved size\n", FIPS_RSA_VER_MIN_SIZE); } #endif if (!qat_prov_is_running()) goto end; if (prsactx->md != NULL) { switch (prsactx->pad_mode) { case RSA_PKCS1_PADDING: if (!QAT_RSA_verify(prsactx->mdnid, tbs, tbslen, NULL, NULL, sig, siglen, prsactx->rsa)) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } ret = 1; goto end; case RSA_X931_PADDING: if (!setup_tbuf(prsactx)) goto end; if (qat_signature_rsa_verify_recover(prsactx, prsactx->tbuf, &rslen, 0, sig, siglen) <= 0) goto end; break; case RSA_PKCS1_PSS_PADDING: { size_t mdsize; /* * We need to check this for the RSA_verify_PKCS1_PSS_mgf1() * call */ mdsize = rsa_get_md_size(prsactx); if (tbslen != mdsize) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH, "Should be %d, but got %d", mdsize, tbslen); goto end; } if (!setup_tbuf(prsactx)) goto end; ret = qat_rsa_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, RSA_NO_PADDING); if (ret <= 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } ret = QAT_RSA_verify_PKCS1_PSS_mgf1(prsactx->rsa, tbs, prsactx->md, prsactx->mgf1_md, prsactx->tbuf, prsactx->saltlen); if (ret <= 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } ret = 1; goto end; } default: ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, "Only X.931, PKCS#1 v1.5 or PSS padding allowed"); goto end; } } else { if (!setup_tbuf(prsactx)) goto end; if (qat_hw_rsa_offload || qat_sw_rsa_offload) { rslen = qat_rsa_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, prsactx->pad_mode); } else { typedef int (*fun_ptr)(void *vprsactx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); fun_ptr fun = get_default_rsa_signature().verify; if (!fun) return 0; return fun(vprsactx, sig, siglen, tbs, tbslen); } if (rslen == 0) { QATerr(ERR_LIB_PROV, ERR_R_RSA_LIB); goto end; } } if ((rslen != tbslen) || memcmp(tbs, prsactx->tbuf, rslen)) goto end; ret = 1; end: #ifdef ENABLE_QAT_FIPS qat_fips_service_indicator = 0; #endif return ret; } static const OSSL_PARAM *qat_signature_rsa_settable_ctx_params(void *vprsactx, ossl_unused void *provctx) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; if (prsactx != NULL && !prsactx->flag_allow_md) return settable_ctx_params_no_digest; return settable_ctx_params; } static int qat_signature_rsa_digest_signverify_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[], int operation) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; if (!qat_prov_is_running()) return 0; if (!qat_rsa_signverify_init(vprsactx, vrsa, params, operation)) return 0; if (mdname != NULL /* was rsa_setup_md already called in rsa_signverify_init()? */ && (mdname[0] == '\0' || OPENSSL_strcasecmp(prsactx->mdname, mdname) != 0) && !qat_rsa_setup_md(prsactx, mdname, prsactx->propq)) return 0; prsactx->flag_allow_md = 0; if (prsactx->mdctx == NULL) { prsactx->mdctx = EVP_MD_CTX_new(); if (prsactx->mdctx == NULL) goto error; } if (!EVP_DigestInit_ex2(prsactx->mdctx, prsactx->md, params)) goto error; return 1; error: EVP_MD_CTX_free(prsactx->mdctx); prsactx->mdctx = NULL; return 0; } static int qat_signature_rsa_digest_sign_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { if (!qat_prov_is_running()) return 0; return qat_signature_rsa_digest_signverify_init(vprsactx, mdname, vrsa, params, EVP_PKEY_OP_SIGN); } static int qat_signature_rsa_digest_signverify_update(void *vprsactx, const unsigned char *data, size_t datalen) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; if (prsactx == NULL || prsactx->mdctx == NULL) return 0; return EVP_DigestUpdate(prsactx->mdctx, data, datalen); } static int qat_signature_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (!qat_prov_is_running() || prsactx == NULL) return 0; prsactx->flag_allow_md = 1; if (prsactx->mdctx == NULL) return 0; /* * If sig is NULL then we're just finding out the sig size. Other fields * are ignored. Defer to rsa_sign. */ if (sig != NULL) { /* * The digests used here are all known (see rsa_get_md_nid()), so they * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. */ if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) return 0; } return qat_signature_rsa_sign(vprsactx, sig, siglen, sigsize, digest, (size_t)dlen); } static int qat_signature_rsa_digest_verify_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { if (!qat_prov_is_running()) return 0; return qat_signature_rsa_digest_signverify_init(vprsactx, mdname, vrsa, params, EVP_PKEY_OP_VERIFY); } int qat_signature_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, size_t siglen) { QAT_PROV_RSA_CTX *prsactx = (QAT_PROV_RSA_CTX *)vprsactx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (!qat_prov_is_running()) return 0; if (prsactx == NULL) return 0; prsactx->flag_allow_md = 1; if (prsactx->mdctx == NULL) return 0; /* * The digests used here are all known (see rsa_get_md_nid()), so they * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. */ if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) return 0; return qat_signature_rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); } static void *qat_signature_rsa_dupctx(void *vprsactx) { QAT_PROV_RSA_CTX *srcctx = (QAT_PROV_RSA_CTX *)vprsactx; QAT_PROV_RSA_CTX *dstctx; if (!qat_prov_is_running()) return NULL; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) { QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } *dstctx = *srcctx; dstctx->rsa = NULL; dstctx->md = NULL; dstctx->mdctx = NULL; dstctx->tbuf = NULL; dstctx->propq = NULL; if (srcctx->rsa != NULL && !QAT_RSA_up_ref(srcctx->rsa)) goto err; dstctx->rsa = srcctx->rsa; if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) goto err; dstctx->md = srcctx->md; if (srcctx->mgf1_md != NULL && !EVP_MD_up_ref(srcctx->mgf1_md)) goto err; dstctx->mgf1_md = srcctx->mgf1_md; if (srcctx->mdctx != NULL) { dstctx->mdctx = EVP_MD_CTX_new(); if (dstctx->mdctx == NULL || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) goto err; } if (srcctx->propq != NULL) { dstctx->propq = OPENSSL_strdup(srcctx->propq); if (dstctx->propq == NULL) goto err; } return dstctx; err: qat_signature_rsa_freectx(dstctx); return NULL; } static int qat_signature_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); fun_ptr fun = get_default_rsa_signature().get_ctx_params; if (!fun) return 0; return fun(vprsactx, params); } static const OSSL_PARAM *qat_signature_rsa_gettable_ctx_md_params(void *vprsactx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx); fun_ptr fun = get_default_rsa_signature().gettable_ctx_md_params; if (!fun) return NULL; return fun(vprsactx); } static int qat_signature_rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) { typedef int (*fun_ptr)(void *vprsactx, const OSSL_PARAM params[]); fun_ptr fun = get_default_rsa_signature().set_ctx_md_params; if (!fun) return 0; return fun(vprsactx, params); } static const OSSL_PARAM *qat_signature_rsa_settable_ctx_md_params(void *vprsactx) { typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx); fun_ptr fun = get_default_rsa_signature().settable_ctx_md_params; if (!fun) return NULL; return fun(vprsactx); } static const OSSL_PARAM *qat_signature_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx) { typedef const OSSL_PARAM * (*fun_ptr)(ossl_unused void *vprsactx, ossl_unused void *provctx); fun_ptr fun = get_default_rsa_signature().gettable_ctx_params; if (!fun) return NULL; return fun(vprsactx, provctx); } static int qat_signature_rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) { typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); fun_ptr fun = get_default_rsa_signature().get_ctx_md_params; if (!fun) return 0; return fun(vprsactx, params); } const OSSL_DISPATCH qat_rsa_signature_functions[] = { {OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))qat_signature_rsa_newctx}, {OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))qat_signature_rsa_sign_init}, {OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))qat_signature_rsa_sign}, { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))qat_signature_rsa_verify_init }, { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))qat_signature_rsa_verify }, { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, (void (*)(void))qat_signature_rsa_verify_recover_init }, { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, (void (*)(void))qat_signature_rsa_verify_recover }, {OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))qat_signature_rsa_freectx}, {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))qat_signature_rsa_set_ctx_params}, {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))qat_signature_rsa_settable_ctx_params}, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))qat_signature_rsa_digest_sign_init }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, (void (*)(void))qat_signature_rsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))qat_signature_rsa_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))qat_signature_rsa_digest_verify_init }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, (void (*)(void))qat_signature_rsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, (void (*)(void))qat_signature_rsa_digest_verify_final }, { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))qat_signature_rsa_dupctx }, { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))qat_signature_rsa_get_ctx_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))qat_signature_rsa_gettable_ctx_params }, { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, (void (*)(void))qat_signature_rsa_get_ctx_md_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_signature_rsa_gettable_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, (void (*)(void))qat_signature_rsa_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_signature_rsa_settable_ctx_md_params }, {0, NULL} }; #endif qatengine-1.9.0/qat_prov_sign_sm2.c000066400000000000000000000543621500416242000173000ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sign_sm2.c * * This file provides an implementation to qatprovider SM2 operations * *****************************************************************************/ #include /* memcpy */ #include #include #include #include #include #include #include #include #include "qat_provider.h" #include "qat_prov_hkdf_packet.h" #include "e_qat.h" #ifdef ENABLE_QAT_HW_SM2 # include "qat_hw_sm2.h" #endif #ifdef ENABLE_QAT_SW_SM2 #include "qat_prov_ec.h" # include "qat_sw_sm2.h" #endif #if defined(ENABLE_QAT_HW_SM2) || defined(ENABLE_QAT_SW_SM2) static OSSL_FUNC_signature_newctx_fn qat_sm2sig_newctx; static OSSL_FUNC_signature_sign_init_fn qat_sm2sig_signature_init; static OSSL_FUNC_signature_verify_init_fn qat_sm2sig_signature_init; static OSSL_FUNC_signature_sign_fn qat_sm2sig_sign; static OSSL_FUNC_signature_verify_fn qat_sm2sig_verify; static OSSL_FUNC_signature_digest_sign_init_fn qat_sm2sig_digest_signverify_init; # ifdef ENABLE_QAT_SW_SM2 static OSSL_FUNC_signature_digest_sign_fn qat_sm2sig_digest_sign; static OSSL_FUNC_signature_digest_verify_fn qat_sm2sig_digest_verify; # endif # ifdef ENABLE_QAT_HW_SM2 static OSSL_FUNC_signature_digest_sign_update_fn qat_sm2sig_digest_signverify_update; static OSSL_FUNC_signature_digest_sign_final_fn qat_sm2sig_digest_sign_final; static OSSL_FUNC_signature_digest_verify_update_fn qat_sm2sig_digest_signverify_update; static OSSL_FUNC_signature_digest_verify_final_fn qat_sm2sig_digest_verify_final; # endif static OSSL_FUNC_signature_digest_verify_init_fn qat_sm2sig_digest_signverify_init; static OSSL_FUNC_signature_freectx_fn qat_sm2sig_freectx; static OSSL_FUNC_signature_dupctx_fn qat_sm2sig_dupctx; static OSSL_FUNC_signature_get_ctx_params_fn qat_sm2sig_get_ctx_params; static OSSL_FUNC_signature_gettable_ctx_params_fn qat_sm2sig_gettable_ctx_params; static OSSL_FUNC_signature_set_ctx_params_fn qat_sm2sig_set_ctx_params; static OSSL_FUNC_signature_settable_ctx_params_fn qat_sm2sig_settable_ctx_params; static OSSL_FUNC_signature_get_ctx_md_params_fn qat_sm2sig_get_ctx_md_params; static OSSL_FUNC_signature_gettable_ctx_md_params_fn qat_sm2sig_gettable_ctx_md_params; static OSSL_FUNC_signature_set_ctx_md_params_fn qat_sm2sig_set_ctx_md_params; static OSSL_FUNC_signature_settable_ctx_md_params_fn qat_sm2sig_settable_ctx_md_params; typedef struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; OSSL_FUNC_signature_sign_fn *sign; OSSL_FUNC_signature_verify_init_fn *verify_init; OSSL_FUNC_signature_verify_fn *verify; OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; OSSL_FUNC_signature_verify_recover_fn *verify_recover; OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; OSSL_FUNC_signature_digest_sign_fn *digest_sign; OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; OSSL_FUNC_signature_digest_verify_fn *digest_verify; OSSL_FUNC_signature_freectx_fn *freectx; OSSL_FUNC_signature_dupctx_fn *dupctx; OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } QAT_EVP_SIGNATURE /* EVP_SIGNATURE for QAT Provider sm2 */; static int qat_sm2sig_set_mdname(QAT_PROV_SM2_CTX *psm2ctx, const char *mdname) { if (psm2ctx->md == NULL) /* We need an SM3 md to compare with */ psm2ctx->md = EVP_MD_fetch(psm2ctx->libctx, psm2ctx->mdname, psm2ctx->propq); if (psm2ctx->md == NULL) return 0; if (mdname == NULL) return 1; if (strlen(mdname) >= sizeof(psm2ctx->mdname) || !EVP_MD_is_a(psm2ctx->md, mdname)) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_DIGEST); return 0; } OPENSSL_strlcpy(psm2ctx->mdname, mdname, sizeof(psm2ctx->mdname)); return 1; } static void *qat_sm2sig_newctx(void *provctx, const char *propq) { QAT_PROV_SM2_CTX *ctx = OPENSSL_zalloc(sizeof(QAT_PROV_SM2_CTX)); if (ctx == NULL) return NULL; ctx->libctx = prov_libctx_of(provctx); if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(ctx); QATerr(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } ctx->mdsize = SM3_DIGEST_LENGTH; strcpy(ctx->mdname, OSSL_DIGEST_NAME_SM3); return ctx; } static int qat_sm2sig_signature_init(void *vpsm2ctx, void *ec, const OSSL_PARAM params[]) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (!qat_prov_is_running() || psm2ctx == NULL) return 0; if (ec == NULL && psm2ctx->ec == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); return 0; } if (ec != NULL) { if (!EC_KEY_up_ref(ec)) return 0; EC_KEY_free(psm2ctx->ec); psm2ctx->ec = ec; } return qat_sm2sig_set_ctx_params(psm2ctx, params); } static int qat_sm2sig_sign(void *vpsm2ctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; int ret; # ifdef ENABLE_QAT_HW_SM2 size_t sltmp; # endif /* SM2 uses ECDSA_size as well */ size_t ecsize = ECDSA_size(ctx->ec); if (sig == NULL) { *siglen = ecsize; return 1; } if (sigsize < (size_t)ecsize) return 0; if (ctx->mdsize != 0 && tbslen != ctx->mdsize) return 0; # ifdef ENABLE_QAT_SW_SM2 ret = mb_ecdsa_sm2_sign(ctx, sig, siglen, sigsize, tbs, tbslen); # endif # ifdef ENABLE_QAT_HW_SM2 ret = qat_sm2_sign(ctx, sig, &sltmp, sigsize, tbs, tbslen); # endif if (ret <= 0) return 0; # ifdef ENABLE_QAT_HW_SM2 *siglen = sltmp; # endif # ifdef ENABLE_QAT_SW_SM2 *siglen = tbslen; # endif return 1; } static int qat_sm2sig_verify(void *vpsm2ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (ctx->mdsize != 0 && tbslen != ctx->mdsize) return 0; # ifdef ENABLE_QAT_SW_SM2 return mb_ecdsa_sm2_verify(ctx, sig, siglen, tbs, tbslen); # endif # ifdef ENABLE_QAT_HW_SM2 return qat_sm2_verify(ctx, sig, siglen, tbs, tbslen); # endif } static void free_md(QAT_PROV_SM2_CTX *ctx) { EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); ctx->mdctx = NULL; ctx->md = NULL; } int qat_sm2sig_compute_z_digest(QAT_PROV_SM2_CTX *ctx) { uint8_t *z = NULL; int ret = 1; if (ctx->flag_compute_z_digest) { /* Only do this once */ ctx->flag_compute_z_digest = 0; if ((z = OPENSSL_zalloc(ctx->mdsize)) == NULL # ifdef ENABLE_QAT_HW_SM2 /* get hashed prefix 'z' of tbs message */ || !qat_hw_sm2_compute_z_digest(z, ctx->md, ctx->id, ctx->id_len, ctx->ec) # endif # ifdef ENABLE_QAT_SW_SM2 || !qat_sm2_compute_z_digest(z, ctx->md, ctx->id, ctx->id_len, ctx->ec) # endif || !EVP_DigestUpdate(ctx->mdctx, z, ctx->mdsize)) ret = 0; OPENSSL_free(z); } return ret; } int qat_sm2sig_digest_signverify_update(void *vpsm2ctx, const unsigned char *data, size_t datalen) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (psm2ctx == NULL || psm2ctx->mdctx == NULL) return 0; return qat_sm2sig_compute_z_digest(psm2ctx) && EVP_DigestUpdate(psm2ctx->mdctx, data, datalen); } # ifdef ENABLE_QAT_HW_SM2 int qat_sm2sig_digest_sign_final(void *vpsm2ctx, unsigned char *sig, size_t *siglen, size_t sigsize) { QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (ctx == NULL || ctx->mdctx == NULL) return 0; /* * If sig is NULL then we're just finding out the sig size. Other fields * are ignored. Defer to sm2sig_sign. */ if (sig != NULL) { if (!(qat_sm2sig_compute_z_digest(ctx) && EVP_DigestFinal_ex(ctx->mdctx, digest, &dlen))) return 0; } return qat_sm2sig_sign(ctx, sig, siglen, sigsize, digest, (size_t)dlen); } # endif static int qat_sm2sig_digest_signverify_init(void *vpsm2ctx, const char *mdname, void *ec, const OSSL_PARAM params[]) { QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; int md_nid; qat_WPACKET pkt; int ret = 0; /* This default value must be assigned before it may be overridden */ ctx->flag_compute_z_digest = 1; if (!qat_sm2sig_signature_init(vpsm2ctx, ec, params) || !qat_sm2sig_set_mdname(ctx, mdname)) return ret; if (ctx->mdctx == NULL) { ctx->mdctx = EVP_MD_CTX_new(); if (ctx->mdctx == NULL) goto error; } md_nid = EVP_MD_get_type(ctx->md); /* * We do not care about DER writing errors. * All it really means is that for some reason, there's no * AlgorithmIdentifier to be had, but the operation itself is * still valid, just as long as it's not used to construct * anything that needs an AlgorithmIdentifier. */ ctx->aid_len = 0; /*WPACKET code implementation kept in qat_prov_hkdf_packet.c*/ if (QAT_WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) && qat_DER_w_algorithmIdentifier_SM2_with_MD(&pkt, -1, ctx->ec, md_nid) && QAT_WPACKET_finish(&pkt)) { QAT_WPACKET_get_total_written(&pkt, &ctx->aid_len); #if OPENSSL_VERSION_NUMBER < 0x30400000 ctx->aid = QAT_WPACKET_get_curr(&pkt); #endif } QAT_WPACKET_cleanup(&pkt); if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) goto error; ret = 1; error: return ret; } # ifdef ENABLE_QAT_SW_SM2 static int qat_sm2sig_digest_sign(void *vpsm2ctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; int ret; size_t ecsize; if (ctx == NULL) { return 0; } /* SM2 uses ECDSA_size as well */ ecsize = ECDSA_size(ctx->ec); if (sig == NULL) { *siglen = ecsize; return 1; } if (sigsize < (size_t)ecsize) return 0; ret = mb_ecdsa_sm2_sign(ctx, sig, siglen, sigsize, tbs, tbslen); if (ret <= 0) return 0; return 1; } static int qat_sm2sig_digest_verify(void *vpsm2ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { int ret = 0; QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (vpsm2ctx == NULL) { return 0; } ret = mb_ecdsa_sm2_verify(ctx, sig, siglen, tbs, tbslen); if (ret <= 0) return 0; return ret; } # endif # ifdef ENABLE_QAT_HW_SM2 int qat_sm2sig_digest_verify_final(void *vpsm2ctx, const unsigned char *sig, size_t siglen) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; if (psm2ctx == NULL || psm2ctx->mdctx == NULL || EVP_MD_get_size(psm2ctx->md) > (int)sizeof(digest)) return 0; if (!(qat_sm2sig_compute_z_digest(psm2ctx) && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen))) return 0; return qat_sm2sig_verify(vpsm2ctx, sig, siglen, digest, (size_t)dlen); } # endif static void qat_sm2sig_freectx(void *vpsm2ctx) { QAT_PROV_SM2_CTX *ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; free_md(ctx); EC_KEY_free(ctx->ec); OPENSSL_free(ctx->id); OPENSSL_free(ctx); } static void *qat_sm2sig_dupctx(void *vpsm2ctx) { QAT_PROV_SM2_CTX *srcctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; QAT_PROV_SM2_CTX *dstctx; dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; *dstctx = *srcctx; dstctx->ec = NULL; dstctx->md = NULL; dstctx->mdctx = NULL; if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec)) goto err; dstctx->ec = srcctx->ec; if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) goto err; dstctx->md = srcctx->md; if (srcctx->mdctx != NULL) { dstctx->mdctx = EVP_MD_CTX_new(); if (dstctx->mdctx == NULL || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) goto err; } if (srcctx->id != NULL) { dstctx->id = OPENSSL_malloc(srcctx->id_len); if (dstctx->id == NULL) goto err; dstctx->id_len = srcctx->id_len; memcpy(dstctx->id, srcctx->id, srcctx->id_len); } return dstctx; err: qat_sm2sig_freectx(dstctx); return NULL; } static int qat_sm2sig_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; OSSL_PARAM *p; if (psm2ctx == NULL) return 0; #if OPENSSL_VERSION_NUMBER < 0x30400000 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); if (p != NULL && !OSSL_PARAM_set_octet_string(p, psm2ctx->aid, psm2ctx->aid_len)) return 0; #endif p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, psm2ctx->mdsize)) return 0; p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, psm2ctx->md == NULL ? psm2ctx->mdname : EVP_MD_get0_name(psm2ctx->md))) return 0; return 1; } static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_END }; static const OSSL_PARAM *qat_sm2sig_gettable_ctx_params(ossl_unused void *vpsm2ctx, ossl_unused void *provctx) { return known_gettable_ctx_params; } static int qat_sm2sig_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[]) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; const OSSL_PARAM *p; size_t mdsize; if (psm2ctx == NULL) return 0; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DIST_ID); if (p != NULL) { void *tmp_id = NULL; size_t tmp_idlen = 0; /* * If the 'z' digest has already been computed, the ID is set too late */ if (!psm2ctx->flag_compute_z_digest) return 0; if (p->data_size != 0 && !OSSL_PARAM_get_octet_string(p, &tmp_id, 0, &tmp_idlen)) return 0; if (psm2ctx->id != NULL) OPENSSL_free(psm2ctx->id); psm2ctx->id = tmp_id; psm2ctx->id_len = tmp_idlen; } /* * The following code checks that the size is the same as the SM3 digest * size returning an error otherwise. * If there is ever any different digest algorithm allowed with SM2 * this needs to be adjusted accordingly. */ p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); if (p != NULL && (!OSSL_PARAM_get_size_t(p, &mdsize) || mdsize != psm2ctx->mdsize)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); if (p != NULL) { char *mdname = NULL; if (!OSSL_PARAM_get_utf8_string(p, &mdname, 0)) return 0; if (!qat_sm2sig_set_mdname(psm2ctx, mdname)) { OPENSSL_free(mdname); return 0; } if (mdname != NULL) OPENSSL_free(mdname); } return 1; } static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DIST_ID, NULL, 0), OSSL_PARAM_END }; static const OSSL_PARAM *qat_sm2sig_settable_ctx_params(ossl_unused void *vpsm2ctx, ossl_unused void *provctx) { return known_settable_ctx_params; } static int qat_sm2sig_get_ctx_md_params(void *vpsm2ctx, OSSL_PARAM *params) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (psm2ctx->mdctx == NULL) return 0; return EVP_MD_CTX_get_params(psm2ctx->mdctx, params); } static const OSSL_PARAM *qat_sm2sig_gettable_ctx_md_params(void *vpsm2ctx) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (psm2ctx->md == NULL) return 0; return EVP_MD_gettable_ctx_params(psm2ctx->md); } static int qat_sm2sig_set_ctx_md_params(void *vpsm2ctx, const OSSL_PARAM params[]) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (psm2ctx->mdctx == NULL) return 0; return EVP_MD_CTX_set_params(psm2ctx->mdctx, params); } static const OSSL_PARAM *qat_sm2sig_settable_ctx_md_params(void *vpsm2ctx) { QAT_PROV_SM2_CTX *psm2ctx = (QAT_PROV_SM2_CTX *)vpsm2ctx; if (psm2ctx->md == NULL) return 0; return EVP_MD_settable_ctx_params(psm2ctx->md); } const OSSL_DISPATCH qat_sm2_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))qat_sm2sig_newctx }, { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))qat_sm2sig_signature_init }, { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))qat_sm2sig_sign }, { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))qat_sm2sig_signature_init }, { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))qat_sm2sig_verify }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))qat_sm2sig_digest_signverify_init }, # ifdef ENABLE_QAT_SW_SM2 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, (void (*)(void))qat_sm2sig_digest_sign }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, (void (*)(void))qat_sm2sig_digest_verify }, # endif { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))qat_sm2sig_digest_signverify_init }, # ifdef ENABLE_QAT_HW_SM2 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, (void (*)(void))qat_sm2sig_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))qat_sm2sig_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, (void (*)(void))qat_sm2sig_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, (void (*)(void))qat_sm2sig_digest_verify_final }, # endif { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))qat_sm2sig_freectx }, { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))qat_sm2sig_dupctx }, { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))qat_sm2sig_get_ctx_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))qat_sm2sig_gettable_ctx_params }, { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))qat_sm2sig_set_ctx_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))qat_sm2sig_settable_ctx_params }, { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, (void (*)(void))qat_sm2sig_get_ctx_md_params }, { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_sm2sig_gettable_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, (void (*)(void))qat_sm2sig_set_ctx_md_params }, { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, (void (*)(void))qat_sm2sig_settable_ctx_md_params }, { 0, NULL } }; #endif qatengine-1.9.0/qat_prov_sign_sm2.h000066400000000000000000000077721500416242000173100ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sign_sm2.h * * This file is for structures and functions declarations for SM2 PROVIDER. * *****************************************************************************/ #ifndef QAT_PROV_SIGN_SM2_H # define QAT_PROV_SIGN_SM2_H # include "qat_prov_ec.h" # include "qat_prov_hkdf_packet.h" # ifdef QAT_OPENSSL_3 # define OSSL_MAX_NAME_SIZE 50 /* Algorithm name */ # define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ # define OSSL_MAX_ALGORITHM_ID_SIZE 256 /* AlgorithmIdentifier DER */ #define DER_OID_V_sm2_with_SM3 QAT_DER_P_OBJECT, 8, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 #define DER_OID_SZ_sm2_with_SM3 10 typedef struct { OSSL_LIB_CTX *libctx; char *propq; EC_KEY *ec; /* * Flag to termine if the 'z' digest needs to be computed and fed to the * hash function. * This flag should be set on initialization and the compuation should * be performed only once, on first update. */ unsigned int flag_compute_z_digest : 1; char mdname[OSSL_MAX_NAME_SIZE]; /* The Algorithm Identifier of the combined signature algorithm */ unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; #if OPENSSL_VERSION_NUMBER < 0x30400000 unsigned char *aid; #endif size_t aid_len; /* main digest */ EVP_MD *md; EVP_MD_CTX *mdctx; size_t mdsize; /* SM2 ID used for calculating the Z value */ unsigned char *id; size_t id_len; const unsigned char *tbs; size_t tbs_len; } QAT_PROV_SM2_CTX; int qat_sm2sig_compute_z_digest(QAT_PROV_SM2_CTX *ctx); #ifdef ENABLE_QAT_HW_SM2 int qat_hw_sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const EC_KEY *key); #endif #ifdef ENABLE_QAT_SW_SM2 int qat_sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const EC_KEY *key); #endif # endif #endif /* QAT_PROV_SIGN_SM2_H */ qatengine-1.9.0/qat_prov_sm3.c000066400000000000000000000240521500416242000162520ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sm3.c * * This file provides an implementation to qatprovider SM3 operations * *****************************************************************************/ #if defined(ENABLE_QAT_HW_SM3) || defined (ENABLE_QAT_SW_SM3) # include # include # include # include # include # include # include # ifdef ENABLE_QAT_HW_SM3 # include "qat_hw_sm3.h" # endif # include "qat_provider.h" # include "qat_utils.h" # include "qat_evp.h" # include "e_qat.h" # define QAT_PROV_DIGEST_FLAG_XOF 0x0001 # define QAT_PROV_DIGEST_FLAG_ALGID_ABSENT 0x0002 # define SM3_DIGEST_LENGTH 32 # define SM3_CBLOCK 64 static OSSL_FUNC_digest_newctx_fn qat_sm3_newctx; static OSSL_FUNC_digest_freectx_fn qat_sm3_freectx; static OSSL_FUNC_digest_dupctx_fn qat_sm3_dupctx; static const OSSL_PARAM qat_digest_default_known_gettable_params[] = { OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_SIZE, NULL), OSSL_PARAM_int(OSSL_DIGEST_PARAM_XOF, NULL), OSSL_PARAM_int(OSSL_DIGEST_PARAM_ALGID_ABSENT, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm3_digest_default_gettable_params(void *provctx) { return qat_digest_default_known_gettable_params; } int qat_sm3_digest_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz, unsigned long flags) { OSSL_PARAM *p = NULL; p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blksz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, paramsz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOF); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & QAT_PROV_DIGEST_FLAG_XOF) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_ALGID_ABSENT); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & QAT_PROV_DIGEST_FLAG_ALGID_ABSENT) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static void *qat_sm3_newctx(void *prov_ctc) { # ifdef ENABLE_QAT_HW_SM3 QAT_SM3_CTX *ctx = qat_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL; # endif # ifdef ENABLE_QAT_SW_SM3 QAT_SM3_CTX_mb *ctx = qat_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL; # endif return ctx; } # ifdef ENABLE_QAT_HW_SM3 static void qat_sm3_free_sw_md_ctx(QAT_SM3_CTX *ctx) { EVP_MD_CTX_free(ctx->sw_md_ctx); EVP_MD_free(ctx->sw_md); ctx->sw_md_ctx = NULL; ctx->sw_md = NULL; } # endif static void qat_sm3_freectx(void *vctx) { # ifdef ENABLE_QAT_HW_SM3 QAT_SM3_CTX *ctx = (QAT_SM3_CTX *)vctx; if (!qat_hw_sm3_cleanup(ctx)){ WARN("qat sm3 ctx cleanup failed.\n"); } if ((qat_hw_sm3_offload) && (!qat_get_qat_offload_disabled())) { # ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD qat_sm3_free_sw_md_ctx(ctx); # endif } else { if (ctx->rcv_count == 0) { qat_sm3_free_sw_md_ctx(ctx); } } # endif # ifdef ENABLE_QAT_SW_SM3 QAT_SM3_CTX_mb *ctx = (QAT_SM3_CTX_mb *)vctx; # endif OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *qat_sm3_dupctx(void *ctx) { # ifdef ENABLE_QAT_HW_SM3 QAT_SM3_CTX *in = (QAT_SM3_CTX *)ctx; QAT_SM3_CTX *ret = qat_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) : NULL; qat_hw_sm3_copy(ret, in); # endif # ifdef ENABLE_QAT_SW_SM3 QAT_SM3_CTX_mb *in = (QAT_SM3_CTX_mb *)ctx; QAT_SM3_CTX_mb *ret = qat_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) : NULL; # endif if (ret != NULL) *ret = *in; # ifdef ENABLE_QAT_HW_SM3 if ((!qat_hw_sm3_offload) || (qat_get_qat_offload_disabled())) { ret->rcv_count = 1; } # endif return ret; } #define QAT_PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ static OSSL_FUNC_digest_get_params_fn qat_name##_get_params; \ static int qat_name##_get_params(OSSL_PARAM params[]) \ { \ return qat_sm3_digest_default_get_params(params, blksize, dgstsize, flags); \ } #define QAT_PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) \ { OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))qat_name##_get_params }, \ { OSSL_FUNC_DIGEST_GETTABLE_PARAMS, \ (void (*)(void))qat_sm3_digest_default_gettable_params } # define QAT_PROV_FUNC_DIGEST_FINAL(name, dgstsize, fin) \ static OSSL_FUNC_digest_final_fn qat_##name##_internal_final; \ static int qat_##name##_internal_final(void *ctx, unsigned char *out, size_t *outl,\ size_t outsz) \ { \ if (qat_prov_is_running() && outsz >= dgstsize && fin(ctx, out)) { \ *outl = dgstsize; \ return 1; \ } \ return 0; \ } # define QAT_PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START( \ name, CTX, blksize, dgstsize, flags, upd, fin) \ QAT_PROV_FUNC_DIGEST_FINAL(name, dgstsize, fin) \ QAT_PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ const OSSL_DISPATCH qat_##name##_functions[] = { \ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))qat_##name##_newctx }, \ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))upd }, \ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))qat_##name##_internal_final }, \ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))qat_##name##_freectx }, \ { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))qat_##name##_dupctx }, \ QAT_PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) # define QAT_PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END \ { 0, NULL } \ }; # define QAT_PROV_IMPLEMENT_digest_functions( \ name, CTX, blksize, dgstsize, flags, init, upd, fin) \ static OSSL_FUNC_digest_init_fn qat_##name##_internal_init; \ static int qat_##name##_internal_init(void *ctx, \ ossl_unused const OSSL_PARAM params[]) \ { \ return qat_prov_is_running() && init(ctx); \ } \ QAT_PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, flags, \ upd, fin), \ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))qat_##name##_internal_init }, \ QAT_PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END /* qat_sm3_functions */ # ifdef ENABLE_QAT_HW_SM3 QAT_PROV_IMPLEMENT_digest_functions(sm3, QAT_SM3_CTX, SM3_CBLOCK, SM3_DIGEST_LENGTH, 0, qat_hw_sm3_init, qat_hw_sm3_update, qat_hw_sm3_final) # endif # ifdef ENABLE_QAT_SW_SM3 QAT_PROV_IMPLEMENT_digest_functions(sm3, QAT_SM3_CTX_mb, SM3_CBLOCK, SM3_DIGEST_LENGTH, 0, qat_sw_sm3_init, qat_sw_sm3_update, qat_sw_sm3_final) # endif #endif /* ENABLE_QAT_HW_SM3 || ENABLE_QAT_SW_SM3 */ qatengine-1.9.0/qat_prov_sm4_cbc.c000066400000000000000000000744461500416242000170760ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @qat_prov_sm4_cbc.c * * This file contains the qatprovider implementation for SM4-CBC operations * *****************************************************************************/ #include #include "qat_provider.h" #include "qat_prov_sm4_cbc.h" #include "qat_utils.h" #include "e_qat.h" #ifdef ENABLE_QAT_SW_SM4_CBC # include "qat_sw_sm4_cbc.h" #endif #ifdef ENABLE_QAT_HW_SM4_CBC # include "qat_hw_sm4_cbc.h" #endif #include "qat_constant_time.h" #define ossl_assert(x) ((x) != 0) #define UNINITIALISED_SIZET ((int)-1) /* Max padding including padding length byte */ # define MAX_PADDING 256 # define SSL3_VERSION 0x0300 #if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) static OSSL_FUNC_cipher_freectx_fn qat_sm4_cbc_freectx; OSSL_FUNC_cipher_get_ctx_params_fn qat_sm4_cbc_get_ctx_params; OSSL_FUNC_cipher_gettable_ctx_params_fn qat_sm4_cbc_generic_gettable_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn qat_sm4_cbc_set_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn qat_sm4_cbc_generic_settable_ctx_params; static int qat_sm4_cbc_generic_initiv(QAT_PROV_CBC_CTX *ctx, const unsigned char *iv, size_t ivlen) { if (ivlen != ctx->ivlen || ivlen > sizeof(ctx->iv)) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } ctx->iv_set = 1; memcpy(ctx->iv, iv, ivlen); memcpy(ctx->oiv, iv, ivlen); return 1; } static int qat_ssl3_cbc_copy_mac(size_t *reclen, size_t origreclen, unsigned char *recdata, unsigned char **mac, int *alloced, size_t block_size, size_t mac_size, size_t good, OSSL_LIB_CTX *libctx) { unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; unsigned char *rotated_mac; unsigned char randmac[EVP_MAX_MD_SIZE]; unsigned char *out; /* * mac_end is the index of |recdata| just after the end of the MAC. */ size_t mac_end = *reclen; size_t mac_start = mac_end - mac_size; size_t in_mac; /* * scan_start contains the number of bytes that we can ignore because the * MAC's position can only vary by 255 bytes. */ size_t scan_start = 0; size_t i, j; size_t rotate_offset; if (!ossl_assert(origreclen >= mac_size && mac_size <= EVP_MAX_MD_SIZE)) return 0; /* If no MAC then nothing to be done */ if (mac_size == 0) { /* No MAC so we can do this in non-constant time */ if (good == 0) return 0; return 1; } *reclen -= mac_size; if (block_size == 1) { /* There's no padding so the position of the MAC is fixed */ if (mac != NULL) *mac = &recdata[*reclen]; if (alloced != NULL) *alloced = 0; return 1; } /* Create the random MAC we will emit if padding is bad */ if (RAND_bytes_ex(libctx, randmac, mac_size, 0) <= 0) return 0; if (!ossl_assert(mac != NULL && alloced != NULL)) return 0; *mac = out = OPENSSL_zalloc(mac_size); if (*mac == NULL) return 0; *alloced = 1; rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); /* This information is public so it's safe to branch based on it. */ if (origreclen > mac_size + 255 + 1) scan_start = origreclen - (mac_size + 255 + 1); in_mac = 0; rotate_offset = 0; memset(rotated_mac, 0, mac_size); for (i = scan_start, j = 0; i < origreclen; i++) { size_t mac_started = qat_constant_time_eq(i, mac_start); size_t mac_ended = qat_constant_time_lt(i, mac_end); unsigned char b = recdata[i]; in_mac |= mac_started; in_mac &= mac_ended; rotate_offset |= j & mac_started; rotated_mac[j++] |= b & in_mac; j &= qat_constant_time_lt(j, mac_size); } /* Now rotate the MAC */ j = 0; for (i = 0; i < mac_size; i++) { /* in case cache-line is 32 bytes, touch second line */ ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; /* If the padding wasn't good we emit a random MAC */ out[j++] = qat_constant_time_select_8((unsigned char)(good & 0xff), rotated_mac[rotate_offset++], randmac[i]); rotate_offset &= qat_constant_time_lt(rotate_offset, mac_size); } return 1; } int qat_tls1_cbc_remove_padding_and_mac(size_t *reclen, size_t origreclen, unsigned char *recdata, unsigned char **mac, int *alloced, size_t block_size, size_t mac_size, int aead, OSSL_LIB_CTX *libctx) { size_t good = -1; size_t padding_length, to_check, i; size_t overhead = ((block_size == 1) ? 0 : 1) /* padding length byte */ + mac_size; /* * These lengths are all public so we can test them in non-constant * time. */ if (overhead > *reclen) return 0; if (block_size != 1) { padding_length = recdata[*reclen - 1]; if (aead) { /* padding is already verified and we don't need to check the MAC */ *reclen -= padding_length + 1 + mac_size; return 1; } good = qat_constant_time_ge(*reclen, overhead + padding_length); /* * The padding consists of a length byte at the end of the record and * then that many bytes of padding, all with the same value as the * length byte. Thus, with the length byte included, there are i+1 bytes * of padding. We can't check just |padding_length+1| bytes because that * leaks decrypted information. Therefore we always have to check the * maximum amount of padding possible. (Again, the length of the record * is public information so we can use it.) */ to_check = 256; /* maximum amount of padding, inc length byte. */ if (to_check > *reclen) to_check = *reclen; for (i = 0; i < to_check; i++) { unsigned char mask = qat_constant_time_ge_8(padding_length, i); unsigned char b = recdata[*reclen - 1 - i]; /* * The final |padding_length+1| bytes should all have the value * |padding_length|. Therefore the XOR should be zero. */ good &= ~(mask & (padding_length ^ b)); } /* * If any of the final |padding_length+1| bytes had the wrong value, one * or more of the lower eight bits of |good| will be cleared. */ good = qat_constant_time_eq(0xff, good & 0xff); *reclen -= good & (padding_length + 1); } return qat_ssl3_cbc_copy_mac(reclen, origreclen, recdata, mac, alloced, block_size, mac_size, good, libctx); } int qat_cipher_tlsunpadblock(OSSL_LIB_CTX *libctx, unsigned int tlsversion, unsigned char *buf, size_t *buflen, size_t blocksize, unsigned char **mac, int *alloced, size_t macsize, int aead) { int ret; if (tlsversion <= 0) return 0; /* Remove the explicit IV */ buf += blocksize; *buflen -= blocksize; /* Fall through */ ret = qat_tls1_cbc_remove_padding_and_mac(buflen, *buflen, buf, mac, alloced, blocksize, macsize, aead, libctx); return ret; } size_t qat_cipher_fillblock(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen) { size_t blockmask = ~(blocksize - 1); size_t bufremain = blocksize - *buflen; assert(*buflen <= blocksize); assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0); if (*inlen < bufremain) bufremain = *inlen; memcpy(buf + *buflen, *in, bufremain); *in += bufremain; *inlen -= bufremain; *buflen += bufremain; return *inlen & blockmask; } int qat_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen) { if (*inlen == 0) return 1; if (*buflen + *inlen > blocksize) { QATerr(ERR_LIB_PROV, QAT_R_INTERNAL_ERROR); return 0; } memcpy(buf + *buflen, *in, *inlen); *buflen += *inlen; *inlen = 0; return 1; } void qat_sm4_cbc_initctx(void *provctx, QAT_PROV_CBC_CTX *ctx, size_t keybits, size_t blkbits, size_t ivbits, uint64_t flags) { if ((flags & PROV_CIPHER_FLAG_INVERSE_CIPHER) != 0) ctx->inverse_cipher = 1; if ((flags & PROV_CIPHER_FLAG_VARIABLE_LENGTH) != 0) ctx->variable_keylength = 1; ctx->nid = NID_sm4_cbc; ctx->pad = 1; ctx->keylen = ((keybits) / 8); ctx->ivlen = ((ivbits) / 8); ctx->mode = EVP_CIPH_CBC_MODE; ctx->blocksize = blkbits / 8; if (provctx != NULL) ctx->libctx = prov_libctx_of(provctx); /* used for rand */ #ifdef ENABLE_QAT_HW_SM4_CBC ctx->qat_cipher_ctx = OPENSSL_zalloc(sizeof(qat_sm4_ctx)); #endif } static void *qat_sm4_cbc_newctx(void *provctx, size_t keybits, size_t blkbits, size_t ivbits, uint64_t flags) { QAT_EVP_CIPHER_SM4_CBC *cipher = NULL; QAT_SM4CBC_CTX *ctx; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); if (!ctx) return NULL; cipher = OPENSSL_zalloc(sizeof(QAT_EVP_CIPHER_SM4_CBC)); if (!cipher) return NULL; cipher->nid = NID_sm4_cbc; ctx->cipher = cipher; qat_sm4_cbc_initctx(provctx, &ctx->base, keybits, blkbits, ivbits, flags); return ctx; } int qat_sm4_cbc_einit(void *vctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, const OSSL_PARAM params[]) { int sts = 0; QAT_PROV_CBC_CTX *ctx = (QAT_PROV_CBC_CTX *) vctx; ctx->num = 0; ctx->bufsz = 0; ctx->updated = 0; ctx->enc = 1; #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) { sts = qat_sw_sm4_cbc_key_init(ctx, inkey, keylen, iv, ivlen, 1); if (sts != 1) { QATerr(ERR_LIB_PROV, QAT_R_EINIT_OPERATION_FAILED); return sts; } } #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) { sts = qat_sm4_cbc_init(ctx, inkey, keylen, iv, ivlen, 1); if (sts != 1) { QATerr(ERR_LIB_PROV, QAT_R_EINIT_OPERATION_FAILED); return sts; } } #endif if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (!qat_sm4_cbc_generic_initiv(ctx, iv, ivlen)) return 0; } if (iv == NULL && ctx->iv_set && (ctx->mode == EVP_CIPH_CBC_MODE\ || ctx->mode == EVP_CIPH_CFB_MODE || ctx->mode == EVP_CIPH_OFB_MODE)) /* reset IV for these modes to keep compatibility with 1.1.1 */ memcpy(ctx->iv, ctx->oiv, ctx->ivlen); if (inkey != NULL) { if (ctx->variable_keylength == 0) { if (keylen != ctx->keylen) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_KEY_LENGTH); return 0; } } else { ctx->keylen = keylen; } } return qat_sm4_cbc_set_ctx_params(ctx, params); } int qat_sm4_cbc_dinit(void *vctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, const OSSL_PARAM params[]) { int sts = 0; QAT_PROV_CBC_CTX *ctx = (QAT_PROV_CBC_CTX *) vctx; ctx->num = 0; ctx->bufsz = 0; ctx->updated = 0; ctx->enc = 0; #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) { sts = qat_sw_sm4_cbc_key_init(ctx, inkey, keylen, iv, ivlen, 0); if (sts != 1) { QATerr(ERR_LIB_PROV, QAT_R_DINIT_OPERATION_FAILED); return sts; } } #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) { sts = qat_sm4_cbc_init(ctx, inkey, keylen, iv, ivlen, 0); if (sts != 1) { QATerr(ERR_LIB_PROV, QAT_R_DINIT_OPERATION_FAILED); return sts; } } #endif if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { if (!qat_sm4_cbc_generic_initiv(ctx, iv, ivlen)) return 0; } if (iv == NULL && ctx->iv_set && (ctx->mode == EVP_CIPH_CBC_MODE || ctx->mode == EVP_CIPH_CFB_MODE || ctx->mode == EVP_CIPH_OFB_MODE)) /* reset IV for these modes to keep compatibility with 1.1.1 */ memcpy(ctx->iv, ctx->oiv, ctx->ivlen); if (inkey != NULL) { if (ctx->variable_keylength == 0) { if (keylen != ctx->keylen) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_KEY_LENGTH); return 0; } } else { ctx->keylen = keylen; } } return qat_sm4_cbc_set_ctx_params(ctx, params); } int qat_sm4_cbc_block_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { size_t outlint = 0; QAT_PROV_CBC_CTX *ctx = (QAT_PROV_CBC_CTX *) vctx; size_t blksz = ctx->blocksize; size_t nextblocks; if (ctx->tlsversion > 0) { /* * Each update call corresponds to a TLS record and is individually * padded */ /* Sanity check inputs */ if (in == NULL || in != out || outsize < inl || !ctx->pad) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); return 0; } if (ctx->enc) { unsigned char padval; size_t padnum, loop; /* Add padding */ padnum = blksz - (inl % blksz); if (outsize < inl + padnum) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); return 0; } if (padnum > MAX_PADDING) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); return 0; } padval = (unsigned char)(padnum - 1); if (ctx->tlsversion == SSL3_VERSION) { if (padnum > 1) memset(out + inl, 0, padnum - 1); *(out + inl + padnum - 1) = padval; } else { /* we need to add 'padnum' padding bytes of value padval */ for (loop = inl; loop < inl + padnum; loop++) out[loop] = padval; } inl += padnum; } if ((inl % blksz) != 0) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); return 0; } #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) { if (qat_sw_sm4_cbc_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) { if (qat_sm4_cbc_do_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif if (ctx->alloced) { OPENSSL_free(ctx->tlsmac); ctx->alloced = 0; ctx->tlsmac = NULL; } if (!ctx->enc && !qat_cipher_tlsunpadblock(ctx->libctx, ctx->tlsversion, out, outl, blksz, &ctx->tlsmac, &ctx->alloced, ctx->tlsmacsize, 0)) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); return 0; } return 1; } if (ctx->bufsz != 0) nextblocks = qat_cipher_fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl); else nextblocks = inl & ~(blksz-1); /* * If we're decrypting and we end an update on a block boundary we hold * the last block back in case this is the last update call and the last * block is padded. */ if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) { if (outsize < blksz) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) { if (qat_sw_sm4_cbc_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) { if (qat_sm4_cbc_do_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif ctx->bufsz = 0; outlint = blksz; out += blksz; } if (nextblocks > 0) { if (!ctx->enc && ctx->pad && nextblocks == inl) { if (!ossl_assert(inl >= blksz)) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } nextblocks -= blksz; } outlint += nextblocks; if (outsize < outlint) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } } if (nextblocks > 0) { #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) { if (qat_sw_sm4_cbc_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) { if (qat_sm4_cbc_do_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif in += nextblocks; inl -= nextblocks; } if (inl != 0 && !qat_cipher_trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) { /* QATerr already called */ return 0; } *outl = outlint; return inl == 0; } int qat_sm4_cbc_block_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { int ret = 0; if (!qat_prov_is_running()) goto end; *outl = 0; ret = 1; end: return ret; } int qat_sm4_cbc_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { int ret = 0; QAT_PROV_CBC_CTX *ctx = (QAT_PROV_CBC_CTX *) vctx; if (!qat_prov_is_running()) goto end; if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) { if (qat_sw_sm4_cbc_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) { if (qat_sm4_cbc_do_cipher(ctx, out, outl, outsize, in, inl) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CBC_OPERATION_FAILED); return 0; } } #endif *outl = inl; ret = 1; end: return ret; } static void qat_sm4_cbc_freectx(void *vctx) { QAT_SM4CBC_CTX *ctx = (QAT_SM4CBC_CTX *) vctx; if (ctx->cipher) { OPENSSL_free(ctx->cipher); ctx->cipher = NULL; } #ifdef ENABLE_QAT_SW_SM4_CBC if (qat_sw_sm4_cbc_offload) qat_sw_sm4_cbc_cleanup((QAT_PROV_CBC_CTX *) ctx); #endif #ifdef ENABLE_QAT_HW_SM4_CBC if (qat_hw_sm4_cbc_offload) qat_sm4_cbc_cleanup((QAT_PROV_CBC_CTX *) ctx); #endif OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void qat_sm4_cbc_copyctx(QAT_PROV_CBC_CTX *dst, const QAT_PROV_CBC_CTX *src) { QAT_PROV_CBC_CTX *sctx = (QAT_PROV_CBC_CTX *)src; QAT_PROV_CBC_CTX *dctx = (QAT_PROV_CBC_CTX *)dst; *dctx = *sctx; } static void *qat_sm4_cbc_dupctx(void *ctx) { QAT_SM4CBC_CTX *in = (QAT_SM4CBC_CTX *)ctx; QAT_SM4CBC_CTX *ret; ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { QATerr(ERR_LIB_PROV, QAT_R_ZALLOC_FAILURE); return NULL; } qat_sm4_cbc_copyctx(&ret->base, &in->base); return ret; } static const OSSL_PARAM qat_sm4_cbc_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_cbc_generic_gettable_params(ossl_unused void *provctx) { return qat_sm4_cbc_known_gettable_params; } int qat_sm4_cbc_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static const OSSL_PARAM qat_sm4_cbc_aead_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_cbc_generic_gettable_ctx_params( ossl_unused void *cctx, ossl_unused void *provctx ) { return qat_sm4_cbc_aead_known_gettable_ctx_params; } static const OSSL_PARAM qat_sm4_cbc_aead_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_cbc_generic_settable_ctx_params( ossl_unused void *cctx, ossl_unused void *provctx ) { return qat_sm4_cbc_aead_known_settable_ctx_params; } int qat_sm4_cbc_get_ctx_params(void *vctx, OSSL_PARAM params[]) { QAT_PROV_CBC_CTX *ctx = (QAT_PROV_CBC_CTX *)vctx; OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen) && !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen) && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS_MAC); if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, ctx->tlsmac, ctx->tlsmacsize)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } int qat_sm4_cbc_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { QAT_PROV_CBC_CTX *ctx = (QAT_PROV_CBC_CTX *)vctx; const OSSL_PARAM *p; if (params == NULL) return 1; p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING); if (p != NULL) { unsigned int pad; if (!OSSL_PARAM_get_uint(p, &pad)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } ctx->pad = pad ? 1 : 0; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_USE_BITS); if (p != NULL) { unsigned int bits; if (!OSSL_PARAM_get_uint(p, &bits)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } ctx->use_bits = bits ? 1 : 0; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION); if (p != NULL) { if (!OSSL_PARAM_get_uint(p, &ctx->tlsversion)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_MAC_SIZE); if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &ctx->tlsmacsize)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM); if (p != NULL) { unsigned int num; if (!OSSL_PARAM_get_uint(p, &num)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } ctx->num = num; } return 1; } /* qat_sm4_cbc_functions */ QAT_sm4_cbc_func(qat_sm4, cbc, CBC, 0, 128, 128, 128, block); #endif qatengine-1.9.0/qat_prov_sm4_cbc.h000066400000000000000000000245101500416242000170660ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sm4_cbc.h * * This file provides an interface to Qat provider SM4-CBC operations * *****************************************************************************/ #ifndef QAT_PROV_SM4_CBC_H # define QAT_PROV_SM4_CBC_H # if defined(ENABLE_QAT_HW_SM4_CBC) || defined(ENABLE_QAT_SW_SM4_CBC) # include # include # include # include # include # include # include # include # include # include # include # include # include # include # ifdef ENABLE_QAT_SW_SM4_CBC # include "crypto_mb/sm4.h" # endif # include "e_qat.h" #define SM4_IV_LEN 16 #define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ # define PROV_CIPHER_FLAG_AEAD 0x0001 # define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 # define PROV_CIPHER_FLAG_CTS 0x0004 # define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 # define PROV_CIPHER_FLAG_RAND_KEY 0x0010 # define QAT_SM4_CBC_BLOCK_SIZE 16 /* Internal flags that are only used within the provider */ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 #define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 typedef struct qat_evp_cipher_st { int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup) (EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; } QAT_EVP_CIPHER_SM4_CBC; typedef struct qat_prov_cbc_ctx_st { int nid; block128_f block; union { cbc128_f cbc; ctr128_f ctr; ecb128_f ecb; } stream; unsigned int mode; size_t keylen; /* key size (in bytes) */ size_t ivlen; size_t blocksize; size_t bufsz; /* Number of bytes in buf */ unsigned int cts_mode; /* Use to set the type for CTS modes */ unsigned int pad : 1; /* Whether padding should be used or not */ unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */ unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */ unsigned int updated : 1; /* Set to 1 during update for one shot ciphers */ unsigned int variable_keylength : 1; unsigned int inverse_cipher : 1; /* set to 1 to use inverse cipher */ unsigned int use_bits : 1; /* Set to 0 for cfb1 to use bits instead of bytes */ unsigned int tlsversion; /* If TLS padding is in use the TLS version number */ unsigned char *tlsmac; /* tls MAC extracted from the last record */ int alloced; /* * Whether the tlsmac data has been allocated or * points into the user buffer. */ size_t tlsmacsize; /* Size of the TLS MAC */ int removetlspad; /* Whether TLS padding should be removed or not */ size_t removetlsfixed; /* * Length of the fixed size data to remove when * processing TLS data (equals mac size plus * IV size if applicable) */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ unsigned int num; /* The original value of the iv */ unsigned char oiv[QAT_SM4_CBC_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ unsigned char buf[QAT_SM4_CBC_BLOCK_SIZE]; unsigned char iv[QAT_SM4_CBC_BLOCK_SIZE]; const void *ks; /* Pointer to algorithm specific key data */ OSSL_LIB_CTX *libctx; #if ENABLE_QAT_HW_SM4_CBC void *qat_cipher_ctx; #endif EVP_CIPHER *sw_cipher; #if ENABLE_QAT_SW_SM4_CBC sm4_key key; #endif void *sw_ctx; } QAT_PROV_CBC_CTX; typedef struct qat_sm4cbc_ctx_st { QAT_PROV_CBC_CTX base; QAT_EVP_CIPHER_SM4_CBC *cipher; }QAT_SM4CBC_CTX; #define QAT_sm4_cbc_func(alg, lc, UCMODE, flags, kbits, blkbits, ivbits, typ) \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ return qat_sm4_cbc_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits, blkbits, ivbits, flags); \ } \ const OSSL_DISPATCH alg##_##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void)) alg##kbits##lc##_newctx}, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_##lc##_dupctx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))alg##_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))alg##_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))alg##_##lc##_block_update }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))alg##_##lc##_block_final }, \ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))alg##_##lc##_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void))alg##_##lc##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void))alg##_##lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))alg##_##lc##_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))qat_sm4_cbc_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))qat_sm4_cbc_generic_settable_ctx_params }, \ { 0, NULL } \ } # endif #endif /* QAT_PROV_SM4_CBC_H */ qatengine-1.9.0/qat_prov_sm4_ccm.c000066400000000000000000000442521500416242000171010ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @qat_prov_sm4_ccm.c * * This file contains the qatprovider implementation for SM4-CCM operations * *****************************************************************************/ #include "qat_provider.h" #include "qat_prov_sm4_ccm.h" #include "qat_utils.h" #include "e_qat.h" #include "qat_evp.h" #ifdef ENABLE_QAT_SW_SM4_CCM # include "qat_sw_sm4_ccm.h" #endif #define SM4_CCM_IV_MIN_SIZE (64 / 8) #define UNINITIALISED_SIZET ((size_t)-1) #define UNINITIALISED_INT ((int)-1) #define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) #ifdef ENABLE_QAT_SW_SM4_CCM void qat_sm4_ccm_init_ctx(void *provctx, QAT_PROV_CCM_CTX *ctx, size_t keybits, size_t ivlen_min) { ctx->key_len = keybits / 8; ctx->key_set = 0; ctx->iv_set = 1; ctx->tag_set = 0; ctx->len_set = 0; ctx->L = 8; ctx->M = 12; ctx->tls_aad_len = UNINITIALISED_SIZET; ctx->pad = 1; ctx->mode = EVP_CIPH_CCM_MODE; ctx->tag_len = UNINITIALISED_INT; ctx->ivlen_min = ivlen_min; ctx->libctx = prov_libctx_of(provctx); ctx->iv_len = (EVP_CCM_TLS_FIXED_IV_LEN + EVP_CCM_TLS_EXPLICIT_IV_LEN); } static void *qat_sm4_ccm_newctx(void *provctx, size_t keybits, int nid) { QAT_PROV_SM4_CCM_CTX *ctx = NULL; QAT_EVP_CIPHER *cipher; if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); cipher = OPENSSL_zalloc(sizeof(QAT_EVP_CIPHER)); cipher->nid = nid; ctx->cipher = cipher; if (!qat_sw_sm4_ccm_offload) { QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (!ctx->base.sw_ctx) ctx->base.sw_ctx = sm4_ccm_cipher.newctx(ctx); } if (ctx != NULL) { qat_sm4_ccm_init_ctx(provctx, &ctx->base, keybits, SM4_CCM_IV_MIN_SIZE); } return ctx; } size_t qat_sm4_ccm_get_ivlen(QAT_PROV_CCM_CTX *ctx) { return 15 - ctx->L; } int qat_sm4_ccm_einit(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) { int sts = 0; if (qat_sw_sm4_ccm_offload) { sts = qat_sw_sm4_ccm_init(ctx, inkey, keylen, iv, ivlen, 1); } else { QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); sts = sm4_ccm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } return sts; } int qat_sm4_ccm_dinit(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) { int sts = 0; if (qat_sw_sm4_ccm_offload) { sts = qat_sw_sm4_ccm_init(ctx, inkey, keylen, iv, ivlen, 0); } else { QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *) ctx; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); sts = sm4_ccm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } return sts; } int qat_sm4_ccm_stream_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { int ret = 0; QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; if (inl == 0) { *outl = 0; ret = 1; goto end; } if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } if (qat_sw_sm4_ccm_offload) { if ((ret = qat_sw_sm4_ccm_do_cipher(ctx, out, outl, outsize, in, inl)) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); goto end; } } else { QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (sm4_ccm_cipher.cupdate == NULL) return 0; if (sm4_ccm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) { return 0; } } ret = 1; end: return ret; } int qat_sm4_ccm_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { int ret = 0; int i = 0; QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; if (!qat_prov_is_running()) goto end; if (qat_sw_sm4_ccm_offload) { i = qat_sw_sm4_ccm_do_cipher(ctx, out, outl, outsize, NULL, 0); } else { QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (sm4_ccm_cipher.cfinal == NULL) return 0; i = sm4_ccm_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); } if (i <= 0) goto end; *outl = 0; ret = 1; end: return ret; } int qat_sm4_ccm_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { int ret = 0; QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; if (!qat_prov_is_running()) goto end; if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } if (qat_sw_sm4_ccm_offload) { if (qat_sw_sm4_ccm_do_cipher(ctx, out, outl, outsize, in, inl) <= 0) { goto end; } } else { QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (sm4_ccm_cipher.cupdate == NULL) return 0; if (sm4_ccm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) { return 0; } } *outl = inl; ret = 1; end: return ret; } int qat_sm4_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]) { QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; OSSL_PARAM *p; if (qat_sw_sm4_ccm_offload != 1) { QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); return sm4_ccm_cipher.get_ctx_params(ctx->sw_ctx, params); } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, qat_sm4_ccm_get_ivlen(ctx))) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_len)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); if (p != NULL) { size_t m = ctx->M; if (!OSSL_PARAM_set_size_t(p, m)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (qat_sm4_ccm_get_ivlen(ctx) > p->data_size) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (qat_sm4_ccm_get_ivlen(ctx) > p->data_size) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (!ctx->enc || !ctx->tag_set) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); return 0; } if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } if (qat_sw_sm4_ccm_offload) qat_sw_sm4_ccm_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, p->data_size, p->data); ctx->tag_set = 0; ctx->iv_set = 0; ctx->len_set = 0; } return 1; } int qat_sm4_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { QAT_PROV_CCM_CTX *ctx = (QAT_PROV_CCM_CTX *) vctx; const OSSL_PARAM *p; size_t sz = 0; if (params == NULL) return 1; if (qat_sw_sm4_ccm_offload != 1) { QAT_EVP_CIPHER sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); return sm4_ccm_cipher.set_ctx_params(ctx->sw_ctx, params); } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if ((p->data_size & 1) || (p->data_size < 4) || p->data_size > 16) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); return 0; } if (p->data != NULL) { if (ctx->enc) { QATerr(ERR_LIB_PROV, QAT_R_TAG_NOT_NEEDED); return 0; } memcpy(ctx->buf, p->data, p->data_size); ctx->tag_set = 1; } if (qat_sw_sm4_ccm_offload) qat_sw_sm4_ccm_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, p->data_size, p->data); ctx->M = p->data_size; if (ctx->sw_ctx != NULL) { PROV_CCM_CTX *sctx = (PROV_CCM_CTX *) ctx->sw_ctx; memcpy(sctx->buf, p->data, p->data_size); sctx->m = p->data_size; sctx->tag_set = 1; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); if (p != NULL) { size_t ivlen; if (!OSSL_PARAM_get_size_t(p, &sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } ivlen = 15 - sz; if (ivlen < 2 || ivlen > 8) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } ctx->L = ivlen; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if (qat_sw_sm4_ccm_offload) sz = qat_sw_sm4_ccm_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data); if (sz == 0) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_DATA); return 0; } ctx->tls_aad_pad_sz = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if (qat_sw_sm4_ccm_offload) { if (qat_sw_sm4_ccm_ctrl (ctx, EVP_CTRL_GCM_SET_IV_FIXED, p->data_size, p->data) == 0) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } } } return 1; } int qat_sm4_ccm_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static OSSL_FUNC_cipher_freectx_fn qat_sm4_ccm_freectx; static void qat_sm4_ccm_freectx(void *vctx) { QAT_PROV_SM4_CCM_CTX *ctx = (QAT_PROV_SM4_CCM_CTX *) vctx; if (ctx->cipher) { OPENSSL_free(ctx->cipher); ctx->cipher = NULL; } if (qat_sw_sm4_ccm_offload) qat_sw_sm4_ccm_cleanup(&ctx->base); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static const OSSL_PARAM qat_sm4_ccm_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_ccm_generic_gettable_params(ossl_unused void *provctx) { return qat_sm4_ccm_known_gettable_params; } static const OSSL_PARAM qat_sm4_ccm_aead_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_ccm_aead_gettable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_sm4_ccm_aead_known_gettable_ctx_params; } static const OSSL_PARAM qat_sm4_ccm_aead_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_ccm_aead_settable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_sm4_ccm_aead_known_settable_ctx_params; } /* qat_sm4_128_ccm_functions */ QAT_sm4_cipher(qat_sm4, ccm, CCM, AEAD_FLAGS, 128, 8, 96, NID_sm4_ccm); #endif qatengine-1.9.0/qat_prov_sm4_ccm.h000066400000000000000000000266111500416242000171050ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sm4_ccm.h * * This file provides an interface to QAT provider SM4-CCM operations * *****************************************************************************/ #ifndef QAT_PROV_SM4_CCM_H # define QAT_PROV_SM4_CCM_H # ifdef ENABLE_QAT_SW_SM4_CCM # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include "qat_utils.h" # include "e_qat.h" /* Crypto_mb includes */ # include "crypto_mb/sm4_ccm.h" # include "qat_sw_sm4_ccm.h" # define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ # define GENERIC_BLOCK_SIZE 16 # define PROV_CIPHER_FLAG_AEAD 0x0001 # define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 # define PROV_CIPHER_FLAG_CTS 0x0004 # define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 # define PROV_CIPHER_FLAG_RAND_KEY 0x0010 # define OSSL_UNION_ALIGN \ double align; \ ossl_uintmax_t align_int; \ void *align_ptr typedef struct qat_evp_cipher_st { int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup)(EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; } QAT_EVP_CIPHER; /* Base structure that is shared by AES & ARIA for CCM MODE */ typedef struct prov_ccm_st { SM4_CCM_CTX_mb16 mb_ccmctx; int init_flag; unsigned char *key; int key_len; int key_set; /* Set if key initialized */ unsigned char *tls_aad; int aad_len; size_t tls_aad_len; /* TLS AAD length */ unsigned int tls_aad_set; unsigned char *tag; unsigned char *calculated_tag; int tag_len; unsigned int tag_set; unsigned int tag_calculated; unsigned char *iv; unsigned char *next_iv; int iv_len; unsigned int iv_set; int iv_gen; int msg_len; /* Message Length */ int len_set; /* Set if message length set */ int L, M; /* L and M parameters from RFC3610 */ EVP_CIPHER_CTX *sw_ctx; unsigned int mode; size_t ivlen_min; size_t tls_aad_pad_sz; uint64_t tls_enc_records; /* Number of TLS records encrypted */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ size_t num; size_t bufsz; /* Number of bytes in buf */ unsigned int enc:1; unsigned int pad:1; /* Whether padding should be used or not */ unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ unsigned char buf[GENERIC_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ OSSL_LIB_CTX *libctx; /* needed for rand calls */ ctr128_f str; CCM128_CONTEXT ccm_ctx; } QAT_PROV_CCM_CTX; typedef struct prov_sm4_ccm_ctx_st { QAT_PROV_CCM_CTX base; /* must be first entry in struct */ QAT_EVP_CIPHER *cipher; } QAT_PROV_SM4_CCM_CTX; typedef struct prov_sm4_ccm_st { unsigned int enc:1; unsigned int key_set:1; /* Set if key initialised */ unsigned int iv_set:1; /* Set if an iv is set */ unsigned int tag_set:1; /* Set if tag is valid */ unsigned int len_set:1; /* Set if message length set */ size_t l, m; /* L and M parameters from RFC3610 */ size_t keylen; size_t tls_aad_len; /* TLS AAD length */ size_t tls_aad_pad_sz; unsigned char iv[GENERIC_BLOCK_SIZE]; unsigned char buf[GENERIC_BLOCK_SIZE]; CCM128_CONTEXT ccm_ctx; ccm128_f str; } PROV_CCM_CTX; size_t qat_sm4_ccm_get_ivlen(QAT_PROV_CCM_CTX * ctx); void qat_sm4_ccm_init_ctx(void *provctx, QAT_PROV_CCM_CTX * ctx, size_t keybits, size_t ivlen_min); int qat_sm4_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]); int qat_sm4_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]); int qat_sm4_ccm_einit(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_sm4_ccm_dinit(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_sm4_ccm_stream_update(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); int qat_sm4_ccm_stream_final(void *ctx, unsigned char *out, size_t *outl, size_t outsize); int qat_sm4_ccm_cipher(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); QAT_EVP_CIPHER qat_get_default_cipher_sm4_ccm(); # define QAT_sm4_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits,nid) \ static OSSL_FUNC_cipher_get_params_fn alg##_##lc##_get_params; \ static int alg##_##lc##_get_params(OSSL_PARAM params[]) \ { \ return qat_sm4_ccm_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lc##_newctx; \ static void *alg##_##kbits##_##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits, nid); \ } \ const OSSL_DISPATCH alg##_##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##_##kbits##_##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))alg##_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))alg##_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))alg##_##lc##_stream_update }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))alg##_##lc##_stream_final }, \ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))alg##_##lc##_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##lc##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))alg##_##lc##_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))alg##_##lc##_aead_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))alg##_##lc##_aead_settable_ctx_params }, \ { 0, NULL } \ } # endif /* ENABLE_QAT_SW_SM4_CCM */ #endif /* QAT_PROV_SM4_CCM_H */ qatengine-1.9.0/qat_prov_sm4_gcm.c000066400000000000000000000433611500416242000171050ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @qat_prov_sm4_gcm.c * * This file contains the qatprovider implementation for SM4-GCM operations * *****************************************************************************/ #include "qat_provider.h" #include "qat_prov_sm4_gcm.h" #include "qat_utils.h" #include "e_qat.h" #ifdef ENABLE_QAT_SW_SM4_GCM # include "qat_sw_sm4_gcm.h" #endif #define SM4_GCM_IV_MIN_SIZE (64 / 8) #define UNINITIALISED_SIZET ((int)-1) #define AEAD_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) #ifdef ENABLE_QAT_SW_SM4_GCM void qat_sm4_gcm_initctx(void *provctx, QAT_PROV_GCM_CTX *ctx, size_t keybits, size_t ivlen_min) { ctx->pad = 1; ctx->mode = EVP_CIPH_GCM_MODE; ctx->tag_len = UNINITIALISED_SIZET; ctx->tls_aad_len = UNINITIALISED_SIZET; ctx->ivlen_min = ivlen_min; ctx->iv_len = (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN); ctx->key_len = keybits / 8; ctx->libctx = prov_libctx_of(provctx); } static void *qat_sm4_gcm_newctx(void *provctx, size_t keybits, int nid) { QAT_EVP_CIPHER_SM4_GCM *cipher = NULL; QAT_SM4GCM_CTX *ctx; QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (!qat_prov_is_running()) return NULL; ctx = OPENSSL_zalloc(sizeof(*ctx)); cipher = OPENSSL_zalloc(sizeof(QAT_EVP_CIPHER_SM4_GCM)); cipher->nid = nid; ctx->cipher = cipher; if (!ctx->base.sw_ctx) ctx->base.sw_ctx = sm4_gcm_cipher.newctx(ctx); if (ctx != NULL) qat_sm4_gcm_initctx(provctx, &ctx->base, keybits, SM4_GCM_IV_MIN_SIZE); return ctx; } int qat_sm4_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) { QAT_PROV_GCM_CTX *ctx = (QAT_PROV_GCM_CTX *) vctx; OSSL_PARAM *p; size_t sz; if (qat_sw_sm4_gcm_offload != 1) { QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); return sm4_gcm_cipher.get_ctx_params(ctx->sw_ctx, params); } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->iv_len)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_len)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); if (p != NULL) { size_t taglen = (ctx->tag_len != UNINITIALISED_SIZET) ? ctx->tag_len : SM4_GCM_TAG_MAX_SIZE; if (!OSSL_PARAM_set_size_t(p, taglen)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (ctx->iv_len > p->data_size) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->iv_len) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->iv_len)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL) { if (ctx->iv_set == IV_STATE_UNINITIALISED) return 0; if (ctx->iv_len > p->data_size) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->iv_len) && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->iv_len)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { sz = p->data_size; if (sz == 0 || sz > EVP_GCM_TLS_TAG_LEN || !ctx->enc || ctx->tag_len == UNINITIALISED_SIZET) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); return 0; } if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } } return 1; } int qat_sm4_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { QAT_PROV_GCM_CTX *ctx = (QAT_PROV_GCM_CTX *) vctx; const OSSL_PARAM *p; size_t sz = 0; void *vp; if (params == NULL) return 1; if (qat_sw_sm4_gcm_offload != 1) { QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); return sm4_gcm_cipher.set_ctx_params(ctx->sw_ctx, params); } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { vp = ctx->buf; if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if (sz == 0 || ctx->enc) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_TAG); return 0; } ctx->tag_len = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &sz)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } if (sz == 0 || sz > ctx->iv_len) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_IV_LENGTH); return 0; } ctx->iv_len = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) sz = qat_sw_sm4_gcm_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, p->data_size, p->data); # endif if (sz == 0) { QATerr(ERR_LIB_PROV, QAT_R_INVALID_AAD); return 0; } ctx->tls_aad_pad_sz = sz; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_ctrl (ctx, EVP_CTRL_GCM_SET_IV_FIXED, p->data_size, p->data) == 0) { # endif QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_GET_PARAMETER); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV); if (p != NULL) { if (p->data == NULL || p->data_type != OSSL_PARAM_OCTET_STRING # ifdef ENABLE_QAT_SW_SM4_GCM || !qat_sw_sm4_gcm_ctrl(ctx, EVP_CTRL_GCM_SET_IV_INV, p->data_size, p->data)) # endif return 0; } return 1; } int qat_sm4_gcm_einit(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) { int sts = 0; # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) { sts = qat_sw_sm4_gcm_init(ctx, inkey, keylen, iv, ivlen, 1); } else { QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *) ctx; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); sts = sm4_gcm_cipher.einit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } # endif return sts; } int qat_sm4_gcm_dinit(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc) { int sts = 0; # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) { sts = qat_sw_sm4_gcm_init(ctx, inkey, keylen, iv, ivlen, 0); } else { QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *) ctx; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); sts = sm4_gcm_cipher.dinit(qctx->sw_ctx, inkey, keylen, iv, ivlen, params); } # endif return sts; } int qat_sm4_gcm_stream_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { int ret = 0; # ifdef ENABLE_QAT_SW_SM4_GCM QAT_PROV_GCM_CTX *ctx = (QAT_PROV_GCM_CTX *) vctx; # endif if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) { if ((ret = qat_sw_sm4_gcm_cipher(ctx, out, outl, outsize, in, inl)) <= 0) { QATerr(ERR_LIB_PROV, QAT_R_CIPHER_OPERATION_FAILED); goto end; } } else { QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (sm4_gcm_cipher.cupdate == NULL) return 0; if (sm4_gcm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) { return 0; } } # endif ret = 1; end: return ret; } int qat_sm4_gcm_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { int ret = 0; # ifdef ENABLE_QAT_SW_SM4_GCM QAT_PROV_GCM_CTX *ctx = (QAT_PROV_GCM_CTX *) vctx; # endif int i = 0; if (!qat_prov_is_running()) goto end; # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) { i = qat_sw_sm4_gcm_cipher(ctx, out, outl, outsize, NULL, 0); } else { QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (sm4_gcm_cipher.cfinal == NULL) return 0; i = sm4_gcm_cipher.cfinal(ctx->sw_ctx, out, outl, outsize); } # endif if (i <= 0) goto end; *outl = 0; ret = 1; end: return ret; } int qat_sm4_gcm_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { int ret = 0; # ifdef ENABLE_QAT_SW_SM4_GCM QAT_PROV_GCM_CTX *ctx = (QAT_PROV_GCM_CTX *) vctx; # endif if (!qat_prov_is_running()) goto end; if (outsize < inl) { QATerr(ERR_LIB_PROV, QAT_R_OUTPUT_BUFFER_TOO_SMALL); goto end; } # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) { if (qat_sw_sm4_gcm_cipher(ctx, out, outl, outsize, in, inl) <= 0) goto end; } else { QAT_EVP_CIPHER_SM4_GCM sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (sm4_gcm_cipher.cupdate == NULL) return 0; if (sm4_gcm_cipher.cupdate(ctx->sw_ctx, out, outl, outsize, in, inl) <= 0) { return 0; } } # endif *outl = inl; ret = 1; end: return ret; } static void qat_sm4_gcm_freectx(void *vctx) { QAT_SM4GCM_CTX *ctx = (QAT_SM4GCM_CTX *) vctx; if (ctx->cipher) { OPENSSL_free(ctx->cipher); ctx->cipher = NULL; } # ifdef ENABLE_QAT_SW_SM4_GCM if (qat_sw_sm4_gcm_offload) qat_sw_sm4_gcm_cleanup((QAT_PROV_GCM_CTX *) ctx); # endif OPENSSL_clear_free(ctx, sizeof(*ctx)); } static const OSSL_PARAM qat_sm4_gcm_known_gettable_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_AEAD, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CUSTOM_IV, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_CTS, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK, NULL), OSSL_PARAM_int(OSSL_CIPHER_PARAM_HAS_RAND_KEY, NULL), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_gcm_generic_gettable_params(ossl_unused void *provctx) { return qat_sm4_gcm_known_gettable_params; } int qat_sm4_gcm_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) { QATerr(ERR_LIB_PROV, QAT_R_FAILED_TO_SET_PARAMETER); return 0; } return 1; } static const OSSL_PARAM qat_sm4_gcm_aead_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_gcm_aead_gettable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_sm4_gcm_aead_known_gettable_ctx_params; } static const OSSL_PARAM qat_sm4_gcm_aead_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; const OSSL_PARAM *qat_sm4_gcm_aead_settable_ctx_params (ossl_unused void *cctx, ossl_unused void *provctx) { return qat_sm4_gcm_aead_known_settable_ctx_params; } /* qat_sm4gcm_functions */ QAT_sm4_gcm_cipher(qat_sm4, gcm, GCM, AEAD_FLAGS, 128, 8, 96, NID_sm4_gcm); #endif qatengine-1.9.0/qat_prov_sm4_gcm.h000066400000000000000000000250341500416242000171070ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sm4_gcm.h * * This file provides an interface to Qat provider SM4-GCM operations * *****************************************************************************/ #ifndef QAT_PROV_SM4_GCM_H # define QAT_PROV_SM4_GCM_H # ifdef ENABLE_QAT_SW_SM4_GCM # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include "crypto_mb/sm4_gcm.h" # include "e_qat.h" # define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ # define SM4_GCM_TAG_MAX_SIZE 16 # define PROV_CIPHER_FLAG_AEAD 0x0001 # define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 # define PROV_CIPHER_FLAG_CTS 0x0004 # define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 # define PROV_CIPHER_FLAG_RAND_KEY 0x0010 # define SM4_GCM_IV_MAX_SIZE (1024 / 8) # define QAT_SM4_GCM_BLOCK_SIZE 16 typedef struct qat_evp_cipher_st { int nid; int block_size; /* Default value for variable length ciphers */ int key_len; int iv_len; /* Legacy structure members */ /* Various flags */ unsigned long flags; /* How the EVP_CIPHER was created. */ int origin; /* init key */ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); /* encrypt/decrypt data */ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); /* cleanup ctx */ int (*cleanup) (EVP_CIPHER_CTX *); /* how big ctx->cipher_data needs to be */ int ctx_size; /* Populate a ASN1_TYPE with parameters */ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); /* Miscellaneous operations */ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; /* New structure members */ /* Above comment to be removed when legacy has gone */ int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_cipher_newctx_fn *newctx; OSSL_FUNC_cipher_encrypt_init_fn *einit; OSSL_FUNC_cipher_decrypt_init_fn *dinit; OSSL_FUNC_cipher_update_fn *cupdate; OSSL_FUNC_cipher_final_fn *cfinal; OSSL_FUNC_cipher_cipher_fn *ccipher; OSSL_FUNC_cipher_freectx_fn *freectx; OSSL_FUNC_cipher_dupctx_fn *dupctx; OSSL_FUNC_cipher_get_params_fn *get_params; OSSL_FUNC_cipher_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_cipher_gettable_params_fn *gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn *settable_ctx_params; }QAT_EVP_CIPHER_SM4_GCM; typedef struct qat_prov_gcm_ctx_st { SM4_GCM_CTX_mb16 smctx; int init_flag; unsigned char* key; int key_set; /* Set if key initialized */ unsigned char* tls_aad; int aad_len; int tls_aad_len; /* TLS AAD length */ unsigned int tls_aad_set; unsigned char* tag; unsigned char* calculated_tag; int tag_len; unsigned int tag_set; unsigned int tag_calculated; unsigned char* iv; unsigned char* next_iv; int iv_len; unsigned int iv_set; int iv_gen; EVP_CIPHER_CTX *sw_ctx; unsigned int mode; /* The mode that we are using */ size_t key_len; size_t ivlen_min; size_t tls_aad_pad_sz; uint64_t tls_enc_records; /* Number of TLS records encrypted */ /* * num contains the number of bytes of |iv| which are valid for modes that * manage partial blocks themselves. */ size_t num; size_t bufsz; /* Number of bytes in buf */ unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */ unsigned int pad:1; /* Whether padding should be used or not */ unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */ unsigned char buf[QAT_SM4_GCM_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ OSSL_LIB_CTX *libctx; /* needed for rand calls */ ctr128_f ctr; } QAT_PROV_GCM_CTX; typedef struct qat_sm4gcm_ctx_st { QAT_PROV_GCM_CTX base; QAT_EVP_CIPHER_SM4_GCM *cipher; }QAT_SM4GCM_CTX; int QAT_SM4_GCM_CTX_get_nid(const QAT_SM4GCM_CTX *ctx); void qat_sm4_gcm_initctx(void *provctx, QAT_PROV_GCM_CTX *ctx, size_t keybits, size_t ivlen_min); int qat_sm4_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]); int qat_sm4_gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[]); int qat_sm4_gcm_einit(void *ctx, const unsigned char* inkey, int keylen, const unsigned char* iv, int ivlen, int enc); int qat_sm4_gcm_dinit(void *ctx, const unsigned char* inkey, int keylen, const unsigned char* iv, int ivlen, int enc); int qat_sm4_gcm_stream_update(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); int qat_sm4_gcm_stream_final(void *ctx, unsigned char *out, size_t *outl, size_t outsize); int qat_sm4_gcm_cipher(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl); QAT_EVP_CIPHER_SM4_GCM get_default_cipher_sm4_gcm(); # define QAT_sm4_gcm_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits, nid) \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ return qat_sm4_gcm_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits, nid); \ } \ const OSSL_DISPATCH alg##_##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))alg##_##lc##_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))alg##_##lc##_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))alg##_##lc##_stream_update }, \ { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))alg##_##lc##_stream_final }, \ { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))alg##_##lc##_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))qat_sm4_gcm_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))qat_sm4_gcm_aead_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ (void (*)(void))qat_sm4_gcm_aead_settable_ctx_params }, \ { 0, NULL } \ } # endif /* ENABLE_QAT_SW_SM4_GCM */ #endif /* QAT_PROV_SM4_GCM_H */ qatengine-1.9.0/qat_provider.cnf000066400000000000000000000004221500416242000166530ustar00rootroot00000000000000[qatengine_sect] activate = 1 enable_external_polling = 0 enable_heuristic_polling = 0 enable_sw_fallback = 0 enable_inline_polling = 0 qat_poll_interval = 10000 qat_epoll_timeout = 1000 enable_event_driven_polling = 0 enable_instance_for_thread = 0 qat_max_retry_count = 5 qatengine-1.9.0/qat_provider.h000066400000000000000000000131641500416242000163430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_provider.h * * This file provides an interface to qat provider init * *****************************************************************************/ #ifndef QAT_PROVIDER_H # define QAT_PROVIDER_H # include # include # include # include # define QAT_PROVIDER_VERSION_STR "v1.9.0" # define QAT_PROVIDER_FULL_VERSION_STR "QAT Provider v1.9.0" # if defined(QAT_HW) && defined(QAT_SW) # define QAT_PROVIDER_NAME_STR "QAT Provider for QAT_HW and QAT_SW" # elif QAT_HW # define QAT_PROVIDER_NAME_STR "QAT Provider for QAT_HW" # else # define QAT_PROVIDER_NAME_STR "QAT Provider for QAT_SW" # endif # define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) # define QAT_NAMES_AES_128_GCM "AES-128-GCM" # define QAT_NAMES_AES_192_GCM "AES-192-GCM" # define QAT_NAMES_AES_256_GCM "AES-256-GCM" # define QAT_NAMES_AES_128_CCM "AES-128-CCM" # define QAT_NAMES_AES_192_CCM "AES-192-CCM" # define QAT_NAMES_AES_256_CCM "AES-256-CCM" # define QAT_NAMES_AES_128_CBC_HMAC_SHA1 "AES-128-CBC-HMAC-SHA1" # define QAT_NAMES_AES_256_CBC_HMAC_SHA1 "AES-256-CBC-HMAC-SHA1" # define QAT_NAMES_AES_128_CBC_HMAC_SHA256 "AES-128-CBC-HMAC-SHA256" # define QAT_NAMES_AES_256_CBC_HMAC_SHA256 "AES-256-CBC-HMAC-SHA256" # define QAT_NAMES_CHACHA20_POLY1305 "ChaCha20-Poly1305" # define QAT_NAMES_SM4_CCM "SM4-CCM:1.2.156.10197.1.104.9" # define QAT_NAMES_SM4_GCM "SM4-GCM:1.2.156.10197.1.104.8" # define QAT_NAMES_SM4_CBC "SM4-CBC:SM4:1.2.156.10197.1.104.2" # define QAT_NAMES_SHA2_224 "SHA2-224:SHA-224:SHA224:2.16.840.1.101.3.4.2.4" # define QAT_NAMES_SHA2_256 "SHA2-256:SHA-256:SHA256:2.16.840.1.101.3.4.2.1" # define QAT_NAMES_SHA2_384 "SHA2-384:SHA-384:SHA384:2.16.840.1.101.3.4.2.2" # define QAT_NAMES_SHA2_512 "SHA2-512:SHA-512:SHA512:2.16.840.1.101.3.4.2.3" # define QAT_NAMES_SHA3_224 "SHA3-224:2.16.840.1.101.3.4.2.7" # define QAT_NAMES_SHA3_256 "SHA3-256:2.16.840.1.101.3.4.2.8" # define QAT_NAMES_SHA3_384 "SHA3-384:2.16.840.1.101.3.4.2.9" # define QAT_NAMES_SHA3_512 "SHA3-512:2.16.840.1.101.3.4.2.10" # define QAT_NAMES_SM3 "SM3:1.2.156.10197.1.401" # define ALGC(NAMES, FUNC, CHECK) { { NAMES, QAT_DEFAULT_PROPERTIES, FUNC }, CHECK } # define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL) static const char QAT_DEFAULT_PROPERTIES[] = "provider=qatprovider"; OSSL_FUNC_provider_get_capabilities_fn qat_prov_get_capabilities; typedef struct bio_method_st { int type; char *name; int (*bwrite) (BIO *, const char *, size_t, size_t *); int (*bwrite_old) (BIO *, const char *, int); int (*bread) (BIO *, char *, size_t, size_t *); int (*bread_old) (BIO *, char *, int); int (*bputs) (BIO *, const char *); int (*bgets) (BIO *, char *, int); long (*ctrl) (BIO *, int, long, void *); int (*create) (BIO *); int (*destroy) (BIO *); long (*callback_ctrl) (BIO *, int, BIO_info_cb *); } QAT_BIO_METHOD; typedef struct qat_provider_ctx_st { const OSSL_CORE_HANDLE *handle; OSSL_LIB_CTX *libctx; QAT_BIO_METHOD *corebiometh; } QAT_PROV_CTX; typedef struct qat_provider_params_st { char *enable_external_polling; char *enable_heuristic_polling; char *enable_sw_fallback; char *enable_inline_polling; char *qat_poll_interval; char *qat_epoll_timeout; char *enable_event_driven_polling; char *enable_instance_for_thread; char *qat_max_retry_count; } QAT_PROV_PARAMS; typedef struct qat_ag_capable_st { OSSL_ALGORITHM alg; int (*capable)(void); } OSSL_ALGORITHM_CAPABLE; void qat_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in, OSSL_ALGORITHM *out); int qat_prov_is_running(void); OSSL_LIB_CTX *prov_libctx_of(QAT_PROV_CTX *ctx); int qat_securitycheck_enabled(OSSL_LIB_CTX *libctx); #endif /* QAT_PROVIDER_H */ qatengine-1.9.0/qat_self_test_data.inc000066400000000000000000002324241500416242000200160ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_self_test_data.inc * * This file provides macros to build Self test data * *****************************************************************************/ /* Macros to build Self test data */ #define ITM(x) ((void *)&x), sizeof(x) #define ITM_STR(x) ((void *)&x), (sizeof(x) - 1) #define ST_KAT_PARAM_END() { "", 0, NULL, 0 } #define ST_KAT_PARAM_BIGNUM(name, data) \ { name, OSSL_PARAM_UNSIGNED_INTEGER, ITM(data) } #define ST_KAT_PARAM_OCTET(name, data) \ { name, OSSL_PARAM_OCTET_STRING, ITM(data) } #define ST_KAT_PARAM_UTF8STRING(name, data) \ { name, OSSL_PARAM_UTF8_STRING, ITM_STR(data) } #define ST_KAT_PARAM_UTF8CHAR(name, data) \ { name, OSSL_PARAM_UTF8_STRING, ITM(data) } #define ST_KAT_PARAM_INT(name, i) \ { name, OSSL_PARAM_INTEGER, ITM(i) } #define QAT_SELF_TEST_DESC_KA_ECDHP256 "ECDHP256" #define QAT_SELF_TEST_DESC_KA_ECDHP384 "ECDHP384" #define QAT_SELF_TEST_DESC_KA_ECX25519 "ECX25519" #define QAT_SELF_TEST_DESC_KA_ECX448 "ECX448" #define QAT_SELF_TEST_DESC_SIGN_ECDSAP256 "ECDSAP256" #define QAT_SELF_TEST_DESC_SIGN_ECDSAP384 "ECDSAP384" #define QAT_SELF_TEST_DESC_KDF_TLS12_256_PRF "TLS12_PRF_256" #define QAT_SELF_TEST_DESC_KDF_TLS12_384_PRF "TLS12_PRF_384" #define QAT_SELF_TEST_DESC_KDF_TLS13_256_EXTRACT "TLS13_KDF_EXTRACT_256" #define QAT_SELF_TEST_DESC_KDF_TLS13_256_EXPAND "TLS13_KDF_EXPAND_256" #define QAT_SELF_TEST_DESC_KDF_TLS13_384_EXTRACT "TLS13_KDF_EXTRACT_384" #define QAT_SELF_TEST_DESC_KDF_TLS13_384_EXPAND "TLS13_KDF_EXPAND_384" #define QAT_SELF_TEST_DESC_MD_SHA_256 "SHA256" #define QAT_SELF_TEST_DESC_MD_SHA_512 "SHA512" /* used to store raw parameters for keys and algorithms */ typedef struct st_kat_param_st { const char *name; /* an OSSL_PARAM name */ size_t type; /* the type associated with the data */ const void *data; /* unsigned char [], or char [] depending on the type */ size_t data_len; /* the length of the data */ } ST_KAT_PARAM; typedef struct st_kat_st { const char *desc; const char *algorithm; const unsigned char *pt; size_t pt_len; const unsigned char *expected; size_t expected_len; } ST_KAT; #define CIPHER_MODE_ENCRYPT 1 #define CIPHER_MODE_DECRYPT 2 #define CIPHER_MODE_ALL (CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT) typedef ST_KAT ST_KAT_DIGEST; typedef struct st_kat_cipher_st { ST_KAT base; int mode; const unsigned char *key; size_t key_len; const unsigned char *iv; size_t iv_len; const unsigned char *aad; size_t aad_len; const unsigned char *tag; size_t tag_len; } ST_KAT_CIPHER; typedef struct st_kat_kdf_st { const char *desc; const char *algorithm; const ST_KAT_PARAM *params; const unsigned char *expected; size_t expected_len; } ST_KAT_KDF; typedef struct st_kat_drbg_st { const char *desc; const char *algorithm; const char *param_name; char *param_value; const unsigned char *entropyin; size_t entropyinlen; const unsigned char *nonce; size_t noncelen; const unsigned char *persstr; size_t persstrlen; const unsigned char *entropyinpr1; size_t entropyinpr1len; const unsigned char *entropyinpr2; size_t entropyinpr2len; const unsigned char *entropyaddin1; size_t entropyaddin1len; const unsigned char *entropyaddin2; size_t entropyaddin2len; const unsigned char *expected; size_t expectedlen; } ST_KAT_DRBG; typedef struct st_kat_kas_st { const char *desc; const char *algorithm; const ST_KAT_PARAM *key_group; const ST_KAT_PARAM *key_host_data; const ST_KAT_PARAM *key_peer_data; const unsigned char *expected; size_t expected_len; } ST_KAT_KAS; typedef struct st_kat_sign_st { const char *desc; const char *algorithm; const char *mdalgorithm; const ST_KAT_PARAM *key; const unsigned char *sig_expected; /* Set to NULL if this value changes */ size_t sig_expected_len; } ST_KAT_SIGN; typedef struct st_kat_asym_cipher_st { const char *desc; const char *algorithm; int encrypt; const ST_KAT_PARAM *key; const ST_KAT_PARAM *postinit; const unsigned char *in; size_t in_len; const unsigned char *expected; size_t expected_len; } ST_KAT_ASYM_CIPHER; /*- DIGEST TEST DATA */ static const unsigned char sha256_pt[] = "abc"; static const unsigned char sha256_digest[] = { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }; static const unsigned char sha512_pt[] = "xyz"; static const unsigned char sha512_digest[] = { 0x4a, 0x3e, 0xd8, 0x14, 0x7e, 0x37, 0x87, 0x6a, 0xdc, 0x8f, 0x76, 0x32, 0x8e, 0x5a, 0xbc, 0xc1, 0xb4, 0x70, 0xe6, 0xac, 0xfc, 0x18, 0xef, 0xea, 0x01, 0x35, 0xf9, 0x83, 0x60, 0x49, 0x53, 0xa5, 0x8e, 0x18, 0x3c, 0x1a, 0x60, 0x86, 0xe9, 0x1b, 0xa3, 0xe8, 0x21, 0xd9, 0x26, 0xf5, 0xfd, 0xeb, 0x37, 0x76, 0x1c, 0x7c, 0xa0, 0x32, 0x8a, 0x96, 0x3f, 0x5e, 0x92, 0x87, 0x06, 0x75, 0xb7, 0x28 }; static const unsigned char sha3_256_pt[] = { 0xe7, 0x37, 0x21, 0x05 }; static const unsigned char sha3_256_digest[] = { 0x3a, 0x42, 0xb6, 0x8a, 0xb0, 0x79, 0xf2, 0x8c, 0x4c, 0xa3, 0xc7, 0x52, 0x29, 0x6f, 0x27, 0x90, 0x06, 0xc4, 0xfe, 0x78, 0xb1, 0xeb, 0x79, 0xd9, 0x89, 0x77, 0x7f, 0x05, 0x1e, 0x40, 0x46, 0xae }; static const ST_KAT_DIGEST st_kat_digest_tests[] = { #ifdef ENABLE_QAT_SW_SHA2 { QAT_SELF_TEST_DESC_MD_SHA_256, "SHA256", ITM_STR(sha256_pt), ITM(sha256_digest), }, { QAT_SELF_TEST_DESC_MD_SHA_512, "SHA512", ITM_STR(sha512_pt), ITM(sha512_digest), }, #endif #ifdef ENABLE_QAT_HW_SHA3 { OSSL_SELF_TEST_DESC_MD_SHA3, "SHA3-256", ITM(sha3_256_pt), ITM(sha3_256_digest), }, #endif }; /*- CIPHER TEST DATA */ /* DES3 test data */ static const unsigned char des_ede3_cbc_pt[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }; static const unsigned char des_ede3_cbc_key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 }; static const unsigned char des_ede3_cbc_iv[] = { 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17 }; static const unsigned char des_ede3_cbc_ct[] = { 0x20, 0x79, 0xC3, 0xD5, 0x3A, 0xA7, 0x63, 0xE1, 0x93, 0xB7, 0x9E, 0x25, 0x69, 0xAB, 0x52, 0x62, 0x51, 0x65, 0x70, 0x48, 0x1F, 0x25, 0xB5, 0x0F, 0x73, 0xC0, 0xBD, 0xA8, 0x5C, 0x8E, 0x0D, 0xA7 }; /* AES-256 GCM test data */ static const unsigned char aes_256_gcm_key[] = { 0x92, 0xe1, 0x1d, 0xcd, 0xaa, 0x86, 0x6f, 0x5c, 0xe7, 0x90, 0xfd, 0x24, 0x50, 0x1f, 0x92, 0x50, 0x9a, 0xac, 0xf4, 0xcb, 0x8b, 0x13, 0x39, 0xd5, 0x0c, 0x9c, 0x12, 0x40, 0x93, 0x5d, 0xd0, 0x8b }; static const unsigned char aes_256_gcm_iv[] = { 0xac, 0x93, 0xa1, 0xa6, 0x14, 0x52, 0x99, 0xbd, 0xe9, 0x02, 0xf2, 0x1a }; static const unsigned char aes_256_gcm_pt[] = { 0x2d, 0x71, 0xbc, 0xfa, 0x91, 0x4e, 0x4a, 0xc0, 0x45, 0xb2, 0xaa, 0x60, 0x95, 0x5f, 0xad, 0x24 }; static const unsigned char aes_256_gcm_aad[] = { 0x1e, 0x08, 0x89, 0x01, 0x6f, 0x67, 0x60, 0x1c, 0x8e, 0xbe, 0xa4, 0x94, 0x3b, 0xc2, 0x3a, 0xd6 }; static const unsigned char aes_256_gcm_ct[] = { 0x89, 0x95, 0xae, 0x2e, 0x6d, 0xf3, 0xdb, 0xf9, 0x6f, 0xac, 0x7b, 0x71, 0x37, 0xba, 0xe6, 0x7f }; static const unsigned char aes_256_gcm_tag[] = { 0xec, 0xa5, 0xaa, 0x77, 0xd5, 0x1d, 0x4a, 0x0a, 0x14, 0xd9, 0xc5, 0x1e, 0x1d, 0xa4, 0x74, 0xab }; /* AES-ECB test data */ static const unsigned char aes_128_ecb_key[] = { 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 }; static const unsigned char aes_128_ecb_pt[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char aes_128_ecb_ct[] = { 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 }; static const ST_KAT_CIPHER st_kat_cipher_tests[] = { #ifndef OPENSSL_NO_DES { { OSSL_SELF_TEST_DESC_CIPHER_TDES, "DES-EDE3-CBC", ITM(des_ede3_cbc_pt), ITM(des_ede3_cbc_ct) }, CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT, ITM(des_ede3_cbc_key), ITM(des_ede3_cbc_iv), }, #endif { { OSSL_SELF_TEST_DESC_CIPHER_AES_GCM, "AES-256-GCM", ITM(aes_256_gcm_pt), ITM(aes_256_gcm_ct) }, CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT, ITM(aes_256_gcm_key), ITM(aes_256_gcm_iv), ITM(aes_256_gcm_aad), ITM(aes_256_gcm_tag) }, }; /*TLS13-KDF self-test data for SHA256*/ static const char tls13_kdf_digest[] = "SHA256"; static int tls13_kdf_extract_mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; static int tls13_kdf_expand_mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; static const unsigned char tls13_kdf_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20 /* "tls13 " */ }; static const unsigned char tls13_kdf_client_early_secret_label[] = { 0x63, 0x20, 0x65, 0x20, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63 /* "c e traffic"*/ }; static const unsigned char tls13_kdf_psk[] = { 0xF8, 0xAF, 0x6A, 0xEA, 0x2D, 0x39, 0x7B, 0xAF, 0x29, 0x48, 0xA2, 0x5B, 0x28, 0x34, 0x20, 0x06, 0x92, 0xCF, 0xF1, 0x7E, 0xEE, 0x91, 0x65, 0xE4, 0xE2, 0x7B, 0xAB, 0xEE, 0x9E, 0xDE, 0xFD, 0x05 }; static const unsigned char tls13_kdf_client_hello_hash[] = { 0x7c, 0x92, 0xf6, 0x8b, 0xd5, 0xbf, 0x36, 0x38, 0xea, 0x33, 0x8a, 0x64, 0x94, 0x72, 0x2e, 0x1b, 0x44, 0x12, 0x7e, 0x1b, 0x7e, 0x8a, 0xad, 0x53, 0x5f, 0x23, 0x22, 0xa6, 0x44, 0xff, 0x22, 0xb3 }; static const unsigned char tls13_kdf_early_secret[] = { 0x15, 0x3B, 0x63, 0x94, 0xA9, 0xC0, 0x3C, 0xF3, 0xF5, 0xAC, 0xCC, 0x6E, 0x45, 0x5A, 0x76, 0x93, 0x28, 0x11, 0x38, 0xA1, 0xBC, 0xFA, 0x38, 0x03, 0xC2, 0x67, 0x35, 0xDD, 0x11, 0x94, 0xD2, 0x16 }; static const unsigned char tls13_kdf_client_early_traffic_secret[] = { 0xC8, 0x05, 0x83, 0xA9, 0x0E, 0x99, 0x5C, 0x48, 0x96, 0x00, 0x49, 0x2A, 0x5D, 0xA6, 0x42, 0xE6, 0xB1, 0xF6, 0x79, 0xBA, 0x67, 0x48, 0x28, 0x79, 0x2D, 0xF0, 0x87, 0xB9, 0x39, 0x63, 0x61, 0x71 }; static const ST_KAT_PARAM tls13_kdf_early_secret_params[] = { ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, tls13_kdf_extract_mode), ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, tls13_kdf_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, tls13_kdf_psk), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM tls13_kdf_client_early_secret_params[] = { ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, tls13_kdf_expand_mode), ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, tls13_kdf_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, tls13_kdf_early_secret), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_DATA, tls13_kdf_client_hello_hash), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_PREFIX, tls13_kdf_prefix), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_LABEL, tls13_kdf_client_early_secret_label), ST_KAT_PARAM_END() }; /*TLS13-KDF self data for SHA384*/ static const char tls13_kdf_digest_384[] = "SHA384"; static const unsigned char tls13_kdf_early_secret_384[] = { 0x93, 0x7b, 0xba, 0xbb, 0x09, 0x3b, 0xec, 0x63, 0xe7, 0xce, 0xd5, 0x8d, 0x90, 0xf3, 0xf7, 0x72, 0xeb, 0x37, 0x41, 0x87, 0xea, 0x7d, 0x6f, 0x03, 0xc1, 0xfe, 0xe4, 0xe1, 0xac, 0xcb, 0x13, 0x1e }; static const unsigned char tls13_kdf_client_early_traffic_secret_384[] = { 0x2a, 0x5a, 0x1b, 0xe5, 0x79, 0x43, 0xc5, 0x22, 0xc4, 0x9f, 0xa2, 0x7d, 0xe5, 0xef, 0x09, 0xca, 0x3e, 0x66, 0x8f, 0x9c, 0xaf, 0x75, 0x1c, 0x2c, 0xc7, 0x36, 0x0e, 0xd7, 0xe6, 0x19, 0x68, 0x98 }; static const ST_KAT_PARAM tls13_kdf_early_secret_params_sha384[] = { ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, tls13_kdf_extract_mode), ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, tls13_kdf_digest_384), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, tls13_kdf_psk), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM tls13_kdf_client_early_secret_params_sha384[] = { ST_KAT_PARAM_INT(OSSL_KDF_PARAM_MODE, tls13_kdf_expand_mode), ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, tls13_kdf_digest_384), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, tls13_kdf_early_secret_384), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_DATA, tls13_kdf_client_hello_hash), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_PREFIX, tls13_kdf_prefix), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_LABEL, tls13_kdf_client_early_secret_label), ST_KAT_PARAM_END() }; static const char sskdf_digest[] = "SHA224"; static const unsigned char sskdf_secret[] = { 0x6d, 0xbd, 0xc2, 0x3f, 0x04, 0x54, 0x88, 0xe4, 0x06, 0x27, 0x57, 0xb0, 0x6b, 0x9e, 0xba, 0xe1, 0x83, 0xfc, 0x5a, 0x59, 0x46, 0xd8, 0x0d, 0xb9, 0x3f, 0xec, 0x6f, 0x62, 0xec, 0x07, 0xe3, 0x72, 0x7f, 0x01, 0x26, 0xae, 0xd1, 0x2c, 0xe4, 0xb2, 0x62, 0xf4, 0x7d, 0x48, 0xd5, 0x42, 0x87, 0xf8, 0x1d, 0x47, 0x4c, 0x7c, 0x3b, 0x18, 0x50, 0xe9 }; static const unsigned char sskdf_otherinfo[] = { 0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0x43, 0x41, 0x56, 0x53, 0x69, 0x64, 0x3c, 0x83, 0x2e, 0x98, 0x49, 0xdc, 0xdb, 0xa7, 0x1e, 0x9a, 0x31, 0x39, 0xe6, 0x06, 0xe0, 0x95, 0xde, 0x3c, 0x26, 0x4a, 0x66, 0xe9, 0x8a, 0x16, 0x58, 0x54, 0xcd, 0x07, 0x98, 0x9b, 0x1e, 0xe0, 0xec, 0x3f, 0x8d, 0xbe }; static const unsigned char sskdf_expected[] = { 0xa4, 0x62, 0xde, 0x16, 0xa8, 0x9d, 0xe8, 0x46, 0x6e, 0xf5, 0x46, 0x0b, 0x47, 0xb8 }; static const ST_KAT_PARAM sskdf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, sskdf_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, sskdf_secret), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_INFO, sskdf_otherinfo), ST_KAT_PARAM_END() }; static const char x942kdf_digest[] = "SHA1"; static const char x942kdf_cekalg[] = "AES-128-WRAP"; static const unsigned char x942kdf_secret[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 }; static const unsigned char x942kdf_expected[] = { 0xd6, 0xd6, 0xb0, 0x94, 0xc1, 0x02, 0x7a, 0x7d, 0xe6, 0xe3, 0x11, 0x72, 0x94, 0xa3, 0x53, 0x64 }; static const ST_KAT_PARAM x942kdf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, x942kdf_digest), ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_CEK_ALG, x942kdf_cekalg), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, x942kdf_secret), ST_KAT_PARAM_END() }; static const char x963kdf_digest[] = "SHA256"; static const unsigned char x963kdf_otherinfo[] = { 0x75, 0xee, 0xf8, 0x1a, 0xa3, 0x04, 0x1e, 0x33, 0xb8, 0x09, 0x71, 0x20, 0x3d, 0x2c, 0x0c, 0x52 }; static const unsigned char x963kdf_secret[] = { 0x22, 0x51, 0x8b, 0x10, 0xe7, 0x0f, 0x2a, 0x3f, 0x24, 0x38, 0x10, 0xae, 0x32, 0x54, 0x13, 0x9e, 0xfb, 0xee, 0x04, 0xaa, 0x57, 0xc7, 0xaf, 0x7d }; static const unsigned char x963kdf_expected[] = { 0xc4, 0x98, 0xaf, 0x77, 0x16, 0x1c, 0xc5, 0x9f, 0x29, 0x62, 0xb9, 0xa7, 0x13, 0xe2, 0xb2, 0x15, 0x15, 0x2d, 0x13, 0x97, 0x66, 0xce, 0x34, 0xa7, 0x76, 0xdf, 0x11, 0x86, 0x6a, 0x69, 0xbf, 0x2e }; static const ST_KAT_PARAM x963kdf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, x963kdf_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, x963kdf_secret), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_INFO, x963kdf_otherinfo), ST_KAT_PARAM_END() }; static const char pbkdf2_digest[] = "SHA256"; static const unsigned char pbkdf2_password[] = { 0x70, 0x61, 0x73, 0x73, 0x00, 0x77, 0x6f, 0x72, 0x64 }; static const unsigned char pbkdf2_salt[] = { 0x73, 0x61, 0x00, 0x6c, 0x74 }; static const unsigned char pbkdf2_expected[] = { 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87, }; static int pbkdf2_iterations = 4096; static int pbkdf2_pkcs5 = 1; static const ST_KAT_PARAM pbkdf2_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, pbkdf2_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_PASSWORD, pbkdf2_password), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SALT, pbkdf2_salt), ST_KAT_PARAM_INT(OSSL_KDF_PARAM_ITER, pbkdf2_iterations), ST_KAT_PARAM_INT(OSSL_KDF_PARAM_PKCS5, pbkdf2_pkcs5), ST_KAT_PARAM_END() }; static const char sshkdf_digest[] = "SHA1"; static const char sshkdf_type = EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV; static const unsigned char sshkdf_key[] = { 0x00, 0x00, 0x00, 0x80, 0x55, 0xba, 0xe9, 0x31, 0xc0, 0x7f, 0xd8, 0x24, 0xbf, 0x10, 0xad, 0xd1, 0x90, 0x2b, 0x6f, 0xbc, 0x7c, 0x66, 0x53, 0x47, 0x38, 0x34, 0x98, 0xa6, 0x86, 0x92, 0x9f, 0xf5, 0xa2, 0x5f, 0x8e, 0x40, 0xcb, 0x66, 0x45, 0xea, 0x81, 0x4f, 0xb1, 0xa5, 0xe0, 0xa1, 0x1f, 0x85, 0x2f, 0x86, 0x25, 0x56, 0x41, 0xe5, 0xed, 0x98, 0x6e, 0x83, 0xa7, 0x8b, 0xc8, 0x26, 0x94, 0x80, 0xea, 0xc0, 0xb0, 0xdf, 0xd7, 0x70, 0xca, 0xb9, 0x2e, 0x7a, 0x28, 0xdd, 0x87, 0xff, 0x45, 0x24, 0x66, 0xd6, 0xae, 0x86, 0x7c, 0xea, 0xd6, 0x3b, 0x36, 0x6b, 0x1c, 0x28, 0x6e, 0x6c, 0x48, 0x11, 0xa9, 0xf1, 0x4c, 0x27, 0xae, 0xa1, 0x4c, 0x51, 0x71, 0xd4, 0x9b, 0x78, 0xc0, 0x6e, 0x37, 0x35, 0xd3, 0x6e, 0x6a, 0x3b, 0xe3, 0x21, 0xdd, 0x5f, 0xc8, 0x23, 0x08, 0xf3, 0x4e, 0xe1, 0xcb, 0x17, 0xfb, 0xa9, 0x4a, 0x59, }; static const unsigned char sshkdf_xcghash[] = { 0xa4, 0xeb, 0xd4, 0x59, 0x34, 0xf5, 0x67, 0x92, 0xb5, 0x11, 0x2d, 0xcd, 0x75, 0xa1, 0x07, 0x5f, 0xdc, 0x88, 0x92, 0x45, }; static const unsigned char sshkdf_session_id[] = { 0xa4, 0xeb, 0xd4, 0x59, 0x34, 0xf5, 0x67, 0x92, 0xb5, 0x11, 0x2d, 0xcd, 0x75, 0xa1, 0x07, 0x5f, 0xdc, 0x88, 0x92, 0x45, }; static const unsigned char sshkdf_expected[] = { 0xe2, 0xf6, 0x27, 0xc0, 0xb4, 0x3f, 0x1a, 0xc1, }; static const ST_KAT_PARAM sshkdf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, sshkdf_digest), ST_KAT_PARAM_UTF8CHAR(OSSL_KDF_PARAM_SSHKDF_TYPE, sshkdf_type), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, sshkdf_key), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SSHKDF_XCGHASH, sshkdf_xcghash), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, sshkdf_session_id), ST_KAT_PARAM_END() }; static const char tls12prf_digest[] = "SHA256"; static const unsigned char tls12prf_secret[] = { 0x20, 0x2c, 0x88, 0xc0, 0x0f, 0x84, 0xa1, 0x7a, 0x20, 0x02, 0x70, 0x79, 0x60, 0x47, 0x87, 0x46, 0x11, 0x76, 0x45, 0x55, 0x39, 0xe7, 0x05, 0xbe, 0x73, 0x08, 0x90, 0x60, 0x2c, 0x28, 0x9a, 0x50, 0x01, 0xe3, 0x4e, 0xeb, 0x3a, 0x04, 0x3e, 0x5d, 0x52, 0xa6, 0x5e, 0x66, 0x12, 0x51, 0x88, 0xbf, }; static const unsigned char tls12prf_seed[] = { 'k', 'e', 'y', ' ', 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n', 0xae, 0x6c, 0x80, 0x6f, 0x8a, 0xd4, 0xd8, 0x07, 0x84, 0x54, 0x9d, 0xff, 0x28, 0xa4, 0xb5, 0x8f, 0xd8, 0x37, 0x68, 0x1a, 0x51, 0xd9, 0x28, 0xc3, 0xe3, 0x0e, 0xe5, 0xff, 0x14, 0xf3, 0x98, 0x68, 0x62, 0xe1, 0xfd, 0x91, 0xf2, 0x3f, 0x55, 0x8a, 0x60, 0x5f, 0x28, 0x47, 0x8c, 0x58, 0xcf, 0x72, 0x63, 0x7b, 0x89, 0x78, 0x4d, 0x95, 0x9d, 0xf7, 0xe9, 0x46, 0xd3, 0xf0, 0x7b, 0xd1, 0xb6, 0x16, }; static const unsigned char tls12prf_expected[] = { 0x44, 0x31, 0xbf, 0x20, 0xbf, 0xd7, 0xa8, 0x48, 0x0d, 0x6f, 0x4e, 0xe8, 0xc9, 0xf8, 0xc1, 0x6a, 0x65, 0xd1, 0x93, 0xe7, 0x54, 0x32, 0xa6, 0x10, 0x3f, 0x73, 0x4b, 0x32, 0x14, 0xe8, 0xe6, 0x33, 0x91, 0x84, 0x1f, 0x2f, 0xed, 0x71, 0xbc, 0x4c, 0x67, 0x11, 0x97, 0xce, 0x0f, 0xb3, 0x5d, 0x0d, }; static const ST_KAT_PARAM tls12prf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, tls12prf_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SECRET, tls12prf_secret), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SEED, tls12prf_seed), ST_KAT_PARAM_END() }; static const char tls12prf_384_digest[] = "SHA384"; static const unsigned char tls12prf_384_secret[] = { 0xFE, 0x96, 0x83, 0xE1, 0x4F, 0x62, 0xF2, 0xBF, 0x52, 0x75, 0xF2, 0x25, 0xB4, 0x4E, 0x1C, 0xF9, 0xB1, 0x11, 0xFD, 0x6C, 0x09, 0xB9, 0xA8, 0x26, 0xB5, 0xC8, 0xEE, 0xB8, 0x07, 0xFB, 0xB4, 0x22, 0xDD, 0xEE, 0xB3, 0xFA, 0xEF, 0x0A, 0x5A, 0x2A, 0xDD, 0x86, 0xC7, 0x24, 0x68, 0x8A, 0xB4, 0xC3 }; static const unsigned char tls12prf_384_seed[] = { 0x25, 0xEE, 0xAB, 0x71, 0x7D, 0x8C, 0xA1, 0x87, 0x37, 0x35, 0xF2, 0x90, 0x12, 0x4F, 0x54, 0x2E, 0xD7, 0x1B, 0xB1, 0xF2, 0x2D, 0x9A, 0x0E, 0x23, 0x59, 0x16, 0x4B, 0x70, 0x55, 0x45, 0x05, 0x64, 0x45, 0x7E, 0x67, 0x72, 0xED, 0x46, 0x0F, 0xFC, 0x65, 0xAE, 0x49, 0x0D, 0x52, 0x69, 0x9E, 0x01, 0x73, 0x49, 0xBE, 0xCA, 0xAA, 0xF0, 0x50, 0x8C, 0x60, 0x98, 0xB8, 0x8D, 0x88, 0x07, 0x35, 0x80 }; static const unsigned char tls12prf_384_expected[] = { 0xaa, 0x39, 0xe6, 0xf6, 0x6d, 0xd0, 0xa6, 0x3e, 0x09, 0x2d, 0xa2, 0xca, 0x17, 0x2d, 0x91, 0xf4, 0xfb, 0x1f, 0x14, 0x3a, 0xb2, 0xf2, 0x55, 0xd8, 0xda, 0x3b, 0xe4, 0x10, 0xeb, 0x02, 0x98, 0x72, 0xba, 0xd7, 0xc0, 0x18, 0x18, 0xed, 0xb3, 0xe8, 0x52, 0x60, 0x90, 0x53, 0xb1, 0x4f, 0x89, 0x00 }; static const ST_KAT_PARAM tls12prf_384_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, tls12prf_384_digest), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SECRET, tls12prf_secret), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SEED, tls12prf_seed), ST_KAT_PARAM_END() }; static const char kbkdf_digest[] = "SHA256"; static const char kbkdf_mac[] = "HMAC"; static const unsigned char kbkdf_salt[] = { 'p', 'r', 'f' }; static const unsigned char kbkdf_prfinput[] = { 't', 'e', 's', 't' }; static unsigned char kbkdf_key[] = { 0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28, 0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C, }; static const ST_KAT_PARAM kbkdf_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, kbkdf_digest), ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_MAC, kbkdf_mac), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, kbkdf_key), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SALT, kbkdf_salt), ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_INFO, kbkdf_prfinput), ST_KAT_PARAM_END() }; static const ST_KAT_KDF st_kat_kdf_tests[] = { #ifdef ENABLE_QAT_HW_PRF { QAT_SELF_TEST_DESC_KDF_TLS12_256_PRF, OSSL_KDF_NAME_TLS1_PRF, tls12prf_params, ITM(tls12prf_expected) }, { QAT_SELF_TEST_DESC_KDF_TLS12_384_PRF, OSSL_KDF_NAME_TLS1_PRF, tls12prf_384_params, ITM(tls12prf_384_expected) }, #endif #ifdef ENABLE_QAT_HW_HKDF { QAT_SELF_TEST_DESC_KDF_TLS13_256_EXTRACT, OSSL_KDF_NAME_TLS1_3_KDF, tls13_kdf_early_secret_params, ITM(tls13_kdf_early_secret) }, { QAT_SELF_TEST_DESC_KDF_TLS13_256_EXPAND, OSSL_KDF_NAME_TLS1_3_KDF, tls13_kdf_client_early_secret_params, ITM(tls13_kdf_client_early_traffic_secret) }, { QAT_SELF_TEST_DESC_KDF_TLS13_384_EXTRACT, OSSL_KDF_NAME_TLS1_3_KDF, tls13_kdf_early_secret_params_sha384, ITM(tls13_kdf_early_secret_384) }, { QAT_SELF_TEST_DESC_KDF_TLS13_384_EXPAND, OSSL_KDF_NAME_TLS1_3_KDF, tls13_kdf_client_early_secret_params_sha384, ITM(tls13_kdf_client_early_traffic_secret_384) }, #endif }; /*- * DRBG test vectors are a small subset of * https://csrc.nist.rip/groups/STM/cavp/documents/drbg/drbgtestvectors.zip * Using the folder drbgvectors_pr_true * Generated for CAVS 14.3. */ /* * Hash_DRBG.rsp * * [SHA-256] * [PredictionResistance = True] * [EntropyInputLen = 256] * [NonceLen = 128] * [PersonalizationStringLen = 256] * [AdditionalInputLen = 256] * [ReturnedBitsLen = 1024] * * COUNT = 14 */ static const unsigned char drbg_hash_sha256_pr_entropyin[] = { 0x06, 0x6d, 0xc8, 0xce, 0x75, 0xb2, 0x89, 0x66, 0xa6, 0x85, 0x16, 0x3f, 0xe2, 0xa4, 0xd4, 0x27, 0xfb, 0xdb, 0x61, 0x66, 0x50, 0x61, 0x6b, 0xa2, 0x82, 0xfc, 0x33, 0x2b, 0x4e, 0x6f, 0x12, 0x20 }; static const unsigned char drbg_hash_sha256_pr_nonce[] = { 0x55, 0x9f, 0x7c, 0x64, 0x89, 0x70, 0x83, 0xec, 0x2d, 0x73, 0x70, 0xd9, 0xf0, 0xe5, 0x07, 0x1f }; static const unsigned char drbg_hash_sha256_pr_persstr[] = { 0x88, 0x6f, 0x54, 0x9a, 0xad, 0x1a, 0xc6, 0x3d, 0x18, 0xcb, 0xcc, 0x66, 0x85, 0xda, 0xa2, 0xc2, 0xf7, 0x9e, 0xb0, 0x89, 0x4c, 0xb4, 0xae, 0xf1, 0xac, 0x54, 0x4f, 0xce, 0x57, 0xf1, 0x5e, 0x11 }; static const unsigned char drbg_hash_sha256_pr_entropyinpr0[] = { 0xff, 0x80, 0xb7, 0xd2, 0x6a, 0x05, 0xbc, 0x8a, 0x7a, 0xbe, 0x53, 0x28, 0x6b, 0x0e, 0xeb, 0x73, 0x3b, 0x71, 0x5a, 0x20, 0x5b, 0xfa, 0x4f, 0xf6, 0x37, 0x03, 0xde, 0xad, 0xb6, 0xea, 0x0e, 0xf4 }; static const unsigned char drbg_hash_sha256_pr_entropyinpr1[] = { 0xc7, 0x38, 0x32, 0x53, 0x46, 0x81, 0xed, 0xe3, 0x7e, 0x03, 0x84, 0x6d, 0x3c, 0x84, 0x17, 0x67, 0x29, 0x7d, 0x24, 0x6c, 0x68, 0x92, 0x41, 0xd2, 0xe7, 0x75, 0xbe, 0x7e, 0xc9, 0x96, 0x29, 0x3d }; static const unsigned char drbg_hash_sha256_pr_addin0[] = { 0xb7, 0x21, 0x5f, 0x14, 0xac, 0x7b, 0xaf, 0xd0, 0xa9, 0x17, 0x72, 0xba, 0x22, 0xf7, 0x19, 0xaf, 0xbd, 0x20, 0xb3, 0x11, 0x63, 0x6c, 0x2b, 0x1e, 0x83, 0xe4, 0xa8, 0x23, 0x35, 0x3f, 0xc6, 0xea }; static const unsigned char drbg_hash_sha256_pr_addin1[] = { 0xce, 0xd3, 0x1f, 0x7e, 0x0d, 0xae, 0x5b, 0xb5, 0xc0, 0x43, 0xe2, 0x46, 0xb2, 0x94, 0x73, 0xe2, 0xfd, 0x39, 0x51, 0x2e, 0xad, 0x45, 0x69, 0xee, 0xe3, 0xe3, 0x80, 0x33, 0x14, 0xab, 0xa7, 0xa3 }; static const unsigned char drbg_hash_sha256_pr_expected[] = { 0x60, 0xc2, 0x34, 0xcf, 0xaf, 0xb4, 0x68, 0x03, 0x3b, 0xf1, 0x95, 0xe5, 0x78, 0xce, 0x26, 0x6e, 0x14, 0x65, 0x32, 0x6a, 0x96, 0xa9, 0xe0, 0x3f, 0x8b, 0x89, 0x36, 0x70, 0xef, 0x62, 0x75, 0x4d, 0x5e, 0x80, 0xd5, 0x53, 0xa1, 0xf8, 0x49, 0x50, 0x20, 0x8b, 0x93, 0x43, 0x07, 0x9f, 0x2e, 0xf8, 0x56, 0xe9, 0xc5, 0x70, 0x61, 0x85, 0x97, 0xb5, 0xdc, 0x82, 0xa2, 0xda, 0xea, 0xa3, 0xfd, 0x9b, 0x2f, 0xd2, 0xa0, 0xd7, 0x1b, 0xc6, 0x29, 0x35, 0xcc, 0xb8, 0x3d, 0xa0, 0x67, 0x98, 0x05, 0xa0, 0xe3, 0x1e, 0xfe, 0xe4, 0xf0, 0xe5, 0x13, 0xb0, 0x83, 0x17, 0xfa, 0xca, 0x93, 0x5e, 0x38, 0x29, 0x48, 0xd2, 0x72, 0xdb, 0x76, 0x3e, 0x6d, 0xf3, 0x25, 0x10, 0xff, 0x1b, 0x99, 0xff, 0xf8, 0xc6, 0x0e, 0xb0, 0xdd, 0x29, 0x2e, 0xbc, 0xbb, 0xc8, 0x0a, 0x01, 0x6e, 0xd3, 0xb0, 0x0e, 0x4e, 0xab }; /* * CTR_DRBG.rsp * * [AES-128 use df] * [PredictionResistance = True] * [EntropyInputLen = 128] * [NonceLen = 64] * [PersonalizationStringLen = 128] * [AdditionalInputLen = 128] * [ReturnedBitsLen = 512] * * COUNT = 0 */ static const unsigned char drbg_ctr_aes128_pr_df_entropyin[] = { 0x92, 0x89, 0x8f, 0x31, 0xfa, 0x1c, 0xff, 0x6d, 0x18, 0x2f, 0x26, 0x06, 0x43, 0xdf, 0xf8, 0x18 }; static const unsigned char drbg_ctr_aes128_pr_df_nonce[] = { 0xc2, 0xa4, 0xd9, 0x72, 0xc3, 0xb9, 0xb6, 0x97 }; static const unsigned char drbg_ctr_aes128_pr_df_persstr[] = { 0xea, 0x65, 0xee, 0x60, 0x26, 0x4e, 0x7e, 0xb6, 0x0e, 0x82, 0x68, 0xc4, 0x37, 0x3c, 0x5c, 0x0b }; static const unsigned char drbg_ctr_aes128_pr_df_entropyinpr0[] = { 0x20, 0x72, 0x8a, 0x06, 0xf8, 0x6f, 0x8d, 0xd4, 0x41, 0xe2, 0x72, 0xb7, 0xc4, 0x2c, 0xe8, 0x10 }; static const unsigned char drbg_ctr_aes128_pr_df_entropyinpr1[] = { 0x3d, 0xb0, 0xf0, 0x94, 0xf3, 0x05, 0x50, 0x33, 0x17, 0x86, 0x3e, 0x22, 0x08, 0xf7, 0xa5, 0x01 }; static const unsigned char drbg_ctr_aes128_pr_df_addin0[] = { 0x1a, 0x40, 0xfa, 0xe3, 0xcc, 0x6c, 0x7c, 0xa0, 0xf8, 0xda, 0xba, 0x59, 0x23, 0x6d, 0xad, 0x1d }; static const unsigned char drbg_ctr_aes128_pr_df_addin1[] = { 0x9f, 0x72, 0x76, 0x6c, 0xc7, 0x46, 0xe5, 0xed, 0x2e, 0x53, 0x20, 0x12, 0xbc, 0x59, 0x31, 0x8c }; static const unsigned char drbg_ctr_aes128_pr_df_expected[] = { 0x5a, 0x35, 0x39, 0x87, 0x0f, 0x4d, 0x22, 0xa4, 0x09, 0x24, 0xee, 0x71, 0xc9, 0x6f, 0xac, 0x72, 0x0a, 0xd6, 0xf0, 0x88, 0x82, 0xd0, 0x83, 0x28, 0x73, 0xec, 0x3f, 0x93, 0xd8, 0xab, 0x45, 0x23, 0xf0, 0x7e, 0xac, 0x45, 0x14, 0x5e, 0x93, 0x9f, 0xb1, 0xd6, 0x76, 0x43, 0x3d, 0xb6, 0xe8, 0x08, 0x88, 0xf6, 0xda, 0x89, 0x08, 0x77, 0x42, 0xfe, 0x1a, 0xf4, 0x3f, 0xc4, 0x23, 0xc5, 0x1f, 0x68 }; /* * HMAC_DRBG.rsp * * [SHA-1] * [PredictionResistance = True] * [EntropyInputLen = 128] * [NonceLen = 64] * [PersonalizationStringLen = 128] * [AdditionalInputLen = 128] * [ReturnedBitsLen = 640] * * COUNT = 0 */ static const unsigned char drbg_hmac_sha1_pr_entropyin[] = { 0x68, 0x0f, 0xac, 0xe9, 0x0d, 0x7b, 0xca, 0x21, 0xd4, 0xa0, 0xed, 0xb7, 0x79, 0x9e, 0xe5, 0xd8 }; static const unsigned char drbg_hmac_sha1_pr_nonce[] = { 0xb7, 0xbe, 0x9e, 0xed, 0xdd, 0x0e, 0x3b, 0x4b }; static const unsigned char drbg_hmac_sha1_pr_persstr[] = { 0xf5, 0x8c, 0x40, 0xae, 0x70, 0xf7, 0xa5, 0x56, 0x48, 0xa9, 0x31, 0xa0, 0xa9, 0x31, 0x3d, 0xd7 }; static const unsigned char drbg_hmac_sha1_pr_entropyinpr0[] = { 0x7c, 0xaf, 0xe2, 0x31, 0x63, 0x0a, 0xa9, 0x5a, 0x74, 0x2c, 0x4e, 0x5f, 0x5f, 0x22, 0xc6, 0xa4 }; static const unsigned char drbg_hmac_sha1_pr_entropyinpr1[] = { 0x1c, 0x0d, 0x77, 0x92, 0x89, 0x88, 0x27, 0x94, 0x8a, 0x58, 0x9f, 0x82, 0x2d, 0x1a, 0xf7, 0xa6 }; static const unsigned char drbg_hmac_sha1_pr_addin0[] = { 0xdc, 0x36, 0x63, 0xf0, 0x62, 0x78, 0x9c, 0xd1, 0x5c, 0xbb, 0x20, 0xc3, 0xc1, 0x8c, 0xd9, 0xd7 }; static const unsigned char drbg_hmac_sha1_pr_addin1[] = { 0xfe, 0x85, 0xb0, 0xab, 0x14, 0xc6, 0x96, 0xe6, 0x9c, 0x24, 0xe7, 0xb5, 0xa1, 0x37, 0x12, 0x0c }; static const unsigned char drbg_hmac_sha1_pr_expected[] = { 0x68, 0x00, 0x4b, 0x3a, 0x28, 0xf7, 0xf0, 0x1c, 0xf9, 0xe9, 0xb5, 0x71, 0x20, 0x79, 0xef, 0x80, 0x87, 0x1b, 0x08, 0xb9, 0xa9, 0x1b, 0xcd, 0x2b, 0x9f, 0x09, 0x4d, 0xa4, 0x84, 0x80, 0xb3, 0x4c, 0xaf, 0xd5, 0x59, 0x6b, 0x0c, 0x0a, 0x48, 0xe1, 0x48, 0xda, 0xbc, 0x6f, 0x77, 0xb8, 0xff, 0xaf, 0x18, 0x70, 0x28, 0xe1, 0x04, 0x13, 0x7a, 0x4f, 0xeb, 0x1c, 0x72, 0xb0, 0xc4, 0x4f, 0xe8, 0xb1, 0xaf, 0xab, 0xa5, 0xbc, 0xfd, 0x86, 0x67, 0xf2, 0xf5, 0x5b, 0x46, 0x06, 0x63, 0x2e, 0x3c, 0xbc }; static const ST_KAT_DRBG st_kat_drbg_tests[] = { { OSSL_SELF_TEST_DESC_DRBG_HASH, "HASH-DRBG", "digest", "SHA256", ITM(drbg_hash_sha256_pr_entropyin), ITM(drbg_hash_sha256_pr_nonce), ITM(drbg_hash_sha256_pr_persstr), ITM(drbg_hash_sha256_pr_entropyinpr0), ITM(drbg_hash_sha256_pr_entropyinpr1), ITM(drbg_hash_sha256_pr_addin0), ITM(drbg_hash_sha256_pr_addin1), ITM(drbg_hash_sha256_pr_expected) }, { OSSL_SELF_TEST_DESC_DRBG_CTR, "CTR-DRBG", "cipher", "AES-128-CTR", ITM(drbg_ctr_aes128_pr_df_entropyin), ITM(drbg_ctr_aes128_pr_df_nonce), ITM(drbg_ctr_aes128_pr_df_persstr), ITM(drbg_ctr_aes128_pr_df_entropyinpr0), ITM(drbg_ctr_aes128_pr_df_entropyinpr1), ITM(drbg_ctr_aes128_pr_df_addin0), ITM(drbg_ctr_aes128_pr_df_addin1), ITM(drbg_ctr_aes128_pr_df_expected) }, { OSSL_SELF_TEST_DESC_DRBG_HMAC, "HMAC-DRBG", "digest", "SHA1", ITM(drbg_hmac_sha1_pr_entropyin), ITM(drbg_hmac_sha1_pr_nonce), ITM(drbg_hmac_sha1_pr_persstr), ITM(drbg_hmac_sha1_pr_entropyinpr0), ITM(drbg_hmac_sha1_pr_entropyinpr1), ITM(drbg_hmac_sha1_pr_addin0), ITM(drbg_hmac_sha1_pr_addin1), ITM(drbg_hmac_sha1_pr_expected) } }; /* KEY EXCHANGE TEST DATA */ #ifndef OPENSSL_NO_DH /* DH KAT */ static const unsigned char dh_p[] = { 0xdc, 0xca, 0x15, 0x11, 0xb2, 0x31, 0x32, 0x25, 0xf5, 0x21, 0x16, 0xe1, 0x54, 0x27, 0x89, 0xe0, 0x01, 0xf0, 0x42, 0x5b, 0xcc, 0xc7, 0xf3, 0x66, 0xf7, 0x40, 0x64, 0x07, 0xf1, 0xc9, 0xfa, 0x8b, 0xe6, 0x10, 0xf1, 0x77, 0x8b, 0xb1, 0x70, 0xbe, 0x39, 0xdb, 0xb7, 0x6f, 0x85, 0xbf, 0x24, 0xce, 0x68, 0x80, 0xad, 0xb7, 0x62, 0x9f, 0x7c, 0x6d, 0x01, 0x5e, 0x61, 0xd4, 0x3f, 0xa3, 0xee, 0x4d, 0xe1, 0x85, 0xf2, 0xcf, 0xd0, 0x41, 0xff, 0xde, 0x9d, 0x41, 0x84, 0x07, 0xe1, 0x51, 0x38, 0xbb, 0x02, 0x1d, 0xae, 0xb3, 0x5f, 0x76, 0x2d, 0x17, 0x82, 0xac, 0xc6, 0x58, 0xd3, 0x2b, 0xd4, 0xb0, 0x23, 0x2c, 0x92, 0x7d, 0xd3, 0x8f, 0xa0, 0x97, 0xb3, 0xd1, 0x85, 0x9f, 0xa8, 0xac, 0xaf, 0xb9, 0x8f, 0x06, 0x66, 0x08, 0xfc, 0x64, 0x4e, 0xc7, 0xdd, 0xb6, 0xf0, 0x85, 0x99, 0xf9, 0x2a, 0xc1, 0xb5, 0x98, 0x25, 0xda, 0x84, 0x32, 0x07, 0x7d, 0xef, 0x69, 0x56, 0x46, 0x06, 0x3c, 0x20, 0x82, 0x3c, 0x95, 0x07, 0xab, 0x6f, 0x01, 0x76, 0xd4, 0x73, 0x0d, 0x99, 0x0d, 0xbb, 0xe6, 0x36, 0x1c, 0xd8, 0xb2, 0xb9, 0x4d, 0x3d, 0x2f, 0x32, 0x9b, 0x82, 0x09, 0x9b, 0xd6, 0x61, 0xf4, 0x29, 0x50, 0xf4, 0x03, 0xdf, 0x3e, 0xde, 0x62, 0xa3, 0x31, 0x88, 0xb0, 0x27, 0x98, 0xba, 0x82, 0x3f, 0x44, 0xb9, 0x46, 0xfe, 0x9d, 0xf6, 0x77, 0xa0, 0xc5, 0xa1, 0x23, 0x8e, 0xaa, 0x97, 0xb7, 0x0f, 0x80, 0xda, 0x8c, 0xac, 0x88, 0xe0, 0x92, 0xb1, 0x12, 0x70, 0x60, 0xff, 0xbf, 0x45, 0x57, 0x99, 0x94, 0x01, 0x1d, 0xc2, 0xfa, 0xa5, 0xe7, 0xf6, 0xc7, 0x62, 0x45, 0xe1, 0xcc, 0x31, 0x22, 0x31, 0xc1, 0x7d, 0x1c, 0xa6, 0xb1, 0x90, 0x07, 0xef, 0x0d, 0xb9, 0x9f, 0x9c, 0xb6, 0x0e, 0x1d, 0x5f, 0x69 }; static const unsigned char dh_q[] = { 0x89, 0x8b, 0x22, 0x67, 0x17, 0xef, 0x03, 0x9e, 0x60, 0x3e, 0x82, 0xe5, 0xc7, 0xaf, 0xe4, 0x83, 0x74, 0xac, 0x5f, 0x62, 0x5c, 0x54, 0xf1, 0xea, 0x11, 0xac, 0xb5, 0x7d }; static const unsigned char dh_g[] = { 0x5e, 0xf7, 0xb8, 0x8f, 0x2d, 0xf6, 0x01, 0x39, 0x35, 0x1d, 0xfb, 0xfe, 0x12, 0x66, 0x80, 0x5f, 0xdf, 0x35, 0x6c, 0xdf, 0xd1, 0x3a, 0x4d, 0xa0, 0x05, 0x0c, 0x7e, 0xde, 0x24, 0x6d, 0xf5, 0x9f, 0x6a, 0xbf, 0x96, 0xad, 0xe5, 0xf2, 0xb2, 0x8f, 0xfe, 0x88, 0xd6, 0xbc, 0xe7, 0xf7, 0x89, 0x4a, 0x3d, 0x53, 0x5f, 0xc8, 0x21, 0x26, 0xdd, 0xd4, 0x24, 0x87, 0x2e, 0x16, 0xb8, 0x38, 0xdf, 0x8c, 0x51, 0xe9, 0x01, 0x6f, 0x88, 0x9c, 0x7c, 0x20, 0x3e, 0x98, 0xa8, 0xb6, 0x31, 0xf9, 0xc7, 0x25, 0x63, 0xd3, 0x8a, 0x49, 0x58, 0x9a, 0x07, 0x53, 0xd3, 0x58, 0xe7, 0x83, 0x31, 0x8c, 0xef, 0xd9, 0x67, 0x7c, 0x7b, 0x2d, 0xbb, 0x77, 0xd6, 0xdc, 0xe2, 0xa1, 0x96, 0x37, 0x95, 0xca, 0x64, 0xb9, 0x2d, 0x1c, 0x9a, 0xac, 0x6d, 0x0e, 0x8d, 0x43, 0x1d, 0xe5, 0xe5, 0x00, 0x60, 0xdf, 0xf7, 0x86, 0x89, 0xc9, 0xec, 0xa1, 0xc1, 0x24, 0x8c, 0x16, 0xed, 0x09, 0xc7, 0xad, 0x41, 0x2a, 0x17, 0x40, 0x6d, 0x2b, 0x52, 0x5a, 0xa1, 0xca, 0xbb, 0x23, 0x7b, 0x97, 0x34, 0xec, 0x7b, 0x8c, 0xe3, 0xfa, 0xe0, 0x2f, 0x29, 0xc5, 0xef, 0xed, 0x30, 0xd6, 0x91, 0x87, 0xda, 0x10, 0x9c, 0x2c, 0x9f, 0xe2, 0xaa, 0xdb, 0xb0, 0xc2, 0x2a, 0xf5, 0x4c, 0x61, 0x66, 0x55, 0x00, 0x0c, 0x43, 0x1c, 0x6b, 0x4a, 0x37, 0x97, 0x63, 0xb0, 0xa9, 0x16, 0x58, 0xef, 0xc8, 0x4e, 0x8b, 0x06, 0x35, 0x8c, 0x8b, 0x4f, 0x21, 0x37, 0x10, 0xfd, 0x10, 0x17, 0x2c, 0xf3, 0x9b, 0x83, 0x0c, 0x2d, 0xd8, 0x4a, 0x0c, 0x8a, 0xb8, 0x25, 0x16, 0xec, 0xab, 0x99, 0x5f, 0xa4, 0x21, 0x5e, 0x02, 0x3e, 0x4e, 0xcf, 0x80, 0x74, 0xc3, 0x9d, 0x6c, 0x88, 0xb7, 0x0d, 0x1e, 0xe4, 0xe9, 0x6f, 0xdc, 0x20, 0xea, 0x11, 0x5c, 0x32 }; static const unsigned char dh_priv[] = { 0x14, 0x33, 0xe0, 0xb5, 0xa9, 0x17, 0xb6, 0x0a, 0x30, 0x23, 0xf2, 0xf8, 0xaa, 0x2c, 0x2d, 0x70, 0xd2, 0x96, 0x8a, 0xba, 0x9a, 0xea, 0xc8, 0x15, 0x40, 0xb8, 0xfc, 0xe6 }; static const unsigned char dh_pub[] = { 0x95, 0xdd, 0x33, 0x8d, 0x29, 0xe5, 0x71, 0x04, 0x92, 0xb9, 0x18, 0x31, 0x7b, 0x72, 0xa3, 0x69, 0x36, 0xe1, 0x95, 0x1a, 0x2e, 0xe5, 0xa5, 0x59, 0x16, 0x99, 0xc0, 0x48, 0x6d, 0x0d, 0x4f, 0x9b, 0xdd, 0x6d, 0x5a, 0x3f, 0x6b, 0x98, 0x89, 0x0c, 0x62, 0xb3, 0x76, 0x52, 0xd3, 0x6e, 0x71, 0x21, 0x11, 0xe6, 0x8a, 0x73, 0x55, 0x37, 0x25, 0x06, 0x99, 0xef, 0xe3, 0x30, 0x53, 0x73, 0x91, 0xfb, 0xc2, 0xc5, 0x48, 0xbc, 0x5a, 0xc3, 0xe5, 0xb2, 0x33, 0x86, 0xc3, 0xee, 0xf5, 0xeb, 0x43, 0xc0, 0x99, 0xd7, 0x0a, 0x52, 0x02, 0x68, 0x7e, 0x83, 0x96, 0x42, 0x48, 0xfc, 0xa9, 0x1f, 0x40, 0x90, 0x8e, 0x8f, 0xb3, 0x31, 0x93, 0x15, 0xf6, 0xd2, 0x60, 0x6d, 0x7f, 0x7c, 0xd5, 0x2c, 0xc6, 0xe7, 0xc5, 0x84, 0x3a, 0xfb, 0x22, 0x51, 0x9c, 0xf0, 0xf0, 0xf9, 0xd3, 0xa0, 0xa4, 0xe8, 0xc8, 0x88, 0x99, 0xef, 0xed, 0xe7, 0x36, 0x43, 0x51, 0xfb, 0x6a, 0x36, 0x3e, 0xe7, 0x17, 0xe5, 0x44, 0x5a, 0xda, 0xb4, 0xc9, 0x31, 0xa6, 0x48, 0x39, 0x97, 0xb8, 0x7d, 0xad, 0x83, 0x67, 0x7e, 0x4d, 0x1d, 0x3a, 0x77, 0x75, 0xe0, 0xf6, 0xd0, 0x0f, 0xdf, 0x73, 0xc7, 0xad, 0x80, 0x1e, 0x66, 0x5a, 0x0e, 0x5a, 0x79, 0x6d, 0x0a, 0x03, 0x80, 0xa1, 0x9f, 0xa1, 0x82, 0xef, 0xc8, 0xa0, 0x4f, 0x5e, 0x4d, 0xb9, 0x0d, 0x1a, 0x86, 0x37, 0xf9, 0x5d, 0xb1, 0x64, 0x36, 0xbd, 0xc8, 0xf3, 0xfc, 0x09, 0x6c, 0x4f, 0xf7, 0xf2, 0x34, 0xbe, 0x8f, 0xef, 0x47, 0x9a, 0xc4, 0xb0, 0xdc, 0x4b, 0x77, 0x26, 0x3e, 0x07, 0xd9, 0x95, 0x9d, 0xe0, 0xf1, 0xbf, 0x3f, 0x0a, 0xe3, 0xd9, 0xd5, 0x0e, 0x4b, 0x89, 0xc9, 0x9e, 0x3e, 0xa1, 0x21, 0x73, 0x43, 0xdd, 0x8c, 0x65, 0x81, 0xac, 0xc4, 0x95, 0x9c, 0x91, 0xd3 }; static const unsigned char dh_peer_pub[] = { 0x1f, 0xc1, 0xda, 0x34, 0x1d, 0x1a, 0x84, 0x6a, 0x96, 0xb7, 0xbe, 0x24, 0x34, 0x0f, 0x87, 0x7d, 0xd0, 0x10, 0xaa, 0x03, 0x56, 0xd5, 0xad, 0x58, 0xaa, 0xe9, 0xc7, 0xb0, 0x8f, 0x74, 0x9a, 0x32, 0x23, 0x51, 0x10, 0xb5, 0xd8, 0x8e, 0xb5, 0xdb, 0xfa, 0x97, 0x8d, 0x27, 0xec, 0xc5, 0x30, 0xf0, 0x2d, 0x31, 0x14, 0x00, 0x5b, 0x64, 0xb1, 0xc0, 0xe0, 0x24, 0xcb, 0x8a, 0xe2, 0x16, 0x98, 0xbc, 0xa9, 0xe6, 0x0d, 0x42, 0x80, 0x86, 0x22, 0xf1, 0x81, 0xc5, 0x6e, 0x1d, 0xe7, 0xa9, 0x6e, 0x6e, 0xfe, 0xe9, 0xd6, 0x65, 0x67, 0xe9, 0x1b, 0x97, 0x70, 0x42, 0xc7, 0xe3, 0xd0, 0x44, 0x8f, 0x05, 0xfb, 0x77, 0xf5, 0x22, 0xb9, 0xbf, 0xc8, 0xd3, 0x3c, 0xc3, 0xc3, 0x1e, 0xd3, 0xb3, 0x1f, 0x0f, 0xec, 0xb6, 0xdb, 0x4f, 0x6e, 0xa3, 0x11, 0xe7, 0x7a, 0xfd, 0xbc, 0xd4, 0x7a, 0xee, 0x1b, 0xb1, 0x50, 0xf2, 0x16, 0x87, 0x35, 0x78, 0xfb, 0x96, 0x46, 0x8e, 0x8f, 0x9f, 0x3d, 0xe8, 0xef, 0xbf, 0xce, 0x75, 0x62, 0x4b, 0x1d, 0xf0, 0x53, 0x22, 0xa3, 0x4f, 0x14, 0x63, 0xe8, 0x39, 0xe8, 0x98, 0x4c, 0x4a, 0xd0, 0xa9, 0x6e, 0x1a, 0xc8, 0x42, 0xe5, 0x31, 0x8c, 0xc2, 0x3c, 0x06, 0x2a, 0x8c, 0xa1, 0x71, 0xb8, 0xd5, 0x75, 0x98, 0x0d, 0xde, 0x7f, 0xc5, 0x6f, 0x15, 0x36, 0x52, 0x38, 0x20, 0xd4, 0x31, 0x92, 0xbf, 0xd5, 0x1e, 0x8e, 0x22, 0x89, 0x78, 0xac, 0xa5, 0xb9, 0x44, 0x72, 0xf3, 0x39, 0xca, 0xeb, 0x99, 0x31, 0xb4, 0x2b, 0xe3, 0x01, 0x26, 0x8b, 0xc9, 0x97, 0x89, 0xc9, 0xb2, 0x55, 0x71, 0xc3, 0xc0, 0xe4, 0xcb, 0x3f, 0x00, 0x7f, 0x1a, 0x51, 0x1c, 0xbb, 0x53, 0xc8, 0x51, 0x9c, 0xdd, 0x13, 0x02, 0xab, 0xca, 0x6c, 0x0f, 0x34, 0xf9, 0x67, 0x39, 0xf1, 0x7f, 0xf4, 0x8b }; static const unsigned char dh_secret_expected[] = { 0x08, 0xff, 0x33, 0xbb, 0x2e, 0xcf, 0xf4, 0x9a, 0x7d, 0x4a, 0x79, 0x12, 0xae, 0xb1, 0xbb, 0x6a, 0xb5, 0x11, 0x64, 0x1b, 0x4a, 0x76, 0x77, 0x0c, 0x8c, 0xc1, 0xbc, 0xc2, 0x33, 0x34, 0x3d, 0xfe, 0x70, 0x0d, 0x11, 0x81, 0x3d, 0x2c, 0x9e, 0xd2, 0x3b, 0x21, 0x1c, 0xa9, 0xe8, 0x78, 0x69, 0x21, 0xed, 0xca, 0x28, 0x3c, 0x68, 0xb1, 0x61, 0x53, 0xfa, 0x01, 0xe9, 0x1a, 0xb8, 0x2c, 0x90, 0xdd, 0xab, 0x4a, 0x95, 0x81, 0x67, 0x70, 0xa9, 0x87, 0x10, 0xe1, 0x4c, 0x92, 0xab, 0x83, 0xb6, 0xe4, 0x6e, 0x1e, 0x42, 0x6e, 0xe8, 0x52, 0x43, 0x0d, 0x61, 0x87, 0xda, 0xa3, 0x72, 0x0a, 0x6b, 0xcd, 0x73, 0x23, 0x5c, 0x6b, 0x0f, 0x94, 0x1f, 0x33, 0x64, 0xf5, 0x04, 0x20, 0x55, 0x1a, 0x4b, 0xfe, 0xaf, 0xe2, 0xbc, 0x43, 0x85, 0x05, 0xa5, 0x9a, 0x4a, 0x40, 0xda, 0xca, 0x7a, 0x89, 0x5a, 0x73, 0xdb, 0x57, 0x5c, 0x74, 0xc1, 0x3a, 0x23, 0xad, 0x88, 0x32, 0x95, 0x7d, 0x58, 0x2d, 0x38, 0xf0, 0xa6, 0x16, 0x5f, 0xb0, 0xd7, 0xe9, 0xb8, 0x79, 0x9e, 0x42, 0xfd, 0x32, 0x20, 0xe3, 0x32, 0xe9, 0x81, 0x85, 0xa0, 0xc9, 0x42, 0x97, 0x57, 0xb2, 0xd0, 0xd0, 0x2c, 0x17, 0xdb, 0xaa, 0x1f, 0xf6, 0xed, 0x93, 0xd7, 0xe7, 0x3e, 0x24, 0x1e, 0xae, 0xd9, 0x0c, 0xaf, 0x39, 0x4d, 0x2b, 0xc6, 0x57, 0x0f, 0x18, 0xc8, 0x1f, 0x2b, 0xe5, 0xd0, 0x1a, 0x2c, 0xa9, 0x9f, 0xf1, 0x42, 0xb5, 0xd9, 0x63, 0xf9, 0xf5, 0x00, 0x32, 0x5e, 0x75, 0x56, 0xf9, 0x58, 0x49, 0xb3, 0xff, 0xc7, 0x47, 0x94, 0x86, 0xbe, 0x1d, 0x45, 0x96, 0xa3, 0x10, 0x6b, 0xd5, 0xcb, 0x4f, 0x61, 0xc5, 0x7e, 0xc5, 0xf1, 0x00, 0xfb, 0x7a, 0x0c, 0x82, 0xa1, 0x0b, 0x82, 0x52, 0x6a, 0x97, 0xd1, 0xd9, 0x7d, 0x98, 0xea, 0xf6 }; static const ST_KAT_PARAM dh_group[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_P, dh_p), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_Q, dh_q), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_G, dh_g), ST_KAT_PARAM_END() }; /* The host's private key */ static const ST_KAT_PARAM dh_host_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PUB_KEY, dh_pub), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, dh_priv), ST_KAT_PARAM_END() }; /* The peer's public key */ static const ST_KAT_PARAM dh_peer_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PUB_KEY, dh_peer_pub), ST_KAT_PARAM_END() }; #endif /* OPENSSL_NO_DH */ #ifndef OPENSSL_NO_EC static const char ecx25519_curve_name[] = "X25519"; static const unsigned char ecx25519_privd[] = { 0x2f, 0xe5, 0xc7, 0x2d, 0x2a, 0x82, 0x5a, 0x92, 0xc1, 0xfb, 0xac, 0xc1, 0xda, 0xbf, 0xdd, 0x5a, 0xca, 0x57, 0x95, 0x1a, 0x7e, 0xa7, 0x64, 0xdf, 0x65, 0x58, 0x21, 0xf0, 0x91, 0x30, 0xaf, 0x72 }; static const unsigned char ecx25519_pub[] = { 0x25, 0x9a, 0x61, 0x98, 0x4b, 0x62, 0xdb, 0x84, 0xfa, 0xaf, 0xb2, 0x88, 0x98, 0xf2, 0x74, 0xba, 0xed, 0x9e, 0xc7, 0xaa, 0x26, 0x34, 0xff, 0xb1, 0xaf, 0xc7, 0x11, 0x37, 0x3a, 0x6d, 0xc9, 0x7c }; static const unsigned char ecx25519_peer_pub[] = { 0x69, 0x98, 0xfe, 0xf4, 0x2d, 0x49, 0x74, 0x5a, 0x3f, 0x92, 0x35, 0x7a, 0x10, 0x59, 0x6b, 0x44, 0xfb, 0x25, 0x80, 0x52, 0x0f, 0x1f, 0x64, 0x84, 0x0a, 0x8f, 0xd7, 0x1e, 0x22, 0x20, 0x31, 0x16 }; static const ST_KAT_PARAM ecx25519_group[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecx25519_curve_name), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecx25519_host_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecx25519_pub), ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PRIV_KEY, ecx25519_privd), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecx25519_peer_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecx25519_peer_pub), ST_KAT_PARAM_END() }; static const unsigned char ecx25519_secret_expected[] = { 0xc1, 0xdf, 0x3b, 0x8e, 0x43, 0xad, 0xbf, 0xe7, 0x0b, 0xb7, 0xc2, 0x08, 0x99, 0x97, 0x2b, 0x00, 0x1c, 0x15, 0x0e, 0x56, 0xd2, 0xc3, 0x0e, 0x3a, 0xb3, 0xbf, 0xc2, 0x2c, 0x9f, 0x27, 0xc1, 0x74 }; static const char ecx448_curve_name[] = "X448"; static const unsigned char ecx448_privd[] = { 0xb0, 0x45, 0x51, 0xd0, 0xa1, 0xce, 0x08, 0xcc, 0xf8, 0xb0, 0xaa, 0xe0, 0x50, 0x4a, 0x7b, 0x19, 0xf6, 0x6c, 0x2a, 0x94, 0x66, 0xbf, 0xbc, 0xc5, 0x7f, 0x7b, 0xa9, 0x7f, 0x5a, 0x2c, 0xa0, 0x26, 0xaf, 0x3b, 0x4f, 0x59, 0x6b, 0xbc, 0x4b, 0x2a, 0xad, 0x49, 0xaa, 0xb6, 0x8e, 0x98, 0x6c, 0x5b, 0x4c, 0x00, 0xa4, 0x2c, 0xe1, 0x78, 0xd4, 0x6a }; static const unsigned char ecx448_pub[] = { 0x75, 0x64, 0xe7, 0x6a, 0x7b, 0x52, 0xe3, 0xe8, 0xfd, 0xaf, 0x88, 0x44, 0x3b, 0xd0, 0x0d, 0xdc, 0x2c, 0xb5, 0x68, 0x8c, 0x9d, 0x61, 0xbf, 0x28, 0x3e, 0x49, 0x5b, 0xf3, 0x84, 0x5e, 0x73, 0xe7, 0xb5, 0x26, 0xdd, 0x6c, 0x2e, 0x4d, 0x50, 0x3b, 0xfb, 0xa5, 0x3c, 0x46, 0x44, 0x78, 0x42, 0xfc, 0xa5, 0x44, 0xa2, 0xf8, 0x9d, 0x1f, 0x39, 0xc4 }; static const unsigned char ecx448_peer_pub[] = { 0x2b, 0x0a, 0xe4, 0xd4, 0x4b, 0x47, 0x05, 0x00, 0x27, 0x5b, 0x4c, 0xb0, 0x24, 0xfc, 0x8f, 0xf4, 0x87, 0x98, 0x0d, 0x4c, 0x51, 0x20, 0xaf, 0x05, 0x07, 0xe3, 0x19, 0x38, 0xbc, 0xb9, 0x9f, 0x81, 0xb8, 0xce, 0xfe, 0xf4, 0x77, 0xee, 0xf0, 0x23, 0xcb, 0xed, 0x81, 0xc4, 0x87, 0x30, 0x90, 0xb9, 0x3b, 0xa9, 0x1c, 0xfc, 0x49, 0x11, 0x76, 0xf3 }; static const ST_KAT_PARAM ecx448_group[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecx448_curve_name), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecx448_host_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecx448_pub), ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PRIV_KEY, ecx448_privd), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecx448_peer_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecx448_peer_pub), ST_KAT_PARAM_END() }; static const unsigned char ecx448_secret_expected[] = { 0x2c, 0x19, 0x0e, 0x3d, 0x00, 0x73, 0xd2, 0x41, 0x2b, 0x51, 0x28, 0x6c, 0xe5, 0x17, 0x93, 0x7c, 0x67, 0xc2, 0xdc, 0xb5, 0x1f, 0x4a, 0x8a, 0x6d, 0x17, 0x27, 0x14, 0xcb, 0xc6, 0x67, 0x87, 0x26, 0x6f, 0x77, 0x7e, 0xa0, 0x16, 0xd3, 0x98, 0x35, 0xde, 0x7e, 0xe0, 0xbc, 0x13, 0x0d, 0x4d, 0x93, 0x5c, 0x3f, 0xd6, 0xe9, 0x16, 0xc2, 0xbf, 0x4a }; static const char ecdh_curve_name[] = "prime256v1"; static const unsigned char ecdh_privd[] = { 0x33, 0xd0, 0x43, 0x83, 0xa9, 0x89, 0x56, 0x03, 0xd2, 0xd7, 0xfe, 0x6b, 0x01, 0x6f, 0xe4, 0x59, 0xcc, 0x0d, 0x9a, 0x24, 0x6c, 0x86, 0x1b, 0x2e, 0xdc, 0x4b, 0x4d, 0x35, 0x43, 0xe1, 0x1b, 0xad }; static const unsigned char ecdh_pub[] = { 0x04, 0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63, 0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d, 0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73, 0x3a, 0x6a, 0x08, 0x28, 0x39, 0xbd, 0xc9, 0xd2, 0x80, 0xec, 0xe9, 0xa7, 0x08, 0x29, 0x71, 0x2f, 0xc9, 0x56, 0x82, 0xee, 0x9a, 0x85, 0x0f, 0x6d, 0x7f, 0x59, 0x5f, 0x8c, 0xd1, 0x96, 0x0b, 0xdf, 0x29, 0x3e, 0x49, 0x07, 0x88, 0x3f, 0x9a, 0x29 }; static const unsigned char ecdh_peer_pub[] = { 0x04, 0x1f, 0x72, 0xbd, 0x2a, 0x3e, 0xeb, 0x6c, 0x76, 0xe5, 0x5d, 0x69, 0x75, 0x24, 0xbf, 0x2f, 0x5b, 0x96, 0xb2, 0x91, 0x62, 0x06, 0x35, 0xcc, 0xb2, 0x4b, 0x31, 0x1b, 0x0c, 0x6f, 0x06, 0x9f, 0x86, 0xcf, 0xc8, 0xac, 0xd5, 0x4f, 0x4d, 0x77, 0xf3, 0x70, 0x4a, 0x8f, 0x04, 0x9a, 0xb1, 0x03, 0xc7, 0xeb, 0xd5, 0x94, 0x78, 0x61, 0xab, 0x78, 0x0c, 0x4a, 0x2d, 0x6b, 0xf3, 0x2f, 0x2e, 0x4a, 0xbc }; static const ST_KAT_PARAM ecdh_group[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecdh_curve_name), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecdh_host_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecdh_pub), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecdh_privd), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecdh_peer_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecdh_peer_pub), ST_KAT_PARAM_END() }; static const unsigned char ecdh_secret_expected[] = { 0x45, 0x2a, 0x2f, 0x0d, 0x24, 0xe6, 0x8d, 0xd0, 0xda, 0x59, 0x7b, 0x0c, 0xec, 0x9b, 0x4c, 0x38, 0x41, 0xdd, 0xce, 0xb3, 0xcc, 0xf1, 0x90, 0x8e, 0x30, 0xdb, 0x5b, 0x5f, 0x97, 0xea, 0xe0, 0xc2 }; static const char ecdh_p384_curve_name[] = "secp384r1"; static const unsigned char ecdh_p384_privd[] = { 0x03, 0x1d, 0x34, 0x0b, 0xe8, 0xe8, 0xc3, 0x76, 0x3c, 0xcf, 0x53, 0x10, 0x51, 0x6f, 0x32, 0xa9, 0xfb, 0x2a, 0xa7, 0xd6, 0x5a, 0x41, 0xbd, 0xeb, 0x66, 0x1d, 0x82, 0xc5, 0xf2, 0x72, 0xd1, 0x33, 0x00, 0xbe, 0x66, 0xa1, 0x95, 0x0f, 0x4d, 0xd6, 0x97, 0x9a, 0xd5, 0x27, 0x86, 0xa8, 0xb2, 0x88 }; static const unsigned char ecdh_p384_pub[] = { 0x04, 0x71, 0x8f, 0x61, 0x3e, 0xd2, 0x60, 0x16, 0x22, 0xb9, 0x7a, 0x54, 0xaf, 0x57, 0xa8, 0x74, 0x3a, 0x5c, 0x7b, 0xe0, 0x69, 0xd3, 0xa9, 0xb8, 0xfa, 0x28, 0xe7, 0x12, 0x6b, 0x7b, 0x0d, 0x43, 0x1f, 0x0c, 0x1f, 0xce, 0x8d, 0x94, 0x31, 0x81, 0x28, 0xe3, 0x83, 0x5d, 0x0d, 0xb3, 0x86, 0xcc, 0x5b, 0x27, 0x49, 0x56, 0x2a, 0xd7, 0x6c, 0x4f, 0x4a, 0xea, 0xeb, 0x47, 0x9c, 0x80, 0xd4, 0x24, 0xcc, 0x05, 0x28, 0xee, 0x0e, 0x47, 0xcf, 0x4c, 0x5d, 0xe9, 0xbc, 0x9b, 0x6c, 0x5e, 0x2c, 0xc4, 0xd0, 0x88, 0x44, 0x00, 0x69, 0xc1, 0xd7, 0xa3, 0x97, 0x68, 0x3d, 0xea, 0x2f, 0xb2, 0x9d, 0x7f, 0xa7 }; static const unsigned char ecdh_p384_peer_pub[] = { 0x04, 0xd0, 0x4f, 0xff, 0x2e, 0x0b, 0x99, 0x10, 0xc2, 0x54, 0xb7, 0xc1, 0x86, 0x53, 0x9a, 0x64, 0x62, 0x83, 0xc6, 0x84, 0x00, 0x76, 0x2a, 0x4c, 0x8f, 0xa9, 0xe6, 0x12, 0x8d, 0xf7, 0xc6, 0x2e, 0xb4, 0x55, 0x6b, 0x20, 0x8d, 0xf1, 0x30, 0xad, 0xb7, 0x7c, 0x60, 0x34, 0x86, 0x5b, 0x7b, 0x9f, 0x68, 0x66, 0x33, 0x3e, 0x9f, 0xe6, 0xab, 0x2b, 0x18, 0x0a, 0xe0, 0x44, 0x59, 0xec, 0x21, 0xa5, 0x6e, 0xe6, 0x61, 0x38, 0x90, 0x02, 0x60, 0xaf, 0xd3, 0xda, 0x4b, 0x94, 0x3f, 0x91, 0xa9, 0x35, 0x7b, 0xdd, 0x5e, 0xd5, 0xe7, 0xb3, 0xb2, 0x85, 0xd2, 0x22, 0xa8, 0x74, 0xaf, 0x8a, 0x4d, 0x15, 0x97 }; static const ST_KAT_PARAM ecdh_p384_group[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecdh_p384_curve_name), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecdh_p384_host_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecdh_p384_pub), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecdh_p384_privd), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM ecdh_p384_peer_key[] = { ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecdh_p384_peer_pub), ST_KAT_PARAM_END() }; static const unsigned char ecdh_p384_secret_expected[] = { 0xce, 0x31, 0x9b, 0xb3, 0x22, 0xf5, 0x95, 0xd4, 0x7d, 0xad, 0x35, 0x47, 0x51, 0x78, 0xaa, 0x26, 0xe8, 0xe8, 0x72, 0x83, 0x8e, 0xc5, 0xbc, 0xfe, 0x9d, 0x4b, 0xe0, 0xc1, 0xcc, 0x56, 0x2a, 0x6c, 0x96, 0xfb, 0x98, 0x19, 0x4a, 0x95, 0x08, 0xba, 0x70, 0x83, 0x8b, 0xa8, 0xe7, 0xe9, 0x7f, 0x5f }; #endif /* OPENSSL_NO_EC */ #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) static const ST_KAT_KAS st_kat_kas_tests[] = { # ifndef OPENSSL_NO_DH { OSSL_SELF_TEST_DESC_KA_DH, "DH", dh_group, dh_host_key, dh_peer_key, ITM(dh_secret_expected) }, # endif /* OPENSSL_NO_DH */ # ifndef OPENSSL_NO_EC { QAT_SELF_TEST_DESC_KA_ECDHP256, "EC", ecdh_group, ecdh_host_key, ecdh_peer_key, ITM(ecdh_secret_expected) }, { QAT_SELF_TEST_DESC_KA_ECDHP384, "EC", ecdh_p384_group, ecdh_p384_host_key, ecdh_p384_peer_key, ITM(ecdh_p384_secret_expected) }, { QAT_SELF_TEST_DESC_KA_ECX25519, "X25519", ecx25519_group, ecx25519_host_key, ecx25519_peer_key, ITM(ecx25519_secret_expected) }, { QAT_SELF_TEST_DESC_KA_ECX448, "X448", ecx448_group, ecx448_host_key, ecx448_peer_key, ITM(ecx448_secret_expected) }, # endif /* OPENSSL_NO_EC */ }; #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */ /* RSA key data */ static const unsigned char rsa_n[] = { 0xDB, 0x10, 0x1A, 0xC2, 0xA3, 0xF1, 0xDC, 0xFF, 0x13, 0x6B, 0xED, 0x44, 0xDF, 0xF0, 0x02, 0x6D, 0x13, 0xC7, 0x88, 0xDA, 0x70, 0x6B, 0x54, 0xF1, 0xE8, 0x27, 0xDC, 0xC3, 0x0F, 0x99, 0x6A, 0xFA, 0xC6, 0x67, 0xFF, 0x1D, 0x1E, 0x3C, 0x1D, 0xC1, 0xB5, 0x5F, 0x6C, 0xC0, 0xB2, 0x07, 0x3A, 0x6D, 0x41, 0xE4, 0x25, 0x99, 0xAC, 0xFC, 0xD2, 0x0F, 0x02, 0xD3, 0xD1, 0x54, 0x06, 0x1A, 0x51, 0x77, 0xBD, 0xB6, 0xBF, 0xEA, 0xA7, 0x5C, 0x06, 0xA9, 0x5D, 0x69, 0x84, 0x45, 0xD7, 0xF5, 0x05, 0xBA, 0x47, 0xF0, 0x1B, 0xD7, 0x2B, 0x24, 0xEC, 0xCB, 0x9B, 0x1B, 0x10, 0x8D, 0x81, 0xA0, 0xBE, 0xB1, 0x8C, 0x33, 0xE4, 0x36, 0xB8, 0x43, 0xEB, 0x19, 0x2A, 0x81, 0x8D, 0xDE, 0x81, 0x0A, 0x99, 0x48, 0xB6, 0xF6, 0xBC, 0xCD, 0x49, 0x34, 0x3A, 0x8F, 0x26, 0x94, 0xE3, 0x28, 0x82, 0x1A, 0x7C, 0x8F, 0x59, 0x9F, 0x45, 0xE8, 0x5D, 0x1A, 0x45, 0x76, 0x04, 0x56, 0x05, 0xA1, 0xD0, 0x1B, 0x8C, 0x77, 0x6D, 0xAF, 0x53, 0xFA, 0x71, 0xE2, 0x67, 0xE0, 0x9A, 0xFE, 0x03, 0xA9, 0x85, 0xD2, 0xC9, 0xAA, 0xBA, 0x2A, 0xBC, 0xF4, 0xA0, 0x08, 0xF5, 0x13, 0x98, 0x13, 0x5D, 0xF0, 0xD9, 0x33, 0x34, 0x2A, 0x61, 0xC3, 0x89, 0x55, 0xF0, 0xAE, 0x1A, 0x9C, 0x22, 0xEE, 0x19, 0x05, 0x8D, 0x32, 0xFE, 0xEC, 0x9C, 0x84, 0xBA, 0xB7, 0xF9, 0x6C, 0x3A, 0x4F, 0x07, 0xFC, 0x45, 0xEB, 0x12, 0xE5, 0x7B, 0xFD, 0x55, 0xE6, 0x29, 0x69, 0xD1, 0xC2, 0xE8, 0xB9, 0x78, 0x59, 0xF6, 0x79, 0x10, 0xC6, 0x4E, 0xEB, 0x6A, 0x5E, 0xB9, 0x9A, 0xC7, 0xC4, 0x5B, 0x63, 0xDA, 0xA3, 0x3F, 0x5E, 0x92, 0x7A, 0x81, 0x5E, 0xD6, 0xB0, 0xE2, 0x62, 0x8F, 0x74, 0x26, 0xC2, 0x0C, 0xD3, 0x9A, 0x17, 0x47, 0xE6, 0x8E, 0xAB }; static const unsigned char rsa_e[] = { 0x01, 0x00, 0x01 }; static const unsigned char rsa_d[] = { 0x52, 0x41, 0xF4, 0xDA, 0x7B, 0xB7, 0x59, 0x55, 0xCA, 0xD4, 0x2F, 0x0F, 0x3A, 0xCB, 0xA4, 0x0D, 0x93, 0x6C, 0xCC, 0x9D, 0xC1, 0xB2, 0xFB, 0xFD, 0xAE, 0x40, 0x31, 0xAC, 0x69, 0x52, 0x21, 0x92, 0xB3, 0x27, 0xDF, 0xEA, 0xEE, 0x2C, 0x82, 0xBB, 0xF7, 0x40, 0x32, 0xD5, 0x14, 0xC4, 0x94, 0x12, 0xEC, 0xB8, 0x1F, 0xCA, 0x59, 0xE3, 0xC1, 0x78, 0xF3, 0x85, 0xD8, 0x47, 0xA5, 0xD7, 0x02, 0x1A, 0x65, 0x79, 0x97, 0x0D, 0x24, 0xF4, 0xF0, 0x67, 0x6E, 0x75, 0x2D, 0xBF, 0x10, 0x3D, 0xA8, 0x7D, 0xEF, 0x7F, 0x60, 0xE4, 0xE6, 0x05, 0x82, 0x89, 0x5D, 0xDF, 0xC6, 0xD2, 0x6C, 0x07, 0x91, 0x33, 0x98, 0x42, 0xF0, 0x02, 0x00, 0x25, 0x38, 0xC5, 0x85, 0x69, 0x8A, 0x7D, 0x2F, 0x95, 0x6C, 0x43, 0x9A, 0xB8, 0x81, 0xE2, 0xD0, 0x07, 0x35, 0xAA, 0x05, 0x41, 0xC9, 0x1E, 0xAF, 0xE4, 0x04, 0x3B, 0x19, 0xB8, 0x73, 0xA2, 0xAC, 0x4B, 0x1E, 0x66, 0x48, 0xD8, 0x72, 0x1F, 0xAC, 0xF6, 0xCB, 0xBC, 0x90, 0x09, 0xCA, 0xEC, 0x0C, 0xDC, 0xF9, 0x2C, 0xD7, 0xEB, 0xAE, 0xA3, 0xA4, 0x47, 0xD7, 0x33, 0x2F, 0x8A, 0xCA, 0xBC, 0x5E, 0xF0, 0x77, 0xE4, 0x97, 0x98, 0x97, 0xC7, 0x10, 0x91, 0x7D, 0x2A, 0xA6, 0xFF, 0x46, 0x83, 0x97, 0xDE, 0xE9, 0xE2, 0x17, 0x03, 0x06, 0x14, 0xE2, 0xD7, 0xB1, 0x1D, 0x77, 0xAF, 0x51, 0x27, 0x5B, 0x5E, 0x69, 0xB8, 0x81, 0xE6, 0x11, 0xC5, 0x43, 0x23, 0x81, 0x04, 0x62, 0xFF, 0xE9, 0x46, 0xB8, 0xD8, 0x44, 0xDB, 0xA5, 0xCC, 0x31, 0x54, 0x34, 0xCE, 0x3E, 0x82, 0xD6, 0xBF, 0x7A, 0x0B, 0x64, 0x21, 0x6D, 0x88, 0x7E, 0x5B, 0x45, 0x12, 0x1E, 0x63, 0x8D, 0x49, 0xA7, 0x1D, 0xD9, 0x1E, 0x06, 0xCD, 0xE8, 0xBA, 0x2C, 0x8C, 0x69, 0x32, 0xEA, 0xBE, 0x60, 0x71 }; static const unsigned char rsa_p[] = { 0xFA, 0xAC, 0xE1, 0x37, 0x5E, 0x32, 0x11, 0x34, 0xC6, 0x72, 0x58, 0x2D, 0x91, 0x06, 0x3E, 0x77, 0xE7, 0x11, 0x21, 0xCD, 0x4A, 0xF8, 0xA4, 0x3F, 0x0F, 0xEF, 0x31, 0xE3, 0xF3, 0x55, 0xA0, 0xB9, 0xAC, 0xB6, 0xCB, 0xBB, 0x41, 0xD0, 0x32, 0x81, 0x9A, 0x8F, 0x7A, 0x99, 0x30, 0x77, 0x6C, 0x68, 0x27, 0xE2, 0x96, 0xB5, 0x72, 0xC9, 0xC3, 0xD4, 0x42, 0xAA, 0xAA, 0xCA, 0x95, 0x8F, 0xFF, 0xC9, 0x9B, 0x52, 0x34, 0x30, 0x1D, 0xCF, 0xFE, 0xCF, 0x3C, 0x56, 0x68, 0x6E, 0xEF, 0xE7, 0x6C, 0xD7, 0xFB, 0x99, 0xF5, 0x4A, 0xA5, 0x21, 0x1F, 0x2B, 0xEA, 0x93, 0xE8, 0x98, 0x26, 0xC4, 0x6E, 0x42, 0x21, 0x5E, 0xA0, 0xA1, 0x2A, 0x58, 0x35, 0xBB, 0x10, 0xE7, 0xBA, 0x27, 0x0A, 0x3B, 0xB3, 0xAF, 0xE2, 0x75, 0x36, 0x04, 0xAC, 0x56, 0xA0, 0xAB, 0x52, 0xDE, 0xCE, 0xDD, 0x2C, 0x28, 0x77, 0x03 }; static const unsigned char rsa_q[] = { 0xDF, 0xB7, 0x52, 0xB6, 0xD7, 0xC0, 0xE2, 0x96, 0xE7, 0xC9, 0xFE, 0x5D, 0x71, 0x5A, 0xC4, 0x40, 0x96, 0x2F, 0xE5, 0x87, 0xEA, 0xF3, 0xA5, 0x77, 0x11, 0x67, 0x3C, 0x8D, 0x56, 0x08, 0xA7, 0xB5, 0x67, 0xFA, 0x37, 0xA8, 0xB8, 0xCF, 0x61, 0xE8, 0x63, 0xD8, 0x38, 0x06, 0x21, 0x2B, 0x92, 0x09, 0xA6, 0x39, 0x3A, 0xEA, 0xA8, 0xB4, 0x45, 0x4B, 0x36, 0x10, 0x4C, 0xE4, 0x00, 0x66, 0x71, 0x65, 0xF8, 0x0B, 0x94, 0x59, 0x4F, 0x8C, 0xFD, 0xD5, 0x34, 0xA2, 0xE7, 0x62, 0x84, 0x0A, 0xA7, 0xBB, 0xDB, 0xD9, 0x8A, 0xCD, 0x05, 0xE1, 0xCC, 0x57, 0x7B, 0xF1, 0xF1, 0x1F, 0x11, 0x9D, 0xBA, 0x3E, 0x45, 0x18, 0x99, 0x1B, 0x41, 0x64, 0x43, 0xEE, 0x97, 0x5D, 0x77, 0x13, 0x5B, 0x74, 0x69, 0x73, 0x87, 0x95, 0x05, 0x07, 0xBE, 0x45, 0x07, 0x17, 0x7E, 0x4A, 0x69, 0x22, 0xF3, 0xDB, 0x05, 0x39 }; static const unsigned char rsa_dp[] = { 0x5E, 0xD8, 0xDC, 0xDA, 0x53, 0x44, 0xC4, 0x67, 0xE0, 0x92, 0x51, 0x34, 0xE4, 0x83, 0xA5, 0x4D, 0x3E, 0xDB, 0xA7, 0x9B, 0x82, 0xBB, 0x73, 0x81, 0xFC, 0xE8, 0x77, 0x4B, 0x15, 0xBE, 0x17, 0x73, 0x49, 0x9B, 0x5C, 0x98, 0xBC, 0xBD, 0x26, 0xEF, 0x0C, 0xE9, 0x2E, 0xED, 0x19, 0x7E, 0x86, 0x41, 0x1E, 0x9E, 0x48, 0x81, 0xDD, 0x2D, 0xE4, 0x6F, 0xC2, 0xCD, 0xCA, 0x93, 0x9E, 0x65, 0x7E, 0xD5, 0xEC, 0x73, 0xFD, 0x15, 0x1B, 0xA2, 0xA0, 0x7A, 0x0F, 0x0D, 0x6E, 0xB4, 0x53, 0x07, 0x90, 0x92, 0x64, 0x3B, 0x8B, 0xA9, 0x33, 0xB3, 0xC5, 0x94, 0x9B, 0x4C, 0x5D, 0x9C, 0x7C, 0x46, 0xA4, 0xA5, 0x56, 0xF4, 0xF3, 0xF8, 0x27, 0x0A, 0x7B, 0x42, 0x0D, 0x92, 0x70, 0x47, 0xE7, 0x42, 0x51, 0xA9, 0xC2, 0x18, 0xB1, 0x58, 0xB1, 0x50, 0x91, 0xB8, 0x61, 0x41, 0xB6, 0xA9, 0xCE, 0xD4, 0x7C, 0xBB }; static const unsigned char rsa_dq[] = { 0x54, 0x09, 0x1F, 0x0F, 0x03, 0xD8, 0xB6, 0xC5, 0x0C, 0xE8, 0xB9, 0x9E, 0x0C, 0x38, 0x96, 0x43, 0xD4, 0xA6, 0xC5, 0x47, 0xDB, 0x20, 0x0E, 0xE5, 0xBD, 0x29, 0xD4, 0x7B, 0x1A, 0xF8, 0x41, 0x57, 0x49, 0x69, 0x9A, 0x82, 0xCC, 0x79, 0x4A, 0x43, 0xEB, 0x4D, 0x8B, 0x2D, 0xF2, 0x43, 0xD5, 0xA5, 0xBE, 0x44, 0xFD, 0x36, 0xAC, 0x8C, 0x9B, 0x02, 0xF7, 0x9A, 0x03, 0xE8, 0x19, 0xA6, 0x61, 0xAE, 0x76, 0x10, 0x93, 0x77, 0x41, 0x04, 0xAB, 0x4C, 0xED, 0x6A, 0xCC, 0x14, 0x1B, 0x99, 0x8D, 0x0C, 0x6A, 0x37, 0x3B, 0x86, 0x6C, 0x51, 0x37, 0x5B, 0x1D, 0x79, 0xF2, 0xA3, 0x43, 0x10, 0xC6, 0xA7, 0x21, 0x79, 0x6D, 0xF9, 0xE9, 0x04, 0x6A, 0xE8, 0x32, 0xFF, 0xAE, 0xFD, 0x1C, 0x7B, 0x8C, 0x29, 0x13, 0xA3, 0x0C, 0xB2, 0xAD, 0xEC, 0x6C, 0x0F, 0x8D, 0x27, 0x12, 0x7B, 0x48, 0xB2, 0xDB, 0x31 }; static const unsigned char rsa_qInv[] = { 0x8D, 0x1B, 0x05, 0xCA, 0x24, 0x1F, 0x0C, 0x53, 0x19, 0x52, 0x74, 0x63, 0x21, 0xFA, 0x78, 0x46, 0x79, 0xAF, 0x5C, 0xDE, 0x30, 0xA4, 0x6C, 0x20, 0x38, 0xE6, 0x97, 0x39, 0xB8, 0x7A, 0x70, 0x0D, 0x8B, 0x6C, 0x6D, 0x13, 0x74, 0xD5, 0x1C, 0xDE, 0xA9, 0xF4, 0x60, 0x37, 0xFE, 0x68, 0x77, 0x5E, 0x0B, 0x4E, 0x5E, 0x03, 0x31, 0x30, 0xDF, 0xD6, 0xAE, 0x85, 0xD0, 0x81, 0xBB, 0x61, 0xC7, 0xB1, 0x04, 0x5A, 0xC4, 0x6D, 0x56, 0x1C, 0xD9, 0x64, 0xE7, 0x85, 0x7F, 0x88, 0x91, 0xC9, 0x60, 0x28, 0x05, 0xE2, 0xC6, 0x24, 0x8F, 0xDD, 0x61, 0x64, 0xD8, 0x09, 0xDE, 0x7E, 0xD3, 0x4A, 0x61, 0x1A, 0xD3, 0x73, 0x58, 0x4B, 0xD8, 0xA0, 0x54, 0x25, 0x48, 0x83, 0x6F, 0x82, 0x6C, 0xAF, 0x36, 0x51, 0x2A, 0x5D, 0x14, 0x2F, 0x41, 0x25, 0x00, 0xDD, 0xF8, 0xF3, 0x95, 0xFE, 0x31, 0x25, 0x50, 0x12 }; static const ST_KAT_PARAM rsa_crt_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_D, rsa_d), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_FACTOR, rsa_p), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_FACTOR, rsa_q), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_EXPONENT, rsa_dp), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_EXPONENT, rsa_dq), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_COEFFICIENT, rsa_qInv), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM rsa_pub_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM rsa_priv_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_D, rsa_d), ST_KAT_PARAM_END() }; static const ST_KAT_PARAM rsa_enc_params[] = { ST_KAT_PARAM_UTF8STRING(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, OSSL_PKEY_RSA_PAD_MODE_NONE), ST_KAT_PARAM_END() }; static const unsigned char rsa_expected_sig[256] = { 0xad, 0xbe, 0x2a, 0xaf, 0x16, 0x85, 0xc5, 0x00, 0x91, 0x3e, 0xd0, 0x49, 0xfb, 0x3a, 0x81, 0xb9, 0x6c, 0x28, 0xbc, 0xbf, 0xea, 0x96, 0x5f, 0xe4, 0x9f, 0x99, 0xf7, 0x18, 0x8c, 0xec, 0x60, 0x28, 0xeb, 0x29, 0x02, 0x49, 0xfc, 0xda, 0xd7, 0x78, 0x68, 0xf8, 0xe1, 0xe9, 0x4d, 0x20, 0x6d, 0x32, 0xa6, 0xde, 0xfc, 0xe4, 0xda, 0xcc, 0x6c, 0x75, 0x36, 0x6b, 0xff, 0x5a, 0xac, 0x01, 0xa8, 0xc2, 0xa9, 0xe6, 0x8b, 0x18, 0x3e, 0xec, 0xea, 0x4c, 0x4a, 0x9e, 0x00, 0x09, 0xd1, 0x8a, 0x69, 0x1b, 0x8b, 0xd9, 0xad, 0x37, 0xe5, 0x7c, 0xff, 0x7d, 0x59, 0x56, 0x3e, 0xa0, 0xc6, 0x32, 0xd8, 0x35, 0x2f, 0xff, 0xfb, 0x05, 0x02, 0xcd, 0xd7, 0x19, 0xb9, 0x00, 0x86, 0x2a, 0xcf, 0xaa, 0x78, 0x16, 0x4b, 0xf1, 0xa7, 0x59, 0xef, 0x7d, 0xe8, 0x74, 0x23, 0x5c, 0xb2, 0xd4, 0x8a, 0x99, 0xa5, 0xbc, 0xfa, 0x63, 0xd8, 0xf7, 0xbd, 0xc6, 0x00, 0x13, 0x06, 0x02, 0x9a, 0xd4, 0xa7, 0xb4, 0x3d, 0x61, 0xab, 0xf1, 0xc2, 0x95, 0x59, 0x9b, 0x3d, 0x67, 0x1f, 0xde, 0x57, 0xb6, 0xb6, 0x9f, 0xb0, 0x87, 0xd6, 0x51, 0xd5, 0x3e, 0x00, 0xe2, 0xc9, 0xa0, 0x03, 0x66, 0xbc, 0x01, 0xb3, 0x8e, 0xfa, 0xf1, 0x15, 0xeb, 0x26, 0xf1, 0x5d, 0x81, 0x90, 0xb4, 0x1c, 0x00, 0x7c, 0x83, 0x4a, 0xa5, 0xde, 0x64, 0xae, 0xea, 0x6c, 0x43, 0xc3, 0x20, 0x77, 0x77, 0x42, 0x12, 0x24, 0xf5, 0xe3, 0x70, 0xdd, 0x59, 0x48, 0x9c, 0xef, 0xd4, 0x8a, 0x3c, 0x29, 0x6a, 0x0c, 0x9c, 0xf2, 0x13, 0xa4, 0x1c, 0x2f, 0x49, 0xcd, 0xb4, 0xaa, 0x28, 0x40, 0x34, 0xc6, 0x75, 0xba, 0x30, 0xe6, 0xd8, 0x5b, 0x2f, 0x08, 0xd0, 0x29, 0xa5, 0x39, 0xfb, 0x6e, 0x3b, 0x0f, 0x52, 0x2c, 0x68, 0xf0, 0x37, 0xa9, 0xd2, 0x56, 0xd6 }; static const unsigned char rsa_asym_plaintext_encrypt[256] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, }; static const unsigned char rsa_asym_expected_encrypt[256] = { 0x54, 0xac, 0x23, 0x96, 0x1d, 0x82, 0x5d, 0x8b, 0x8f, 0x36, 0x33, 0xd0, 0xf4, 0x02, 0xa2, 0x61, 0xb1, 0x13, 0xd4, 0x4a, 0x46, 0x06, 0x37, 0x3c, 0xbf, 0x40, 0x05, 0x3c, 0xc6, 0x3b, 0x64, 0xdc, 0x22, 0x22, 0xaf, 0x36, 0x79, 0x62, 0x45, 0xf0, 0x97, 0x82, 0x22, 0x44, 0x86, 0x4a, 0x7c, 0xfa, 0xac, 0x03, 0x21, 0x84, 0x3f, 0x31, 0xad, 0x2a, 0xa4, 0x6e, 0x7a, 0xc5, 0x93, 0xf3, 0x0f, 0xfc, 0xf1, 0x62, 0xce, 0x82, 0x12, 0x45, 0xc9, 0x35, 0xb0, 0x7a, 0xcd, 0x99, 0x8c, 0x91, 0x6b, 0x5a, 0xd3, 0x46, 0xdb, 0xf9, 0x9e, 0x52, 0x49, 0xbd, 0x1e, 0xe8, 0xda, 0xac, 0x61, 0x47, 0xc2, 0xda, 0xfc, 0x1e, 0xfb, 0x74, 0xd7, 0xd6, 0xc1, 0x18, 0x86, 0x3e, 0x20, 0x9c, 0x7a, 0xe1, 0x04, 0xb7, 0x38, 0x43, 0xb1, 0x4e, 0xa0, 0xd8, 0xc1, 0x39, 0x4d, 0xe1, 0xd3, 0xb0, 0xb3, 0xf1, 0x82, 0x87, 0x1f, 0x74, 0xb5, 0x69, 0xfd, 0x33, 0xd6, 0x21, 0x7c, 0x61, 0x60, 0x28, 0xca, 0x70, 0xdb, 0xa0, 0xbb, 0xc8, 0x73, 0xa9, 0x82, 0xf8, 0x6b, 0xd8, 0xf0, 0xc9, 0x7b, 0x20, 0xdf, 0x9d, 0xfb, 0x8c, 0xd4, 0xa2, 0x89, 0xe1, 0x9b, 0x04, 0xad, 0xaa, 0x11, 0x6c, 0x8f, 0xce, 0x83, 0x29, 0x56, 0x69, 0xbb, 0x00, 0x3b, 0xef, 0xca, 0x2d, 0xcd, 0x52, 0xc8, 0xf1, 0xb3, 0x9b, 0xb4, 0x4f, 0x6d, 0x9c, 0x3d, 0x69, 0xcc, 0x6d, 0x1f, 0x38, 0x4d, 0xe6, 0xbb, 0x0c, 0x87, 0xdc, 0x5f, 0xa9, 0x24, 0x93, 0x03, 0x46, 0xa2, 0x33, 0x6c, 0xf4, 0xd8, 0x5d, 0x68, 0xf3, 0xd3, 0xe0, 0xf2, 0x30, 0xdb, 0xf5, 0x4f, 0x0f, 0xad, 0xc7, 0xd0, 0xaa, 0x47, 0xd9, 0x9f, 0x85, 0x1b, 0x2e, 0x6c, 0x3c, 0x57, 0x04, 0x29, 0xf4, 0xf5, 0x66, 0x7d, 0x93, 0x4a, 0xaa, 0x05, 0x52, 0x55, 0xc1, 0xc6, 0x06, 0x90, 0xab, }; #ifndef OPENSSL_NO_EC /* ECDSA key data */ static const char ecd_prime_curve_name[] = "secp224r1"; static const unsigned char ecd_prime_priv[] = { 0x98, 0x1f, 0xb5, 0xf1, 0xfc, 0x87, 0x1d, 0x7d, 0xde, 0x1e, 0x01, 0x64, 0x09, 0x9b, 0xe7, 0x1b, 0x9f, 0xad, 0x63, 0xdd, 0x33, 0x01, 0xd1, 0x50, 0x80, 0x93, 0x50, 0x30 }; static const unsigned char ecd_prime_pub[] = { 0x04, 0x95, 0x47, 0x99, 0x44, 0x29, 0x8f, 0x51, 0x39, 0xe2, 0x53, 0xec, 0x79, 0xb0, 0x4d, 0xde, 0x87, 0x1a, 0x76, 0x54, 0xd5, 0x96, 0xb8, 0x7a, 0x6d, 0xf4, 0x1c, 0x2c, 0x87, 0x91, 0x5f, 0xd5, 0x31, 0xdd, 0x24, 0xe5, 0x78, 0xd9, 0x08, 0x24, 0x8a, 0x49, 0x99, 0xec, 0x55, 0xf2, 0x82, 0xb3, 0xc4, 0xb7, 0x33, 0x68, 0xe4, 0x24, 0xa9, 0x12, 0x82 }; static const ST_KAT_PARAM ecdsa_prime_key[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecdh_curve_name), ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecdh_pub), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecdh_privd), ST_KAT_PARAM_END() }; static const unsigned char ecdsa_expected_sig[] = { 0x30, 0x45, 0x02, 0x21, 0x00, 0x8b, 0x03, 0x2a, 0xc7, 0xea, 0x25, 0x32, 0x0d, 0xeb, 0xe5, 0x54, 0xf3, 0xc5, 0xf0, 0x96, 0xfe, 0x3d, 0x13, 0xa0, 0xba, 0x7b, 0x6f, 0x64, 0x23, 0xb5, 0x85, 0xe5, 0xf7, 0x5a, 0xe5, 0x5a, 0x85, 0x02, 0x20, 0x0a, 0x29, 0x4d, 0x58, 0x35, 0x3d, 0x01, 0xc1, 0x49, 0xe0, 0xff, 0x96, 0xc6, 0x33, 0x1c, 0x9e, 0xb8, 0xf2, 0xb6, 0x31, 0xb6, 0x17, 0xc0, 0xee, 0x65, 0x04, 0x7f, 0x57, 0x59, 0x93, 0xab, 0xef }; static const unsigned char ecdsa_sw_expected_sig[] = { 0x30, 0x44, 0x02, 0x20, 0x2b, 0x42, 0xf5, 0x76, 0xd0, 0x7f, 0x41, 0x65, 0xff, 0x65, 0xd1, 0xf3, 0xb1, 0x50, 0x0f, 0x81, 0xe4, 0x4c, 0x31, 0x6f, 0x1f, 0x0b, 0x3e, 0xf5, 0x73, 0x25, 0xb6, 0x9a, 0xca, 0x46, 0x10, 0x4f, 0x02, 0x20, 0x17, 0xe8, 0x64, 0x30, 0xf8, 0x37, 0x2e, 0xd0, 0x64, 0xd8, 0x4b, 0xcc, 0x04, 0x76, 0xe5, 0x66, 0xf4, 0xce, 0xae, 0x2c, 0x7c, 0x93, 0xe3, 0x88, 0xf0, 0x6d, 0xde, 0x62, 0x3c, 0x49, 0xbf, 0xec }; # ifndef OPENSSL_NO_EC2M static const char ecd_bin_curve_name[] = "sect233r1"; static const unsigned char ecd_bin_priv[] = { 0x00, 0x6d, 0xd6, 0x39, 0x9d, 0x2a, 0xa2, 0xc8, 0x8c, 0xfc, 0x7b, 0x80, 0x66, 0xaa, 0xe1, 0xaa, 0xba, 0xee, 0xcb, 0xfd, 0xc9, 0xe5, 0x36, 0x38, 0x2e, 0xf7, 0x37, 0x6d, 0xd3, 0x20 }; static const unsigned char ecd_bin_pub[] = { 0x04, 0x00, 0x06, 0xe2, 0x56, 0xf7, 0x37, 0xf9, 0xea, 0xb6, 0xd1, 0x0f, 0x59, 0xfa, 0x23, 0xc3, 0x93, 0xa8, 0xb2, 0x26, 0xe2, 0x5c, 0x08, 0xbe, 0x63, 0x49, 0x26, 0xdc, 0xc7, 0x1e, 0x6f, 0x01, 0x32, 0x3b, 0xe6, 0x54, 0x8d, 0xc1, 0x13, 0x3e, 0x54, 0xb2, 0x66, 0x89, 0xb2, 0x82, 0x0a, 0x72, 0x02, 0xa8, 0xe9, 0x6f, 0x54, 0xfd, 0x3a, 0x6b, 0x99, 0xb6, 0x8f, 0x80, 0x46 }; static const ST_KAT_PARAM ecdsa_bin_key[] = { ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecdh_p384_curve_name), ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecdh_p384_pub), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecdh_p384_privd), ST_KAT_PARAM_END() }; static const unsigned char ecdsa_bin_sign_exp[] = { 0x30, 0x65, 0x02, 0x31, 0x00, 0x8e, 0xfb, 0x76, 0xf9, 0x87, 0x17, 0x68, 0x2e, 0x92, 0x4f, 0x59, 0x6f, 0x87, 0x7a, 0xb0, 0x29, 0x7b, 0x79, 0x1b, 0xb3, 0x35, 0x6e, 0x30, 0x32, 0xef, 0xf5, 0x19, 0x4e, 0xe3, 0x58, 0xdc, 0x5a, 0x59, 0x96, 0x1e, 0x8e, 0x82, 0xf1, 0x3f, 0x9a, 0xd6, 0xa0, 0xee, 0x01, 0x3d, 0xf4, 0xab, 0x7a, 0x02, 0x30, 0x64, 0x00, 0xda, 0xc5, 0xd1, 0x10, 0xc2, 0x30, 0x96, 0xaa, 0x91, 0x14, 0x74, 0x3f, 0x49, 0x76, 0xc8, 0x67, 0xad, 0x83, 0x67, 0xdd, 0xcf, 0x04, 0x03, 0xff, 0xd6, 0x44, 0xed, 0x21, 0x76, 0xcb, 0x55, 0x13, 0xa0, 0x88, 0xae, 0x4e, 0x7b, 0x2b, 0x0e, 0x17, 0x1c, 0xf7, 0x0b, 0x5e, 0x89, 0x18 }; static const unsigned char ecdsa_sw_bin_sign_exp[] = { 0x30, 0x65, 0x02, 0x30, 0x30, 0xea, 0x51, 0x4f, 0xc0, 0xd3, 0x8d, 0x82, 0x08, 0x75, 0x6f, 0x06, 0x81, 0x13, 0xc7, 0xca, 0xda, 0x9f, 0x66, 0xa3, 0xb4, 0x0e, 0xa3, 0xb3, 0x13, 0xd0, 0x40, 0xd9, 0xb5, 0x7d, 0xd4, 0x1a, 0x33, 0x27, 0x95, 0xd0, 0x2c, 0xc7, 0xd5, 0x07, 0xfc, 0xef, 0x9f, 0xaf, 0x01, 0xa2, 0x70, 0x88, 0x02, 0x31, 0x00, 0xd7, 0x14, 0xf7, 0x38, 0xdf, 0x37, 0xfc, 0x12, 0x71, 0xfe, 0x25, 0x2a, 0x11, 0x6a, 0x87, 0x88, 0xe1, 0x24, 0x56, 0xe6, 0x4e, 0xaa, 0xfb, 0xe0, 0x1d, 0xa4, 0xe3, 0xfc, 0x88, 0xd1, 0xe8, 0xfb, 0x35, 0xf3, 0x9c, 0xe7, 0x26, 0x7a, 0x39, 0xab, 0xd1, 0xa3, 0xde, 0x5f, 0xd1, 0x94, 0x84, 0x09 }; # endif /* OPENSSL_NO_EC2M */ #endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_DSA /* dsa 2048 */ static const unsigned char dsa_p[] = { 0xa2, 0x9b, 0x88, 0x72, 0xce, 0x8b, 0x84, 0x23, 0xb7, 0xd5, 0xd2, 0x1d, 0x4b, 0x02, 0xf5, 0x7e, 0x03, 0xe9, 0xe6, 0xb8, 0xa2, 0x58, 0xdc, 0x16, 0x61, 0x1b, 0xa0, 0x98, 0xab, 0x54, 0x34, 0x15, 0xe4, 0x15, 0xf1, 0x56, 0x99, 0x7a, 0x3e, 0xe2, 0x36, 0x65, 0x8f, 0xa0, 0x93, 0x26, 0x0d, 0xe3, 0xad, 0x42, 0x2e, 0x05, 0xe0, 0x46, 0xf9, 0xec, 0x29, 0x16, 0x1a, 0x37, 0x5f, 0x0e, 0xb4, 0xef, 0xfc, 0xef, 0x58, 0x28, 0x5c, 0x5d, 0x39, 0xed, 0x42, 0x5d, 0x7a, 0x62, 0xca, 0x12, 0x89, 0x6c, 0x4a, 0x92, 0xcb, 0x19, 0x46, 0xf2, 0x95, 0x2a, 0x48, 0x13, 0x3f, 0x07, 0xda, 0x36, 0x4d, 0x1b, 0xdf, 0x6b, 0x0f, 0x71, 0x39, 0x98, 0x3e, 0x69, 0x3c, 0x80, 0x05, 0x9b, 0x0e, 0xac, 0xd1, 0x47, 0x9b, 0xa9, 0xf2, 0x85, 0x77, 0x54, 0xed, 0xe7, 0x5f, 0x11, 0x2b, 0x07, 0xeb, 0xbf, 0x35, 0x34, 0x8b, 0xbf, 0x3e, 0x01, 0xe0, 0x2f, 0x2d, 0x47, 0x3d, 0xe3, 0x94, 0x53, 0xf9, 0x9d, 0xd2, 0x36, 0x75, 0x41, 0xca, 0xca, 0x3b, 0xa0, 0x11, 0x66, 0x34, 0x3d, 0x7b, 0x5b, 0x58, 0xa3, 0x7b, 0xd1, 0xb7, 0x52, 0x1d, 0xb2, 0xf1, 0x3b, 0x86, 0x70, 0x71, 0x32, 0xfe, 0x09, 0xf4, 0xcd, 0x09, 0xdc, 0x16, 0x18, 0xfa, 0x34, 0x01, 0xeb, 0xf9, 0xcc, 0x7b, 0x19, 0xfa, 0x94, 0xaa, 0x47, 0x20, 0x88, 0x13, 0x3d, 0x6c, 0xb2, 0xd3, 0x5c, 0x11, 0x79, 0xc8, 0xc8, 0xff, 0x36, 0x87, 0x58, 0xd5, 0x07, 0xd9, 0xf9, 0xa1, 0x7d, 0x46, 0xc1, 0x10, 0xfe, 0x31, 0x44, 0xce, 0x9b, 0x02, 0x2b, 0x42, 0xe4, 0x19, 0xeb, 0x4f, 0x53, 0x88, 0x61, 0x3b, 0xfc, 0x3e, 0x26, 0x24, 0x1a, 0x43, 0x2e, 0x87, 0x06, 0xbc, 0x58, 0xef, 0x76, 0x11, 0x72, 0x78, 0xde, 0xab, 0x6c, 0xf6, 0x92, 0x61, 0x82, 0x91, 0xb7 }; static const unsigned char dsa_q[] = { 0xa3, 0xbf, 0xd9, 0xab, 0x78, 0x84, 0x79, 0x4e, 0x38, 0x34, 0x50, 0xd5, 0x89, 0x1d, 0xc1, 0x8b, 0x65, 0x15, 0x7b, 0xdc, 0xfc, 0xda, 0xc5, 0x15, 0x18, 0x90, 0x28, 0x67 }; static const unsigned char dsa_g[] = { 0x68, 0x19, 0x27, 0x88, 0x69, 0xc7, 0xfd, 0x3d, 0x2d, 0x7b, 0x77, 0xf7, 0x7e, 0x81, 0x50, 0xd9, 0xad, 0x43, 0x3b, 0xea, 0x3b, 0xa8, 0x5e, 0xfc, 0x80, 0x41, 0x5a, 0xa3, 0x54, 0x5f, 0x78, 0xf7, 0x22, 0x96, 0xf0, 0x6c, 0xb1, 0x9c, 0xed, 0xa0, 0x6c, 0x94, 0xb0, 0x55, 0x1c, 0xfe, 0x6e, 0x6f, 0x86, 0x3e, 0x31, 0xd1, 0xde, 0x6e, 0xed, 0x7d, 0xab, 0x8b, 0x0c, 0x9d, 0xf2, 0x31, 0xe0, 0x84, 0x34, 0xd1, 0x18, 0x4f, 0x91, 0xd0, 0x33, 0x69, 0x6b, 0xb3, 0x82, 0xf8, 0x45, 0x5e, 0x98, 0x88, 0xf5, 0xd3, 0x1d, 0x47, 0x84, 0xec, 0x40, 0x12, 0x02, 0x46, 0xf4, 0xbe, 0xa6, 0x17, 0x94, 0xbb, 0xa5, 0x86, 0x6f, 0x09, 0x74, 0x64, 0x63, 0xbd, 0xf8, 0xe9, 0xe1, 0x08, 0xcd, 0x95, 0x29, 0xc3, 0xd0, 0xf6, 0xdf, 0x80, 0x31, 0x6e, 0x2e, 0x70, 0xaa, 0xeb, 0x1b, 0x26, 0xcd, 0xb8, 0xad, 0x97, 0xbc, 0x3d, 0x28, 0x7e, 0x0b, 0x8d, 0x61, 0x6c, 0x42, 0xe6, 0x5b, 0x87, 0xdb, 0x20, 0xde, 0xb7, 0x00, 0x5b, 0xc4, 0x16, 0x74, 0x7a, 0x64, 0x70, 0x14, 0x7a, 0x68, 0xa7, 0x82, 0x03, 0x88, 0xeb, 0xf4, 0x4d, 0x52, 0xe0, 0x62, 0x8a, 0xf9, 0xcf, 0x1b, 0x71, 0x66, 0xd0, 0x34, 0x65, 0xf3, 0x5a, 0xcc, 0x31, 0xb6, 0x11, 0x0c, 0x43, 0xda, 0xbc, 0x7c, 0x5d, 0x59, 0x1e, 0x67, 0x1e, 0xaf, 0x7c, 0x25, 0x2c, 0x1c, 0x14, 0x53, 0x36, 0xa1, 0xa4, 0xdd, 0xf1, 0x32, 0x44, 0xd5, 0x5e, 0x83, 0x56, 0x80, 0xca, 0xb2, 0x53, 0x3b, 0x82, 0xdf, 0x2e, 0xfe, 0x55, 0xec, 0x18, 0xc1, 0xe6, 0xcd, 0x00, 0x7b, 0xb0, 0x89, 0x75, 0x8b, 0xb1, 0x7c, 0x2c, 0xbe, 0x14, 0x44, 0x1b, 0xd0, 0x93, 0xae, 0x66, 0xe5, 0x97, 0x6d, 0x53, 0x73, 0x3f, 0x4f, 0xa3, 0x26, 0x97, 0x01, 0xd3, 0x1d, 0x23, 0xd4, 0x67 }; static const unsigned char dsa_pub[] = { 0xa0, 0x12, 0xb3, 0xb1, 0x70, 0xb3, 0x07, 0x22, 0x79, 0x57, 0xb7, 0xca, 0x20, 0x61, 0xa8, 0x16, 0xac, 0x7a, 0x2b, 0x3d, 0x9a, 0xe9, 0x95, 0xa5, 0x11, 0x9c, 0x38, 0x5b, 0x60, 0x3b, 0xf6, 0xf6, 0xc5, 0xde, 0x4d, 0xc5, 0xec, 0xb5, 0xdf, 0xa4, 0xa4, 0x1c, 0x68, 0x66, 0x2e, 0xb2, 0x5b, 0x63, 0x8b, 0x7e, 0x26, 0x20, 0xba, 0x89, 0x8d, 0x07, 0xda, 0x6c, 0x49, 0x91, 0xe7, 0x6c, 0xc0, 0xec, 0xd1, 0xad, 0x34, 0x21, 0x07, 0x70, 0x67, 0xe4, 0x7c, 0x18, 0xf5, 0x8a, 0x92, 0xa7, 0x2a, 0xd4, 0x31, 0x99, 0xec, 0xb7, 0xbd, 0x84, 0xe7, 0xd3, 0xaf, 0xb9, 0x01, 0x9f, 0x0e, 0x9d, 0xd0, 0xfb, 0xaa, 0x48, 0x73, 0x00, 0xb1, 0x30, 0x81, 0xe3, 0x3c, 0x90, 0x28, 0x76, 0x43, 0x6f, 0x7b, 0x03, 0xc3, 0x45, 0x52, 0x84, 0x81, 0xd3, 0x62, 0x81, 0x5e, 0x24, 0xfe, 0x59, 0xda, 0xc5, 0xac, 0x34, 0x66, 0x0d, 0x4c, 0x8a, 0x76, 0xcb, 0x99, 0xa7, 0xc7, 0xde, 0x93, 0xeb, 0x95, 0x6c, 0xd6, 0xbc, 0x88, 0xe5, 0x8d, 0x90, 0x10, 0x34, 0x94, 0x4a, 0x09, 0x4b, 0x01, 0x80, 0x3a, 0x43, 0xc6, 0x72, 0xb9, 0x68, 0x8c, 0x0e, 0x01, 0xd8, 0xf4, 0xfc, 0x91, 0xc6, 0x2a, 0x3f, 0x88, 0x02, 0x1f, 0x7b, 0xd6, 0xa6, 0x51, 0xb1, 0xa8, 0x8f, 0x43, 0xaa, 0x4e, 0xf2, 0x76, 0x53, 0xd1, 0x2b, 0xf8, 0xb7, 0x09, 0x9f, 0xdf, 0x6b, 0x46, 0x10, 0x82, 0xf8, 0xe9, 0x39, 0x10, 0x7b, 0xfd, 0x2f, 0x72, 0x10, 0x08, 0x7d, 0x32, 0x6c, 0x37, 0x52, 0x00, 0xf1, 0xf5, 0x1e, 0x7e, 0x74, 0xa3, 0x41, 0x31, 0x90, 0x1b, 0xcd, 0x08, 0x63, 0x52, 0x1f, 0xf8, 0xd6, 0x76, 0xc4, 0x85, 0x81, 0x86, 0x87, 0x36, 0xc5, 0xe5, 0x1b, 0x16, 0xa4, 0xe3, 0x92, 0x15, 0xea, 0x0b, 0x17, 0xc4, 0x73, 0x59, 0x74, 0xc5, 0x16 }; static const unsigned char dsa_priv[] = { 0x6c, 0xca, 0xee, 0xf6, 0xd7, 0x3b, 0x4e, 0x80, 0xf1, 0x1c, 0x17, 0xb8, 0xe9, 0x62, 0x7c, 0x03, 0x66, 0x35, 0xba, 0xc3, 0x94, 0x23, 0x50, 0x5e, 0x40, 0x7e, 0x5c, 0xb7 }; static const ST_KAT_PARAM dsa_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_P, dsa_p), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_Q, dsa_q), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_FFC_G, dsa_g), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PUB_KEY, dsa_pub), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, dsa_priv), ST_KAT_PARAM_END() }; static const unsigned char dsa_exp[] = { 0x30, 0x3d, 0x02, 0x1c, 0x6d, 0x9e, 0xf2, 0x04, 0x19, 0x63, 0x63, 0x95, 0x01, 0x86, 0x02, 0xd2, 0x88, 0x0e, 0x98, 0x4b, 0x3c, 0x19, 0xe0, 0xe2, 0x66, 0x2d, 0xa3, 0xb8, 0xf7, 0x63, 0x4c, 0xf7, 0x02, 0x1d, 0x00, 0x95, 0x10, 0x39, 0x20, 0x73, 0x4d, 0x28, 0x4c, 0x0f, 0x42, 0x1e, 0x73, 0x05, 0xfe, 0xa7, 0xb9, 0x55, 0x81, 0x4f, 0x07, 0x99, 0x9d, 0xaa, 0xce, 0x2a, 0xd3, 0xd4, 0x8b }; #endif /* OPENSSL_NO_DSA */ static const ST_KAT_SIGN st_kat_sign_tests[] = { { OSSL_SELF_TEST_DESC_SIGN_RSA, "RSA", "SHA-256", rsa_crt_key, ITM(rsa_expected_sig) }, # ifndef OPENSSL_NO_EC { QAT_SELF_TEST_DESC_SIGN_ECDSAP256, "EC", "SHA-256", ecdsa_prime_key, ITM(ecdsa_expected_sig) }, # ifndef OPENSSL_NO_EC2M { QAT_SELF_TEST_DESC_SIGN_ECDSAP384, "EC", "SHA-256", ecdsa_bin_key, ITM(ecdsa_bin_sign_exp) }, # endif #endif /* OPENSSL_NO_EC */ #ifdef ENABLE_QAT_HW_DSA # ifndef OPENSSL_NO_DSA { OSSL_SELF_TEST_DESC_SIGN_DSA, "DSA", "SHA-256", dsa_key, ITM(dsa_exp), }, # endif /* OPENSSL_NO_DSA */ #endif /* ENABLE_QAT_HW_DSA */ }; static const ST_KAT_SIGN st_kat_sw_sign_tests[] = { { OSSL_SELF_TEST_DESC_SIGN_RSA, "RSA", "SHA-256", rsa_crt_key, ITM(rsa_expected_sig) }, # ifndef OPENSSL_NO_EC { QAT_SELF_TEST_DESC_SIGN_ECDSAP256, "EC", "SHA-256", ecdsa_prime_key, ITM(ecdsa_sw_expected_sig) }, # ifndef OPENSSL_NO_EC2M { QAT_SELF_TEST_DESC_SIGN_ECDSAP384, "EC", "SHA-256", ecdsa_bin_key, ITM(ecdsa_sw_bin_sign_exp) }, # endif # endif /* OPENSSL_NO_EC */ #ifdef ENABLE_QAT_HW_DSA # ifndef OPENSSL_NO_DSA { OSSL_SELF_TEST_DESC_SIGN_DSA, "DSA", "SHA-256", dsa_key, ITM(dsa_exp), }, # endif /* OPENSSL_NO_DSA */ #endif /* ENABLE_QAT_HW_DSA */ }; static const ST_KAT_ASYM_CIPHER st_kat_asym_cipher_tests[] = { { OSSL_SELF_TEST_DESC_ASYM_RSA_ENC, "RSA", 1, rsa_pub_key, rsa_enc_params, ITM(rsa_asym_plaintext_encrypt), ITM(rsa_asym_expected_encrypt), }, { OSSL_SELF_TEST_DESC_ASYM_RSA_DEC, "RSA", 0, rsa_priv_key, rsa_enc_params, ITM(rsa_asym_expected_encrypt), ITM(rsa_asym_plaintext_encrypt), }, { OSSL_SELF_TEST_DESC_ASYM_RSA_DEC, "RSA", 0, rsa_crt_key, rsa_enc_params, ITM(rsa_asym_expected_encrypt), ITM(rsa_asym_plaintext_encrypt), }, }; qatengine-1.9.0/qat_self_test_kats.c000066400000000000000000000740341500416242000175210ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_self_test_kats.c * * This file provides an implementation to perform qat self test * *****************************************************************************/ #include "qat_fips.h" #ifndef FIPS_MODULE # define FIPS_MODULE 1 #endif #ifdef ENABLE_QAT_FIPS extern int qat_fips_kat_test; int add_params(OSSL_PARAM_BLD *bld, const ST_KAT_PARAM *params, BN_CTX *ctx) { int ret = 0; const ST_KAT_PARAM *p; BIGNUM *bn = NULL; if (params == NULL) { WARN("params are NULL,...so quitting..\n"); return 1; } for (p = params; p->data != NULL; ++p) { switch (p->type) { case OSSL_PARAM_UNSIGNED_INTEGER: bn = BN_CTX_get(ctx); if (bn == NULL || (BN_bin2bn(p->data, p->data_len, bn) == NULL) || !OSSL_PARAM_BLD_push_BN(bld, p->name, bn)) goto err; break; case OSSL_PARAM_UTF8_STRING: if (!OSSL_PARAM_BLD_push_utf8_string(bld, p->name, p->data, p->data_len)) goto err; break; case OSSL_PARAM_OCTET_STRING: if (!OSSL_PARAM_BLD_push_octet_string(bld, p->name, p->data, p->data_len)) goto err; break; case OSSL_PARAM_INTEGER: if (!OSSL_PARAM_BLD_push_int(bld, p->name, *(int *)p->data)) goto err; break; default: break; } } ret = 1; err: return ret; } /* * Helper function to setup a EVP_CipherInit * Used to hide the complexity of Authenticated ciphers. */ static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const ST_KAT_CIPHER *t, int enc) { unsigned char *in_tag = NULL; int pad = 0, tmp; /* Flag required for Key wrapping */ EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); if (t->tag == NULL) { /* Use a normal cipher init */ return EVP_CipherInit_ex(ctx, cipher, NULL, t->key, t->iv, enc) && EVP_CIPHER_CTX_set_padding(ctx, pad); } /* The authenticated cipher init */ if (!enc) in_tag = (unsigned char *)t->tag; return EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc) && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, t->iv_len, NULL) && (in_tag == NULL || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, t->tag_len, in_tag)) && EVP_CipherInit_ex(ctx, NULL, NULL, t->key, t->iv, enc) && EVP_CIPHER_CTX_set_padding(ctx, pad) && EVP_CipherUpdate(ctx, NULL, &tmp, t->aad, t->aad_len); } int RSA_components_update(RSA *rsa, size_t size) { int ret = 1; BIGNUM *n = NULL; BIGNUM *e = NULL; BIGNUM *d = NULL; BIGNUM *p = NULL; BIGNUM *q = NULL; BIGNUM *dmp1 = NULL; BIGNUM *dmq1 = NULL; BIGNUM *iqmp = NULL; if (size > 1024 && size <= 2048) { /* bignumber format needed for RSA structure */ if (((n = BN_bin2bn(rsa_n, sizeof(rsa_n), NULL)) == NULL) || ((e = BN_bin2bn(rsa_e, sizeof(rsa_e), NULL)) == NULL) || ((d = BN_bin2bn(rsa_d, sizeof(rsa_d), NULL)) == NULL) || ((p = BN_bin2bn(rsa_p, sizeof(rsa_p), NULL)) == NULL) || ((q = BN_bin2bn(rsa_q, sizeof(rsa_q), NULL)) == NULL) || ((dmp1 = BN_bin2bn(rsa_dp, sizeof(rsa_dp), NULL)) == NULL) || ((dmq1 = BN_bin2bn(rsa_dq, sizeof(rsa_dq), NULL)) == NULL) || ((iqmp = BN_bin2bn(rsa_qInv, sizeof(rsa_qInv), NULL)) == NULL)) { WARN("# FAIL RSA - Failed setting parameters\n"); ret = 0; if (n) BN_free(n); if (e) BN_free(e); if (d) BN_free(d); if (p) BN_free(p); if (q) BN_free(q); if (dmp1) BN_free(dmp1); if (dmq1) BN_free(dmq1); if (iqmp) BN_free(iqmp); } } RSA_set0_key(rsa, n, e, d); RSA_set0_factors(rsa, p, q); RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp); return ret; } static int QAT_self_test_sign(const ST_KAT_SIGN *t, TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { qat_fips_kat_test = 1; int ret = 0; OSSL_PARAM *params = NULL, *params_sig = NULL; OSSL_PARAM_BLD *bld = NULL; EVP_PKEY_CTX *sctx = NULL, *kctx = NULL; EVP_PKEY *pkey = NULL; OSSL_SELF_TEST *st = args->st; unsigned char sig[256]; const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; BN_CTX *bnctx = NULL; size_t siglen = sizeof(sig); static const unsigned char dgst[] = { 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81, 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28, 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69 }; if (t->sig_expected == NULL) typ = OSSL_SELF_TEST_TYPE_PCT_SIGNATURE; OSSL_SELF_TEST_onbegin(st, typ, t->desc); bnctx = BN_CTX_new_ex(libctx); if (bnctx == NULL) { WARN("Error in memory creation for BN_CTX\n"); ret = 0; goto err; } bld = OSSL_PARAM_BLD_new(); if (bld == NULL) { WARN("Error in memory creation for OSSL_PARAM_BLD\n"); ret = 0; goto err; } if (!add_params(bld, t->key, bnctx)) { WARN("Error in add_params API\n"); ret = 0; goto err; } params = OSSL_PARAM_BLD_to_param(bld); /* Create a EVP_PKEY_CTX to load the DSA key into */ kctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, ""); if (kctx == NULL || params == NULL) { WARN("Error in kctx creation..\n"); ret = 0; goto err; } if (EVP_PKEY_fromdata_init(kctx) <= 0 || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) { WARN("Error in EVP_PKEY_fromdata_init || EVP_PKEY_fromdata \n"); ret = 0; goto err; } /* Create a EVP_PKEY_CTX to use for the signing operation */ sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL); /*calling QAT provider qat_signature_rsa_sign_init() * using EVP_PKEY_sign_init*/ if (sctx == NULL || EVP_PKEY_sign_init(sctx) <= 0) { WARN("Error in EVP_PKEY_CTX_new_from_pkey\n"); ret = 0; goto err; } /* set signature parameters */ if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST, t->mdalgorithm, strlen(t->mdalgorithm) + 1)) { WARN("Error in OSSL_PARAM_BLD_push_utf8_string\n"); goto err; } params_sig = OSSL_PARAM_BLD_to_param(bld); if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) { WARN("Error in EVP_PKEY_CTX_set_params..\n"); ret = 0; goto err; } if (!strcmp(t->desc, OSSL_SELF_TEST_DESC_SIGN_RSA)) { QAT_EVP_PKEY_CTX *tctx = (QAT_EVP_PKEY_CTX *) sctx; QAT_PROV_RSA_CTX *vprsactx = (QAT_PROV_RSA_CTX *) tctx->op.sig.algctx; if (!RSA_components_update((RSA *)vprsactx->rsa, siglen * 8)) { WARN("Error: Failed to update RSA components!!..\n"); } } if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0) WARN("Error: Failed at EVP_PKEY_sign API!!..\n"); if (EVP_PKEY_verify_init(sctx) <= 0) WARN("Error: Failed at EVP_PKEY_verify_init API!!..\n"); if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0) { WARN("Error: Failed at EVP_PKEY_CTX_set_params API!!..\n"); ret = 0; goto err; } /* * Used by RSA, for other key types where the signature changes, we * can only use the verify. */ DUMPL("Expected Sign", t->sig_expected, t->sig_expected_len); DUMPL("Actual Sign", sig, siglen); if (t->sig_expected != NULL && (siglen != t->sig_expected_len || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0)) { WARN("Error: Failed at expected sig..\n"); ret = 0; goto err; } OSSL_SELF_TEST_oncorrupt_byte(st, sig); if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0) { WARN("Error: Failed at EVP_PKEY_verify..\n"); ret = 0; goto err; } ret = 1; err: BN_CTX_free(bnctx); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(kctx); EVP_PKEY_CTX_free(sctx); OSSL_PARAM_free(params); OSSL_PARAM_free(params_sig); OSSL_PARAM_BLD_free(bld); OSSL_SELF_TEST_onend(st, ret); qat_fips_kat_test = 0; return ret; } # if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) static int QAT_self_test_ka(const ST_KAT_KAS *t, TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int ret = 0; EVP_PKEY_CTX *kactx = NULL, *dctx = NULL; EVP_PKEY *pkey = NULL, *peerkey = NULL; OSSL_PARAM *params = NULL; OSSL_PARAM *params_peer = NULL; unsigned char secret[256]; size_t secret_len = sizeof(secret); OSSL_PARAM_BLD *bld = NULL; BN_CTX *bnctx = NULL; OSSL_SELF_TEST *st = args->st; OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KA, t->desc); bnctx = BN_CTX_new_ex(libctx); if (bnctx == NULL) goto err; bld = OSSL_PARAM_BLD_new(); if (bld == NULL) goto err; if (!add_params(bld, t->key_group, bnctx) || !add_params(bld, t->key_host_data, bnctx)) goto err; params = OSSL_PARAM_BLD_to_param(bld); if (!add_params(bld, t->key_group, bnctx) || !add_params(bld, t->key_peer_data, bnctx)) goto err; params_peer = OSSL_PARAM_BLD_to_param(bld); if (params == NULL || params_peer == NULL) goto err; /* Create a EVP_PKEY_CTX to load the DH keys into */ kactx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, ""); if (kactx == NULL) goto err; if (EVP_PKEY_fromdata_init(kactx) <= 0 || EVP_PKEY_fromdata(kactx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) goto err; if (EVP_PKEY_fromdata_init(kactx) <= 0 || EVP_PKEY_fromdata(kactx, &peerkey, EVP_PKEY_KEYPAIR, params_peer) <= 0) goto err; /* Create a EVP_PKEY_CTX to perform key derivation */ dctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL); if (dctx == NULL) goto err; if (EVP_PKEY_derive_init(dctx) <= 0 || EVP_PKEY_derive_set_peer(dctx, peerkey) <= 0 || EVP_PKEY_derive(dctx, secret, &secret_len) <= 0) goto err; OSSL_SELF_TEST_oncorrupt_byte(st, secret); DUMPL("Expected Secret Key", t->expected, t->expected_len); DUMPL("Actual Secret Key", secret, secret_len); if (secret_len != t->expected_len || memcmp(secret, t->expected, t->expected_len) != 0) goto err; ret = 1; err: BN_CTX_free(bnctx); EVP_PKEY_free(pkey); EVP_PKEY_free(peerkey); EVP_PKEY_CTX_free(kactx); EVP_PKEY_CTX_free(dctx); OSSL_PARAM_free(params_peer); OSSL_PARAM_free(params); OSSL_PARAM_BLD_free(bld); OSSL_SELF_TEST_onend(st, ret); return ret; } # endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */ static int QAT_self_test_kdf(const ST_KAT_KDF *t, TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int ret = 0; unsigned char out[128], *prf_out[128]; EVP_KDF *kdf = NULL; EVP_KDF_CTX *ctx = NULL; BN_CTX *bnctx = NULL; OSSL_PARAM *params = NULL; OSSL_PARAM_BLD *bld = NULL; OSSL_SELF_TEST *st = args->st; OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc); if (!strcmp(t->desc, "TLS13_KDF_EXTRACT_256") || !strcmp(t->desc, "TLS13_KDF_EXPAND_256") || !strcmp(t->desc, "TLS13_KDF_EXTRACT_384") || !strcmp(t->desc, "TLS13_KDF_EXPAND_384")) { bld = OSSL_PARAM_BLD_new(); if (bld == NULL) { printf("Error in memory creation for OSSL_PARAM_BLD\n"); ret = 0; goto err; } kdf = EVP_KDF_fetch(libctx, t->algorithm, ""); if (kdf == NULL) { printf("Error in kdf fetch..\n"); ret = 0; goto err; } ctx = EVP_KDF_CTX_new(kdf); if (ctx == NULL) { printf("Error in kctx creation..\n"); ret = 0; goto err; } bnctx = BN_CTX_new_ex(libctx); if (bnctx == NULL) { printf("Error in memory creation for BN_CTX\n"); ret = 0; goto err; } if (!add_params(bld, t->params, bnctx)) { printf("Error in add_params API\n"); ret = 0; goto err; } params = OSSL_PARAM_BLD_to_param(bld); if (params == NULL) goto err; if (t->expected_len > sizeof(out)) goto err; if (EVP_KDF_derive(ctx, out, t->expected_len, params) <= 0) goto err; } if (!strcmp(t->desc, "TLS12_PRF_256") || !strcmp(t->desc, "TLS12_PRF_384")) { *prf_out = out; if (QAT_TlsPrf_Ops(args, *prf_out, t->expected_len, t->desc) <= 0) { WARN("Error in QAT_TlsPrf_Ops API\n"); goto err; } } OSSL_SELF_TEST_oncorrupt_byte(st, out); if (!strcmp(t->desc, "TLS12_PRF_256") || !strcmp(t->desc, "TLS12_PRF_384")) { if (memcmp(*prf_out, t->expected, t->expected_len) != 0) goto err; } if (!strcmp(t->desc, "TLS13_KDF_EXTRACT_256") || !strcmp(t->desc, "TLS13_KDF_EXPAND_256") || !strcmp(t->desc, "TLS13_KDF_EXTRACT_384") || !strcmp(t->desc, "TLS13_KDF_EXPAND_384")) { DUMPL("Expected Secret Key", t->expected, t->expected_len); DUMPL("Actual Secret Key", out, t->expected_len); if (memcmp(out, t->expected, t->expected_len) != 0) goto err; } ret = 1; err: EVP_KDF_free(kdf); EVP_KDF_CTX_free(ctx); BN_CTX_free(bnctx); OSSL_PARAM_free(params); OSSL_PARAM_BLD_free(bld); OSSL_SELF_TEST_onend(st, ret); return ret; } /* Test a single KAT for encrypt/decrypt */ static int QAT_self_test_cipher(const ST_KAT_CIPHER *t, TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int ret = 0, encrypt = 1, len = 0, ct_len = 0, pt_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *cipher = NULL; unsigned char ct_buf[256] = { 0 }; unsigned char pt_buf[256] = { 0 }; OSSL_SELF_TEST *st = args->st; OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc); ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) goto err; cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, NULL); if (cipher == NULL) goto err; /* Encrypt plain text message */ if ((t->mode & CIPHER_MODE_ENCRYPT) != 0) { if (!cipher_init(ctx, cipher, t, encrypt) || !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt, t->base.pt_len) || !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len)) goto err; OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf); ct_len += len; if (ct_len != (int)t->base.expected_len || memcmp(t->base.expected, ct_buf, ct_len) != 0) goto err; if (t->tag != NULL) { unsigned char tag[16] = { 0 }; if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len, tag) || memcmp(tag, t->tag, t->tag_len) != 0) goto err; } } /* Decrypt cipher text */ if ((t->mode & CIPHER_MODE_DECRYPT) != 0) { if (!(cipher_init(ctx, cipher, t, !encrypt) && EVP_CipherUpdate(ctx, pt_buf, &len, t->base.expected, t->base.expected_len) && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, t->tag_len, (void *)t->tag) && EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len))) goto err; OSSL_SELF_TEST_oncorrupt_byte(st, pt_buf); pt_len += len; if (pt_len != (int)t->base.pt_len || memcmp(pt_buf, t->base.pt, pt_len) != 0) goto err; } ret = 1; err: EVP_CIPHER_free(cipher); EVP_CIPHER_CTX_free(ctx); OSSL_SELF_TEST_onend(st, ret); return ret; } static int QAT_self_test_digest(const ST_KAT_DIGEST *t, TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int ok = 0; unsigned char out[EVP_MAX_MD_SIZE]; unsigned int out_len = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT); EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL); OSSL_SELF_TEST *st = args->st; OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc); if (ctx == NULL || md == NULL || !EVP_DigestInit_ex(ctx, md, NULL) || !EVP_DigestUpdate(ctx, t->pt, t->pt_len) || !EVP_DigestFinal(ctx, out, &out_len)) goto err; /* Optional corruption */ OSSL_SELF_TEST_oncorrupt_byte(st, out); DUMPL("Expected output", t->expected, t->expected_len); DUMPL("Actual output", out, out_len); if (out_len != t->expected_len || memcmp(out, t->expected, out_len) != 0) goto err; ok = 1; err: EVP_MD_free(md); EVP_MD_CTX_free(ctx); OSSL_SELF_TEST_onend(st, ok); return ok; } static int qat_self_test_kdfs(TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int i, ret = 1, count = 0; if (args->enable_async) { qat_async_kdf_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } else { qat_kdf_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) { if ((qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXTRACT_256")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXPAND_256")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXTRACT_384")) || (qat_hw_hkdf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS13_KDF_EXPAND_384")) || (qat_hw_prf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS12_PRF_256")) || (qat_hw_prf_offload == 0 && !strcmp(st_kat_kdf_tests[i].desc, "TLS12_PRF_384"))) continue; if (!QAT_self_test_kdf(&st_kat_kdf_tests[i], args, libctx)) { ret = 0; count++; } if (args->enable_async) { qat_async_kdf_result->desc[i] = st_kat_kdf_tests[i].desc; qat_async_kdf_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_KDF; qat_async_kdf_result->result[i] = ret; } else { qat_kdf_result->desc[i] = st_kat_kdf_tests[i].desc; qat_kdf_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_KDF; qat_kdf_result->result[i] = ret; } ret = 1; } return (count ? 0 : 1); } static int qat_self_test_digests(TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int i, ret = 1; if (args->enable_async) { qat_async_digest_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } else { qat_digest_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) { if (qat_hw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA3")) continue; if (qat_sw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA256")) continue; if (qat_sw_sha_offload == 0 && !strcmp(st_kat_digest_tests[i].desc, "SHA512")) continue; if (!QAT_self_test_digest(&st_kat_digest_tests[i], args, libctx)) ret = 0; if (args->enable_async) { qat_async_digest_result->desc[i] = st_kat_digest_tests[i].desc; qat_async_digest_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_DIGEST; qat_async_digest_result->result[i] = ret; } else { qat_digest_result->desc[i] = st_kat_digest_tests[i].desc; qat_digest_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_DIGEST; qat_digest_result->result[i] = ret; } } return ret; } static int qat_self_test_ciphers(TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int i, ret = 1, count = 0; if (args->enable_async) { qat_async_cipher_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } else { qat_cipher_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_gcm_offload == 0 && !strcmp(st_kat_cipher_tests[i].base.desc, "AES_GCM"))) continue; } else { if ((qat_sw_gcm_offload == 0 && !strcmp(st_kat_cipher_tests[i].base.desc, "AES_GCM"))) continue; } if (!QAT_self_test_cipher(&st_kat_cipher_tests[i], args, libctx)) { ret = 0; count++; } if (args->enable_async) { qat_async_cipher_result->desc[i] = st_kat_cipher_tests[i].base.desc; qat_async_cipher_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_CIPHER; qat_async_cipher_result->result[i] = ret; } else { qat_cipher_result->desc[i] = st_kat_cipher_tests[i].base.desc; qat_cipher_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_CIPHER; qat_cipher_result->result[i] = ret; } ret = 1; } return (count ? 0 : 1); } static int qat_self_test_kas(TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int ret = 1, count = 0; if (args->enable_async) { qat_async_kas_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } else { qat_kas_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } # if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) int i; for (i = 0; i < (int)OSSL_NELEM(st_kat_kas_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if (qat_hw_offload) { if ((qat_hw_dh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "DH")) || (qat_hw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP256")) || (qat_hw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP384")) || (qat_hw_ecx_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX25519")) || (qat_hw_ecx_448_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX448"))) continue; } else { if ((qat_hw_dh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "DH")) || (qat_sw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP256")) || (qat_sw_ecdh_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECDHP384")) || (qat_sw_ecx_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX25519")) || (qat_hw_ecx_448_offload == 0 && !strcmp(st_kat_kas_tests[i].desc, "ECX448"))) continue; } if (!QAT_self_test_ka(&st_kat_kas_tests[i], args, libctx)) { ret = 0; count++; } if (args->enable_async) { qat_async_kas_result->desc[i] = st_kat_kas_tests[i].desc; qat_async_kas_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_KA; qat_async_kas_result->result[i] = ret; } else { qat_kas_result->desc[i] = st_kat_kas_tests[i].desc; qat_kas_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_KA; qat_kas_result->result[i] = ret; } ret = 1; } # endif return (count ? 0 : 1); } static int qat_self_test_signatures(TEST_PARAMS *args, OSSL_LIB_CTX *libctx) { int i, ret = 1, count = 0; if (args->enable_async) { qat_async_signature_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } else { qat_signature_result = (QAT_SELF_TEST_RESULT *) calloc(1, sizeof(QAT_SELF_TEST_RESULT)); } /* Since expected sig value is different for QAT_HW QAT_SW * So that, Using different test vectors */ if (qat_hw_offload) { /* Self test for QAT_HW signature algorithms */ for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if ((qat_hw_dsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "DSA")) || (qat_hw_rsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "RSA")) || (qat_hw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP256")) || (qat_hw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP384"))) continue; if (!QAT_self_test_sign(&st_kat_sign_tests[i], args, libctx)) { ret = 0; count++; } if (args->enable_async) { qat_async_signature_result->desc[i] = st_kat_sign_tests[i].desc; qat_async_signature_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; qat_async_signature_result->result[i] = ret; } else { qat_signature_result->desc[i] = st_kat_sign_tests[i].desc; qat_signature_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; qat_signature_result->result[i] = ret; } ret = 1; } } else { /* Self test for QAT_SW signature algorithms */ for (i = 0; i < (int)OSSL_NELEM(st_kat_sw_sign_tests); ++i) { /* To skip self test when particular algorithm support is disabled */ if ((qat_hw_dsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "DSA")) || (qat_sw_rsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "RSA")) || (qat_sw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP256")) || (qat_sw_ecdsa_offload == 0 && !strcmp(st_kat_sign_tests[i].desc, "ECDSAP384"))) continue; if (!QAT_self_test_sign(&st_kat_sw_sign_tests[i], args, libctx)) { ret = 0; count++; } if (args->enable_async) { qat_async_signature_result->desc[i] = st_kat_sw_sign_tests[i].desc; qat_async_signature_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; qat_async_signature_result->result[i] = ret; } else { qat_signature_result->desc[i] = st_kat_sw_sign_tests[i].desc; qat_signature_result->type[i] = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE; qat_signature_result->result[i] = ret; } ret = 1; } } return (count ? 0 : 1); } /* * Run the algorithm KAT's. * Return 1 is successful, otherwise return 0. * Here we will call or add required tests. * This runs all the tests regardless of if any fail. */ int QAT_SELF_TEST_kats(void *args) { int ret = 1; TEST_PARAMS *temp_args = (TEST_PARAMS *) args; if (!qat_self_test_signatures(temp_args, temp_args->provctx)) ret = 0; if (!qat_self_test_kas(temp_args, temp_args->provctx)) ret = 0; if (!qat_self_test_ciphers(temp_args, temp_args->provctx)) ret = 0; if (!qat_self_test_kdfs(temp_args, temp_args->provctx)) ret = 0; if (!qat_self_test_digests(temp_args, temp_args->provctx)) ret = 0; return ret; } #endif qatengine-1.9.0/qat_self_test_tls_prf.c000066400000000000000000000652561500416242000202360ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2022 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include "test/tests.h" #include "qat_utils.h" #define MD_SERVER_FINISHED_SEED2_LEN 32 #define MD_SERVER_FINISHED_SEC_LEN 48 #define MD_SERVER_FINISHED_BUFF_SIZE 12 #define MD_SERVER_FINISHED_MASTER_SEC_LEN 12 #define MD_CLIENT_FINISHED_SEED2_LEN 32 #define MD_CLIENT_FINISHED_SEC_LEN 48 #define MD_CLIENT_FINISHED_BUFF_SIZE 12 #define MD_CLIENT_FINISHED_MASTER_SEC_LEN 12 #define MD_KEY_EXPANSION_SEED2_LEN 32 #define MD_KEY_EXPANSION_SEED3_LEN 32 #define MD_KEY_EXPANSION_SEC_LEN 48 #define MD_KEY_EXPANSION_BUFF_SIZE 104 #define MD_KEY_EXPANSION_MASTER_SEC_LEN 104 #define MASTER_SECRET_SEED2_LEN 32 #define MASTER_SECRET_SEED4_LEN 32 #define MASTER_SECRET_SEC_LEN 48 #define EXTENDED_MASTER_SECRET_SEED2_LEN 32 #define EXTENDED_MASTER_SECRET_SEC_LEN 48 static const unsigned char prf_sf_lseed2[] = { 0xD8, 0xDD, 0x4A, 0xC2, 0x78, 0xD2, 0x2C, 0xE6, 0x22, 0x9C, 0x18, 0x2C, 0x88, 0x1B, 0x4D, 0x7F, 0xC7, 0xC0, 0x71, 0x46, 0x8C, 0xE8, 0x86, 0x5B, 0x87, 0x5A, 0x31, 0x2E, 0x53, 0x33, 0xE1, 0x39 }; static const unsigned char prf_sf_lsec[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_sf_resMasSec_TLS1_2_SHA256[] = { 0x68, 0xCA, 0xCC, 0xAF, 0x1A, 0x9F, 0xAE, 0xE4, 0xFC, 0x23, 0xD5, 0xC6 }; static const unsigned char prf_sf_resMasSec_TLS1_2_SHA384[] = { 0xD3, 0xF1, 0xF1, 0x54, 0x13, 0x84, 0xD5, 0x48, 0x85, 0xDD, 0xEC, 0xD0 }; static const unsigned char prf_sf_resMasSec_TLS1_2_SHA512[] = { 0x3D, 0xFB, 0x40, 0x47, 0x89, 0x66, 0x7C, 0xDE, 0xFB, 0xDD, 0x59, 0x52 }; static const unsigned char prf_sf_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0x1D, 0xFA, 0xC3, 0xDE, 0xAE, 0x74, 0x2B, 0xE1, 0x87, 0xC0, 0x0B, 0x9B }; static const unsigned char prf_cf_lseed2[] = { 0xC2, 0xFA, 0x5E, 0xE1, 0x95, 0xCF, 0x3C, 0xF8, 0x09, 0xC8, 0x37, 0xC5, 0x80, 0x41, 0xFA, 0xC2, 0xE3, 0x7C, 0x2F, 0xCC, 0xA7, 0x50, 0x82, 0x6C, 0x9E, 0x5D, 0x87, 0x5F, 0x46, 0xD4, 0xF7, 0x02 }; static const unsigned char prf_cf_lsec[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_cf_resMasSec_TLS1_2_SHA256[] = { 0xC9, 0x86, 0xD8, 0xFE, 0x8D, 0x26, 0xCB, 0x11, 0xC8, 0xB3, 0xF6, 0xD3 }; static const unsigned char prf_cf_resMasSec_TLS1_2_SHA384[] = { 0x62, 0x8C, 0x23, 0xB7, 0x10, 0x0D, 0x85, 0x08, 0x35, 0x74, 0x14, 0x73 }; static const unsigned char prf_cf_resMasSec_TLS1_2_SHA512[] = { 0x9A, 0xEF, 0x80, 0x3C, 0xEE, 0x32, 0xBC, 0xBC, 0x1A, 0xC0, 0xA7, 0xDD }; static const unsigned char prf_cf_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0x67, 0x18, 0x75, 0xEF, 0xBE, 0x50, 0xAD, 0xD5, 0x94, 0x78, 0x53, 0x85 }; static const unsigned char prf_ke_lseed2[] = { 0xEF, 0x14, 0xF7, 0x48, 0x0C, 0x36, 0xB2, 0xF3, 0xFB, 0x4F, 0x9F, 0xBF, 0xBA, 0x6C, 0x6F, 0x0A, 0x27, 0xAB, 0xF8, 0x16, 0xFF, 0x37, 0xE9, 0x88, 0x0D, 0x8A, 0x3B, 0x59, 0x57, 0xA6, 0xC1, 0x7E }; static const unsigned char prf_ke_lseed3[] = { 0x88, 0x3E, 0x61, 0xAE, 0xE3, 0xB6, 0xD8, 0x62, 0x18, 0x86, 0x4A, 0x7D, 0x4B, 0x0A, 0xA5, 0xF9, 0xE7, 0xE7, 0xAA, 0xD5, 0x8B, 0xB1, 0xBD, 0x54, 0x1F, 0xF2, 0x47, 0xCC, 0xDA, 0xA8, 0x3F, 0x2D }; static const unsigned char prf_ke_lsec[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_ke_resMasSec_TLS1_2_SHA256[] = { 0x5E, 0xD9, 0x1F, 0x2F, 0x5C, 0x3A, 0x78, 0x82, 0x7C, 0xC3, 0xEA, 0x22, 0x47, 0x5F, 0x24, 0xD6, 0xEA, 0x8B, 0xCC, 0x40, 0xF5, 0xAD, 0xC1, 0x39, 0xBE, 0x15, 0x87, 0x85, 0x3A, 0x4C, 0x63, 0xA6, 0xBD, 0x5C, 0x58, 0x5D, 0xD8, 0xD9, 0x1F, 0x1D, 0xE1, 0x60, 0xD2, 0x2E, 0x59, 0x31, 0x0E, 0xFC, 0xB7, 0xFB, 0x0D, 0x9A, 0x4E, 0xF8, 0x8D, 0x72, 0x35, 0x6D, 0x8C, 0xEC, 0x99, 0x6F, 0x08, 0x41, 0xB3, 0xB5, 0xDA, 0xB6, 0x7F, 0x97, 0xF0, 0xFF, 0xAF, 0xF4, 0x05, 0x26, 0xC2, 0x05, 0x3D, 0x60, 0x18, 0xAD, 0x01, 0x59, 0xE6, 0x16, 0x06, 0x0C, 0x90, 0x81, 0x8D, 0x23, 0x08, 0x90, 0x57, 0x73, 0x56, 0xAE, 0xD6, 0x7F, 0x64, 0x2B, 0x29, 0x72 }; static const unsigned char prf_ke_resMasSec_TLS1_2_SHA384[] = { 0xB7, 0xC3, 0x82, 0xDE, 0x7C, 0x72, 0xA0, 0x3F, 0x4E, 0xF6, 0x4B, 0x3B, 0x92, 0x1A, 0xBA, 0x44, 0x58, 0x28, 0x3D, 0xA6, 0x2F, 0x02, 0x34, 0x2F, 0x0B, 0x75, 0x73, 0xB1, 0x69, 0x43, 0x40, 0xA5, 0x8A, 0x9B, 0xDC, 0x88, 0x06, 0x4E, 0x57, 0x62, 0xBC, 0x3A, 0xB6, 0x38, 0x30, 0x8A, 0x3E, 0x8C, 0x41, 0xA9, 0xF1, 0x54, 0xB9, 0xA5, 0x83, 0xDC, 0x3A, 0x3D, 0x52, 0x0C, 0xB9, 0x79, 0xC9, 0xAC, 0x10, 0xBD, 0x4F, 0x13, 0x8C, 0xBC, 0xA2, 0x99, 0x17, 0xBA, 0xA9, 0x0C, 0xF8, 0x20, 0x0C, 0x4F, 0x96, 0xA3, 0x39, 0x9B, 0x78, 0x8D, 0x1B, 0x21, 0x93, 0x14, 0x76, 0xBF, 0x7A, 0xA7, 0x80, 0x5E, 0xF3, 0x94, 0x56, 0xFB, 0x4B, 0x51, 0x01, 0x13 }; static const unsigned char prf_ke_resMasSec_TLS1_2_SHA512[] = { 0xBC, 0x50, 0xE2, 0x72, 0x61, 0xAC, 0x97, 0x4E, 0x89, 0x41, 0xAB, 0xBA, 0x39, 0xBD, 0xAC, 0x82, 0xCD, 0x7A, 0x8C, 0x4E, 0x2D, 0x22, 0xC5, 0x62, 0x3F, 0x2D, 0x4F, 0xB2, 0x55, 0x53, 0x7D, 0xC6, 0x58, 0xE2, 0xBF, 0x23, 0xF7, 0x03, 0x44, 0xF7, 0x1B, 0xE8, 0x13, 0x4A, 0xDC, 0x03, 0xFD, 0x49, 0x43, 0xB1, 0xB7, 0xAE, 0x60, 0x78, 0x41, 0x20, 0x27, 0x17, 0x0F, 0x18, 0x1F, 0xE4, 0x39, 0x49, 0x2E, 0xF9, 0x87, 0x2F, 0x3F, 0x45, 0xC1, 0x7D, 0x68, 0xC0, 0xCF, 0x4D, 0x6B, 0xA7, 0x55, 0x8D, 0xFF, 0x38, 0xE4, 0x22, 0x4F, 0x86, 0x86, 0xD1, 0x71, 0xA1, 0x51, 0x5B, 0x61, 0xA1, 0xFC, 0xB0, 0xEE, 0x5C, 0x07, 0x17, 0xA0, 0x90, 0x9F, 0x50 }; static const unsigned char prf_ke_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0x6C, 0x73, 0xAE, 0xFE, 0xB0, 0xBC, 0x7A, 0x0C, 0xF6, 0xBB, 0x28, 0xE7, 0x19, 0x01, 0x5C, 0x95, 0x4D, 0x46, 0xDA, 0xC2, 0xC6, 0xCD, 0x10, 0xE8, 0xF5, 0x19, 0xE9, 0x7A, 0xED, 0x75, 0x7F, 0xAC, 0x7F, 0x16, 0xAB, 0x42, 0x98, 0x52, 0x0D, 0x1C, 0xED, 0x73, 0x23, 0x57, 0x19, 0x45, 0x26, 0x51, 0xD2, 0xA1, 0xF2, 0xA1, 0x3D, 0xA9, 0x59, 0xBB, 0xD8, 0x63, 0x26, 0xFD, 0xCF, 0x95, 0x67, 0x71, 0x4A, 0xF0, 0xBB, 0xA1, 0xE4, 0xAE, 0xE1, 0x8C, 0xAE, 0xA7, 0xC3, 0xA6, 0xDE, 0xB1, 0x8C, 0x75, 0x12, 0x61, 0x27, 0xB0, 0x07, 0x78, 0x94, 0xF9, 0x8C, 0xDC, 0xF9, 0xE5, 0x1A, 0x3C, 0x90, 0x0B, 0xB5, 0x65, 0x17, 0x7E, 0xB9, 0x23, 0x71, 0x0C }; static const unsigned char prf_ms_lseed2[] = { 0x88, 0x3E, 0x61, 0xAE, 0xE3, 0xB6, 0xD8, 0x62, 0x18, 0x86, 0x4A, 0x7D, 0x4B, 0x0A, 0xA5, 0xF9, 0xE7, 0xE7, 0xAA, 0xD5, 0x8B, 0xB1, 0xBD, 0x54, 0x1F, 0xF2, 0x47, 0xCC, 0xDA, 0xA8, 0x3F, 0x2D }; static const unsigned char prf_ms_lseed4[] = { 0xEF, 0x14, 0xF7, 0x48, 0x0C, 0x36, 0xB2, 0xF3, 0xFB, 0x4F, 0x9F, 0xBF, 0xBA, 0x6C, 0x6F, 0x0A, 0x27, 0xAB, 0xF8, 0x16, 0xFF, 0x37, 0xE9, 0x88, 0x0D, 0x8A, 0x3B, 0x59, 0x57, 0xA6, 0xC1, 0x7E }; static const unsigned char prf_ms_lsec[] = { 0x03, 0x03, 0x0B, 0x03, 0x07, 0xEF, 0x7A, 0xDC, 0xFB, 0xD1, 0x86, 0xE3, 0x46, 0xC0, 0x45, 0x36, 0xA2, 0x73, 0x31, 0xE3, 0x7A, 0xC8, 0x45, 0x3A, 0xB9, 0x58, 0x0A, 0x4E, 0xA1, 0xC0, 0x73, 0x55, 0x57, 0x92, 0xA5, 0xCD, 0x1A, 0x76, 0xE8, 0xDD, 0xCF, 0xE3, 0x7A, 0x77, 0x48, 0xEE, 0x16, 0xAE }; static const unsigned char prf_ms_resMasSec_TLS1_2_SHA256[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_ms_resMasSec_TLS1_2_SHA384[] = { 0xD0, 0x90, 0xDE, 0x77, 0xDB, 0x2C, 0xBB, 0x24, 0x37, 0xEB, 0xB2, 0x9E, 0x65, 0xE4, 0xCB, 0xD0, 0x15, 0x60, 0x90, 0x61, 0x90, 0x82, 0x44, 0x86, 0x9B, 0x9C, 0x70, 0xB6, 0xBB, 0x17, 0x37, 0x6E, 0x55, 0xCD, 0x04, 0x61, 0x9F, 0xC1, 0x7A, 0x40, 0x32, 0x82, 0xCB, 0xC1, 0x70, 0xD5, 0xC4, 0xDA }; static const unsigned char prf_ms_resMasSec_TLS1_2_SHA512[] = { 0x36, 0x25, 0x70, 0x6A, 0x23, 0x20, 0x5D, 0x88, 0x3B, 0xAA, 0x7E, 0x7C, 0x72, 0xE1, 0x91, 0x9B, 0x6F, 0x91, 0x21, 0xAB, 0x51, 0x36, 0x12, 0xCB, 0x77, 0x10, 0x26, 0xBA, 0xC8, 0xC5, 0xAE, 0x8F, 0x05, 0x1C, 0x6D, 0xD0, 0x79, 0xED, 0x57, 0x0F, 0x4C, 0x0B, 0x79, 0xD3, 0x45, 0x22, 0x71, 0xCE }; static const unsigned char prf_ms_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0xB0, 0xCC, 0x9D, 0xAB, 0xA4, 0xA4, 0xF9, 0x9C, 0x0D, 0x17, 0x25, 0xF4, 0x82, 0xBB, 0x91, 0x20, 0x1F, 0xF8, 0xA3, 0x7A, 0x9A, 0x69, 0x00, 0x0B, 0x35, 0x4F, 0xE7, 0xA7, 0xBB, 0xBC, 0x96, 0x90, 0x83, 0x80, 0x42, 0xB5, 0x33, 0xE9, 0x60, 0x42, 0x9C, 0x4B, 0x8F, 0x7B, 0xA1, 0x2E, 0x4E, 0x19 }; static const unsigned char prf_ems_lseed2[] = { 0xFF, 0x77, 0x85, 0x63, 0xD4, 0x23, 0x6A, 0x57, 0xD4, 0x68, 0x83, 0x29, 0x6F, 0x86, 0x18, 0x6A, 0x4C, 0xF3, 0xC3, 0xF4, 0xC8, 0xDC, 0xDF, 0x97, 0x30, 0xD2, 0x2F, 0x9C, 0x5B, 0xA7, 0xD0, 0x5E }; static const unsigned char prf_ems_lsec[] = { 0x03, 0x03, 0xE3, 0x11, 0xC5, 0xED, 0xE6, 0x51, 0x41, 0xC3, 0x99, 0xC9, 0x87, 0x56, 0x8C, 0x46, 0xD0, 0x07, 0xA8, 0x3E, 0xE3, 0x7F, 0xBD, 0x60, 0x56, 0xA2, 0xD0, 0x61, 0x83, 0xFF, 0xA3, 0x0E, 0x21, 0x9A, 0x6C, 0x59, 0x79, 0x9D, 0x27, 0x23, 0xDD, 0xBC, 0x0C, 0x5D, 0xB9, 0x76, 0xA9, 0xC5 }; static const unsigned char prf_ems_resMasSec_TLS1_2_SHA256[] = { 0x44, 0x31, 0xBF, 0x20, 0xBF, 0xD7, 0xA8, 0x48, 0x0D, 0x6F, 0x4E, 0xE8, 0xC9, 0xF8, 0xC1, 0x6A, 0x65, 0xD1, 0x93, 0xE7, 0x54, 0x32, 0xA6, 0x10, 0x3F, 0x73, 0x4B, 0x32, 0x14, 0xE8, 0xE6, 0x33, 0x91, 0x84, 0x1F, 0x2F, 0xED, 0x71, 0xBC, 0x4C, 0x67, 0x11, 0x97, 0xCE, 0x0F, 0xB3, 0x5D, 0x0D }; static const unsigned char prf_ems_resMasSec_TLS1_2_SHA384[] = { 0xAA, 0x39, 0xE6, 0xF6, 0x6D, 0xD0, 0xA6, 0x3E, 0x09, 0x2D, 0xA2, 0xCA, 0x17, 0x2D, 0x91, 0xF4, 0xFB, 0x1F, 0x14, 0x3A, 0xB2, 0xF2, 0x55, 0xD8, 0xDA, 0x3B, 0xE4, 0x10, 0xEB, 0x02, 0x98, 0x72, 0xBA, 0xD7, 0xC0, 0x18, 0x18, 0xED, 0xB3, 0xE8, 0x52, 0x60, 0x90, 0x53, 0xB1, 0x4F, 0x89, 0x00 }; static const unsigned char prf_ems_resMasSec_TLS1_2_SHA512[] = { 0xD2, 0xBA, 0xC7, 0x9D, 0x39, 0xA4, 0x6B, 0x34, 0xBE, 0x3D, 0xA2, 0xEA, 0xE7, 0x8C, 0xDD, 0x66, 0xF2, 0xAF, 0x4E, 0xD1, 0x19, 0xAB, 0x65, 0x50, 0x58, 0xBB, 0x27, 0x87, 0x99, 0xCF, 0x1A, 0x0E, 0x8C, 0x65, 0x41, 0x57, 0x5F, 0xF4, 0xE2, 0xAB, 0x94, 0x1A, 0x75, 0xC8, 0x71, 0x33, 0x1C, 0x5B }; static const unsigned char prf_ems_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0xC3, 0x5D, 0xF1, 0xC2, 0x5B, 0x8B, 0x01, 0xB7, 0xA8, 0x9A, 0x71, 0x03, 0x0E, 0x01, 0x4C, 0x0E, 0xF9, 0xBB, 0x07, 0xC4, 0xDC, 0x62, 0xE6, 0xE0, 0x4C, 0x48, 0x02, 0x2E, 0x94, 0x94, 0xC9, 0x85, 0x38, 0xA4, 0x26, 0x4F, 0xDE, 0x90, 0xE8, 0x8A, 0xD6, 0x5D, 0xB9, 0x96, 0x7A, 0xA9, 0xC8, 0xF8 }; static int qat_prf(const EVP_MD **md, int md_count, const void *seed1, int seed1_len, const void *seed2, int seed2_len, const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, int slen, unsigned char *out, int olen); void populateMdServerFinished(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MD_SERVER_FINISHED_SEED2_LEN; *seed2 = (void *)&prf_sf_lseed2; seed3 = NULL; seed4 = NULL; seed5 = NULL; *sec_len = MD_SERVER_FINISHED_SEC_LEN; *sec = (void *)&prf_sf_lsec; *buff_size = MD_SERVER_FINISHED_BUFF_SIZE; *masterSecLen = MD_SERVER_FINISHED_MASTER_SEC_LEN; if (TLS1_2_VERSION == tls_version) { if (!strcmp(digest_kdf, "SHA256")) *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_2_SHA256; else if (!strcmp(digest_kdf, "SHA384")) *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_2_SHA384; else if (!strcmp(digest_kdf, "SHA512")) *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_2_SHA512; } else *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_TLS1_1_MD5SHA1; } void populateMdClientFinished(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MD_CLIENT_FINISHED_SEED2_LEN; *seed2 = (void *)&prf_cf_lseed2; seed3 = NULL; seed4 = NULL; seed5 = NULL; *sec_len = MD_CLIENT_FINISHED_SEC_LEN; *sec = (void *)&prf_cf_lsec; *buff_size = MD_CLIENT_FINISHED_BUFF_SIZE; *masterSecLen = MD_CLIENT_FINISHED_MASTER_SEC_LEN; if (TLS1_2_VERSION == tls_version) { if (!strcmp(digest_kdf, "SHA256")) { *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_2_SHA256; } else if (!strcmp(digest_kdf, "SHA384")) { *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_2_SHA384; } else if (!strcmp(digest_kdf, "SHA512")) { *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_TLS1_1_MD5SHA1; } } void populateMdKeyExpansion(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MD_KEY_EXPANSION_SEED2_LEN; *seed2 = (void *)&prf_ke_lseed2; *seed3_len = MD_KEY_EXPANSION_SEED3_LEN; *seed3 = (void *)&prf_ke_lseed3; seed4 = NULL; seed5 = NULL; *sec_len = MD_KEY_EXPANSION_SEC_LEN; *sec = (void *)&prf_ke_lsec; *buff_size = MD_KEY_EXPANSION_BUFF_SIZE; *masterSecLen = MD_KEY_EXPANSION_MASTER_SEC_LEN; if (TLS1_2_VERSION == tls_version) { if (!strcmp(digest_kdf, "SHA256")) { *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_2_SHA256; } else if (!strcmp(digest_kdf, "SHA384")) { *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_2_SHA384; } else if (!strcmp(digest_kdf, "SHA512")) { *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_TLS1_1_MD5SHA1; } } void populatemasterSecret(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MASTER_SECRET_SEED2_LEN; *seed2 = (void *)&prf_ms_lseed2; seed3 = NULL; *seed4_len = MASTER_SECRET_SEED4_LEN; *seed4 = (void *)&prf_ms_lseed4; seed5 = NULL; *sec_len = MASTER_SECRET_SEC_LEN; *sec = (void *)&prf_ms_lsec; *buff_size = SSL_MAX_MASTER_KEY_LENGTH; *masterSecLen = SSL_MAX_MASTER_KEY_LENGTH; if (TLS1_2_VERSION == tls_version) { if (!strcmp(digest_kdf, "SHA256")) { *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_2_SHA256; } else if (!strcmp(digest_kdf, "SHA384")) { *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_2_SHA384; } else if (!strcmp(digest_kdf, "SHA512")) { *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_TLS1_1_MD5SHA1; } } void populateExtendedMasterSecret(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = EXTENDED_MASTER_SECRET_SEED2_LEN; *seed2 = (void *)&prf_ems_lseed2; seed3 = NULL; seed4 = NULL; seed5 = NULL; *sec_len = EXTENDED_MASTER_SECRET_SEC_LEN; *sec = (void *)&prf_ems_lsec; *buff_size = SSL_MAX_MASTER_KEY_LENGTH; *masterSecLen = SSL_MAX_MASTER_KEY_LENGTH; if (TLS1_2_VERSION == tls_version) { if (!strcmp(digest_kdf, "SHA256")) { *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_2_SHA256; } else if (!strcmp(digest_kdf, "SHA384")) { *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_2_SHA384; } else if (!strcmp(digest_kdf, "SHA512")) { *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_TLS1_1_MD5SHA1; } } static int qat_prf(const EVP_MD **md, int md_count, const void *seed1, int seed1_len, const void *seed2, int seed2_len, const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, int slen, unsigned char *out, int olen) { EVP_PKEY_CTX *pctx = NULL; int ret = 0; size_t outlen = olen; if (md == NULL) { /* Should never happen */ WARN("# FAIL: md has not been set\n"); return 0; } pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, *md) <= 0) goto err; if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, slen) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed4, seed4_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed5, seed5_len) <= 0) goto err; if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) goto err; ret = 1; err: if (ret == 0) WARN("# FAIL: performing qat_prf operations\n"); EVP_PKEY_CTX_free(pctx); return ret; } static int TlsPrf_Ops(void *args, unsigned char *out, size_t outlen, const char *desc) { int operation = 4; char *digest_kdf = "NULL"; const EVP_MD *md[SSL_MAX_DIGEST] = { 0 }; int md_count = 0, version = 0; void *seed1 = NULL, *seed2 = NULL, *seed3 = NULL, *seed4 = NULL, *seed5 = NULL; int seed1_len = 0, seed2_len = 0, seed3_len = 0, seed4_len = 0, seed5_len = 0; int secSize = 0, buff_len = 0; unsigned char *secret = NULL, *expectedMasterSecret = NULL; size_t masterSecretSize = 0; int count = 0; OpenSSL_add_all_digests(); if (!strcmp(desc, "TLS12_PRF_256")) { digest_kdf = "SN_sha_256"; md[0] = EVP_get_digestbyname(SN_sha256); } else if (!strcmp(desc, "TLS12_PRF_384")) { digest_kdf = "SN_sha_384"; md[0] = EVP_get_digestbyname(SN_sha384); } for (; count < operation; count++) { md_count = 1; version = TLS1_2_VERSION; switch (operation) { case 0: /*TLS_MD_MASTER_SECRET_CONST */ if (count == 0) DEBUG("Validating: TLS_MD_MASTER_SECRET_CONST\n"); seed1 = TLS_MD_MASTER_SECRET_CONST; seed1_len = TLS_MD_MASTER_SECRET_CONST_SIZE; populatemasterSecret(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 1: /*TLS_MD_KEY_EXPANSION_CONST */ if (count == 0) DEBUG("Validating: TLS_MD_KEY_EXPANSION_CONST\n"); seed1 = TLS_MD_KEY_EXPANSION_CONST; seed1_len = TLS_MD_KEY_EXPANSION_CONST_SIZE; populateMdKeyExpansion(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 2: /*TLS_MD_CLIENT_FINISH_CONST */ if (count == 0) DEBUG("Validating: TLS_MD_CLIENT_FINISH_CONST\n"); seed1 = TLS_MD_CLIENT_FINISH_CONST; seed1_len = TLS_MD_CLIENT_FINISH_CONST_SIZE; populateMdClientFinished(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 3: /*TLS_MD_SERVER_FINISH_CONST */ if (count == 0) DEBUG("Validating: TLS_MD_SERVER_FINISH_CONST\n"); seed1 = TLS_MD_SERVER_FINISH_CONST; seed1_len = TLS_MD_SERVER_FINISH_CONST_SIZE; populateMdServerFinished(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 4: /*TLS_MD_EXTENDED_MASTER_SECRET_CONST */ if (count == 0) DEBUG("Validating: TLS_MD_EXTENDED_MASTER_SECRET_CONST\n"); seed1 = TLS_MD_EXTENDED_MASTER_SECRET_CONST; seed1_len = TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE; populateExtendedMasterSecret(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; } qat_prf(md, md_count, seed1, seed1_len, seed2, seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, seed5_len, secret, secSize, out, outlen); } return 1; } int QAT_TlsPrf_Ops(void *args, unsigned char *out, size_t outlen, const char *desc) { if (!(TlsPrf_Ops(args, out, outlen, desc))) DEBUG("error in TlsPrf_Ops\n"); return 1; } qatengine-1.9.0/qat_sw_ec.c000066400000000000000000002464701500416242000156140ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_ec.c * * This file provides multibuffer support for ECDH & ECDSA * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #ifdef QAT_BORINGSSL # include #endif /* QAT_BORINGSSL */ #include #include #include /* Local includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" #include "qat_evp.h" #include "qat_sw_ec.h" #include "qat_sw_request.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif /* Crypto_mb includes */ #include "crypto_mb/ec_nistp256.h" #include "crypto_mb/ec_nistp384.h" #include "crypto_mb/ec_sm2.h" # if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_ECDSA) extern int qat_fips_kat_test; static const unsigned char KINV_256[] = { 0x62, 0x15, 0x9E, 0x5B, 0xA9, 0xE7, 0x12, 0xFB, 0x09, 0x8C, 0xCE, 0x8F, 0xE2, 0x0F, 0x1B, 0xED, 0x83, 0x46, 0x55, 0x4E, 0x98, 0xEF, 0x3C, 0x7C, 0x1F, 0xC3, 0x33, 0x2B, 0xA6, 0x7D, 0x87, 0xEF }; static const unsigned char R_256[] = { 0x2B, 0x42, 0xF5, 0x76, 0xD0, 0x7F, 0x41, 0x65, 0xFF, 0x65, 0xD1, 0xF3, 0xB1, 0x50, 0x0F, 0x81, 0xE4, 0x4C, 0x31, 0x6F, 0x1F, 0x0B, 0x3E, 0xF5, 0x73, 0x25, 0xB6, 0x9A, 0xCA, 0x46, 0x10, 0x4F }; static const unsigned char KINV_384[] = { 0xAC, 0x22, 0x7D, 0xA5, 0x19, 0x29, 0x53, 0x3D, 0xFC, 0x2E, 0x9E, 0xEF, 0xB4, 0xE0, 0xF7, 0xBD, 0x22, 0x39, 0x2C, 0xA7, 0x32, 0x89, 0xED, 0x1C, 0x6C, 0x00, 0xB2, 0x14, 0xE8, 0x87, 0x4D, 0x80, 0x07, 0xC8, 0xAC, 0x46, 0xB2, 0x5D, 0x67, 0x7D, 0xFE, 0x9B, 0x1C, 0x6C, 0x10, 0xA4, 0x7E, 0x4A }; static const unsigned char R_384[] = { 0x30, 0xEA, 0x51, 0x4F, 0xC0, 0xD3, 0x8D, 0x82, 0x08, 0x75, 0x6F, 0x06, 0x81, 0x13, 0xC7, 0xCA, 0xDA, 0x9F, 0x66, 0xA3, 0xB4, 0x0E, 0xA3, 0xB3, 0x13, 0xD0, 0x40, 0xD9, 0xB5, 0x7D, 0xD4, 0x1A, 0x33, 0x27, 0x95, 0xD0, 0x2C, 0xC7, 0xD5, 0x07, 0xFC, 0xEF, 0x9F, 0xAF, 0x01, 0xA2, 0x70, 0x88 }; #endif static inline int mb_ec_check_curve(int curve_type) { int ret = 0; switch (curve_type) { case NID_X9_62_prime256v1: ret = EC_P256; break; case NID_secp384r1: ret = EC_P384; break; #ifndef QAT_BORINGSSL case NID_sm2: ret = EC_SM2; break; #endif /* QAT_BORINGSSL */ default: break; } return ret; } #ifdef ENABLE_QAT_SW_ECDSA void process_ecdsa_sign_reqs(mb_thread_data *tlv, int bit_len) { ecdsa_sign_op_data *ecdsa_sign_req_array[MULTIBUFF_BATCH] = {0}; unsigned char *sign_r[MULTIBUFF_BATCH] = {0}; unsigned char *sign_s[MULTIBUFF_BATCH] = {0};; const unsigned char *digest[MULTIBUFF_BATCH] = {0}; const BIGNUM *eph_key[MULTIBUFF_BATCH] = {0}; const BIGNUM *priv_key[MULTIBUFF_BATCH] = {0}; unsigned int sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdsa_cycles_sign_execute); /* Build Arrays of pointers for call */ switch (bit_len) { case EC_P256: DEBUG("Dequeue ECDSA p256 sign reqs.\n"); while ((ecdsa_sign_req_array[req_num] = mb_queue_ecdsap256_sign_dequeue(tlv->ecdsap256_sign_queue)) != NULL) { sign_r[req_num] = ecdsa_sign_req_array[req_num]->sign_r; sign_s[req_num] = ecdsa_sign_req_array[req_num]->sign_s; digest[req_num] = ecdsa_sign_req_array[req_num]->digest; eph_key[req_num] = ecdsa_sign_req_array[req_num]->eph_key; priv_key[req_num] = ecdsa_sign_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_P384: DEBUG("Dequeue ECDSA p384 sign reqs.\n"); while ((ecdsa_sign_req_array[req_num] = mb_queue_ecdsap384_sign_dequeue(tlv->ecdsap384_sign_queue)) != NULL) { sign_r[req_num] = ecdsa_sign_req_array[req_num]->sign_r; sign_s[req_num] = ecdsa_sign_req_array[req_num]->sign_s; digest[req_num] = ecdsa_sign_req_array[req_num]->digest; eph_key[req_num] = ecdsa_sign_req_array[req_num]->eph_key; priv_key[req_num] = ecdsa_sign_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; switch (bit_len) { case EC_P256: DEBUG("Submitting %d ECDSA p256 sign requests\n", local_request_no); sts = mbx_nistp256_ecdsa_sign_ssl_mb8(sign_r, sign_s, digest, eph_key, priv_key, NULL); break; case EC_P384: DEBUG("Submitting %d ECDSA p384 sign requests\n", local_request_no); num_ecdsa_sw_sign_reqs += local_request_no; sts = mbx_nistp384_ecdsa_sign_ssl_mb8(sign_r, sign_s, digest, eph_key, priv_key, NULL); break; } for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdsa_sign_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer ECDSA Sign request[%d] success\n", req_num); *ecdsa_sign_req_array[req_num]->sts = 1; } else { WARN("Multibuffer ECDSA Sign request[%d] failure - sts %d\n", req_num, MBX_GET_STS(sts, req_num)); *ecdsa_sign_req_array[req_num]->sts = 0; } } if (ecdsa_sign_req_array[req_num]->job) { #ifdef QAT_BORINGSSL bssl_mb_async_job_finish_wait(ecdsa_sign_req_array[req_num]->job, ASYNC_JOB_COMPLETE, ASYNC_STATUS_OK); #endif qat_wake_job(ecdsa_sign_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdsa_sign_req_array[req_num], sizeof(ecdsa_sign_op_data)); mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (bit_len) { case EC_P256: mb_ecdsap256_sign_req_rates.req_this_period += local_request_no; break; case EC_P384: mb_ecdsap384_sign_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&ecdsa_cycles_sign_execute, 1, "[ECDSA:sign_execute]"); DEBUG("Processed Final Request\n"); } void process_ecdsa_sign_setup_reqs(mb_thread_data *tlv, int bit_len) { ecdsa_sign_setup_op_data *ecdsa_sign_setup_req_array[MULTIBUFF_BATCH] = {0}; BIGNUM *k_inv[MULTIBUFF_BATCH] = {0}; BIGNUM *sig_rp[MULTIBUFF_BATCH] = {0}; const BIGNUM *eph_key[MULTIBUFF_BATCH] = {0}; unsigned int sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdsa_cycles_sign_setup_execute); /* Build Arrays of pointers for call */ switch (bit_len) { case EC_P256: DEBUG("Dequeue ECDSA p256 sign setup reqs.\n"); while ((ecdsa_sign_setup_req_array[req_num] = mb_queue_ecdsap256_sign_setup_dequeue(tlv->ecdsap256_sign_setup_queue)) != NULL) { k_inv[req_num] = ecdsa_sign_setup_req_array[req_num]->k_inv; sig_rp[req_num] = ecdsa_sign_setup_req_array[req_num]->sig_rp; eph_key[req_num] = ecdsa_sign_setup_req_array[req_num]->eph_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_P384: DEBUG("Dequeue ECDSA p384 sign setup reqs.\n"); while ((ecdsa_sign_setup_req_array[req_num] = mb_queue_ecdsap384_sign_setup_dequeue(tlv->ecdsap384_sign_setup_queue)) != NULL) { k_inv[req_num] = ecdsa_sign_setup_req_array[req_num]->k_inv; sig_rp[req_num] = ecdsa_sign_setup_req_array[req_num]->sig_rp; eph_key[req_num] = ecdsa_sign_setup_req_array[req_num]->eph_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; switch (bit_len) { case EC_P256: DEBUG("Submitting %d ECDSA p256 sign setup requests\n", local_request_no); sts = mbx_nistp256_ecdsa_sign_setup_ssl_mb8(k_inv, sig_rp, eph_key, NULL); break; case EC_P384: DEBUG("Submitting %d ECDSA p384 sign setup requests\n", local_request_no); sts = mbx_nistp384_ecdsa_sign_setup_ssl_mb8(k_inv, sig_rp, eph_key, NULL); break; } for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdsa_sign_setup_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer ECDSA Sign setup request[%d] success\n", req_num); *ecdsa_sign_setup_req_array[req_num]->sts = 1; } else { WARN("Multibuffer ECDSA Sign setup request[%d] failure - sts %d\n", req_num, MBX_GET_STS(sts, req_num)); *ecdsa_sign_setup_req_array[req_num]->sts = 0; } } if (ecdsa_sign_setup_req_array[req_num]->job) { qat_wake_job(ecdsa_sign_setup_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdsa_sign_setup_req_array[req_num], sizeof(ecdsa_sign_setup_op_data)); mb_flist_ecdsa_sign_setup_push(tlv->ecdsa_sign_setup_freelist, ecdsa_sign_setup_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (bit_len) { case EC_P256: mb_ecdsap256_sign_setup_req_rates.req_this_period += local_request_no; break; case EC_P384: mb_ecdsap384_sign_setup_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&ecdsa_cycles_sign_setup_execute, 1, "[ECDSA:sign_setup_execute]"); DEBUG("Processed Final Request\n"); } void process_ecdsa_sign_sig_reqs(mb_thread_data *tlv, int bit_len) { ecdsa_sign_sig_op_data *ecdsa_sign_sig_req_array[MULTIBUFF_BATCH] = {0}; unsigned char *sign_r[MULTIBUFF_BATCH] = {0}; unsigned char *sign_s[MULTIBUFF_BATCH] = {0};; const unsigned char *digest[MULTIBUFF_BATCH] = {0}; const BIGNUM *k_inv[MULTIBUFF_BATCH] = {0}; const BIGNUM *sig_rp[MULTIBUFF_BATCH] = {0}; const BIGNUM *priv_key[MULTIBUFF_BATCH] = {0}; unsigned int sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdsa_cycles_sign_sig_execute); /* Build Arrays of pointers for call */ switch (bit_len) { case EC_P256: DEBUG("Dequeue ECDSA p256 sign sig reqs.\n"); while ((ecdsa_sign_sig_req_array[req_num] = mb_queue_ecdsap256_sign_sig_dequeue(tlv->ecdsap256_sign_sig_queue)) != NULL) { sign_r[req_num] = ecdsa_sign_sig_req_array[req_num]->sign_r; sign_s[req_num] = ecdsa_sign_sig_req_array[req_num]->sign_s; digest[req_num] = ecdsa_sign_sig_req_array[req_num]->digest; sig_rp[req_num] = ecdsa_sign_sig_req_array[req_num]->sig_rp; k_inv[req_num] = ecdsa_sign_sig_req_array[req_num]->k_inv; priv_key[req_num] = ecdsa_sign_sig_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_P384: DEBUG("Dequeue ECDSA p384 sign sig reqs.\n"); while ((ecdsa_sign_sig_req_array[req_num] = mb_queue_ecdsap384_sign_sig_dequeue(tlv->ecdsap384_sign_sig_queue)) != NULL) { sign_r[req_num] = ecdsa_sign_sig_req_array[req_num]->sign_r; sign_s[req_num] = ecdsa_sign_sig_req_array[req_num]->sign_s; digest[req_num] = ecdsa_sign_sig_req_array[req_num]->digest; sig_rp[req_num] = ecdsa_sign_sig_req_array[req_num]->sig_rp; k_inv[req_num] = ecdsa_sign_sig_req_array[req_num]->k_inv; priv_key[req_num] = ecdsa_sign_sig_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; switch (bit_len) { case EC_P256: DEBUG("Submitting %d ECDSA p256 sign sig requests\n", local_request_no); sts = mbx_nistp256_ecdsa_sign_complete_ssl_mb8(sign_r, sign_s, digest, sig_rp, k_inv, priv_key, NULL); break; case EC_P384: DEBUG("Submitting %d ECDSA p384 sign sig requests\n", local_request_no); sts = mbx_nistp384_ecdsa_sign_complete_ssl_mb8(sign_r, sign_s, digest, sig_rp, k_inv, priv_key, NULL); break; } for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdsa_sign_sig_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer ECDSA Sign sig request[%d] success\n", req_num); *ecdsa_sign_sig_req_array[req_num]->sts = 1; } else { WARN("Multibuffer ECDSA Sign sig request[%d] failure - sts %d\n", req_num, MBX_GET_STS(sts, req_num)); *ecdsa_sign_sig_req_array[req_num]->sts = 0; } } if (ecdsa_sign_sig_req_array[req_num]->job) { qat_wake_job(ecdsa_sign_sig_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdsa_sign_sig_req_array[req_num], sizeof(ecdsa_sign_sig_op_data)); mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_ecdsap256_sign_sig_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&ecdsa_cycles_sign_sig_execute, 1, "[ECDSA:sign_sig_execute]"); DEBUG("Processed Final Request\n"); } void process_ecdsa_verify_reqs(mb_thread_data *tlv, int bit_len) { ecdsa_verify_op_data *ecdsa_verify_req_array[MULTIBUFF_BATCH] = {0}; const int8u* digest[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_verify_x[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_verify_y[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_verify_z[MULTIBUFF_BATCH] = {0}; const ECDSA_SIG *sig[MULTIBUFF_BATCH] = {0}; int sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdsa_cycles_verify_execute); /* Build Arrays of pointers for call */ switch (bit_len) { case EC_P256: DEBUG("Dequeue ECDSA p256 verify reqs.\n"); while ((ecdsa_verify_req_array[req_num] = mb_queue_ecdsap256_verify_dequeue(tlv->ecdsap256_verify_queue)) != NULL) { ecdsa_verify_x[req_num] = ecdsa_verify_req_array[req_num]->x; ecdsa_verify_y[req_num] = ecdsa_verify_req_array[req_num]->y; ecdsa_verify_z[req_num] = ecdsa_verify_req_array[req_num]->z; digest[req_num] = ecdsa_verify_req_array[req_num]->digest; sig[req_num] = ecdsa_verify_req_array[req_num]->s; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_P384: DEBUG("Dequeue ECDSA p384 verify reqs.\n"); while ((ecdsa_verify_req_array[req_num] = mb_queue_ecdsap384_verify_dequeue(tlv->ecdsap384_verify_queue)) != NULL) { ecdsa_verify_x[req_num] = ecdsa_verify_req_array[req_num]->x; ecdsa_verify_y[req_num] = ecdsa_verify_req_array[req_num]->y; ecdsa_verify_z[req_num] = ecdsa_verify_req_array[req_num]->z; digest[req_num] = ecdsa_verify_req_array[req_num]->digest; sig[req_num] = ecdsa_verify_req_array[req_num]->s; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; switch (bit_len) { case EC_P256: DEBUG("Submitting %d ECDSA p256 verify requests\n", local_request_no); sts = mbx_nistp256_ecdsa_verify_ssl_mb8(sig, digest, ecdsa_verify_x, ecdsa_verify_y, ecdsa_verify_z, NULL); break; case EC_P384: DEBUG("Submitting %d ECDSA p384 verify requests\n", local_request_no); sts = mbx_nistp384_ecdsa_verify_ssl_mb8(sig, digest, ecdsa_verify_x, ecdsa_verify_y, ecdsa_verify_z, NULL); break; } for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdsa_verify_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer ECDSA Verify request[%d] success\n", req_num); *ecdsa_verify_req_array[req_num]->sts = 1; } else { WARN("Multibuffer ECDSA Verify request[%d] failure - sts %d\n", req_num, MBX_GET_STS(sts, req_num)); *ecdsa_verify_req_array[req_num]->sts = 0; } } if (ecdsa_verify_req_array[req_num]->job) { qat_wake_job(ecdsa_verify_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdsa_verify_req_array[req_num], sizeof(ecdsa_verify_op_data)); mb_flist_ecdsa_verify_push(tlv->ecdsa_verify_freelist, ecdsa_verify_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (bit_len) { case EC_P256: mb_ecdsap256_verify_req_rates.req_this_period += local_request_no; break; case EC_P384: mb_ecdsap384_verify_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&ecdsa_cycles_verify_execute, 1, "[ECDSA:verify_execute]"); DEBUG("Processed Final Request\n"); } #endif #ifdef ENABLE_QAT_SW_ECDH void process_ecdh_keygen_reqs(mb_thread_data *tlv, int curve) { ecdh_keygen_op_data *ecdh_keygen_req_array[MULTIBUFF_BATCH] = {0}; BIGNUM *ecdh_keygen_x[MULTIBUFF_BATCH] = {0}; BIGNUM *ecdh_keygen_y[MULTIBUFF_BATCH] = {0}; BIGNUM *ecdh_keygen_z[MULTIBUFF_BATCH] = {0}; const BIGNUM* ecdh_keygen_privkey[MULTIBUFF_BATCH] = {0}; unsigned int ecdh_sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdh_cycles_keygen_execute); /* Build Arrays of pointers for call */ switch (curve) { case EC_P256: DEBUG("Dequeue ECDHP256 keygen reqs.\n"); while ((ecdh_keygen_req_array[req_num] = mb_queue_ecdhp256_keygen_dequeue(tlv->ecdhp256_keygen_queue)) != NULL) { ecdh_keygen_x[req_num] = ecdh_keygen_req_array[req_num]->x; ecdh_keygen_y[req_num] = ecdh_keygen_req_array[req_num]->y; ecdh_keygen_z[req_num] = ecdh_keygen_req_array[req_num]->z; ecdh_keygen_privkey[req_num] = ecdh_keygen_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_P384: DEBUG("Dequeue ECDHP384 keygen reqs.\n"); while ((ecdh_keygen_req_array[req_num] = mb_queue_ecdhp384_keygen_dequeue(tlv->ecdhp384_keygen_queue)) != NULL) { ecdh_keygen_x[req_num] = ecdh_keygen_req_array[req_num]->x; ecdh_keygen_y[req_num] = ecdh_keygen_req_array[req_num]->y; ecdh_keygen_z[req_num] = ecdh_keygen_req_array[req_num]->z; ecdh_keygen_privkey[req_num] = ecdh_keygen_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_SM2: DEBUG("Dequeue SM2ECDH keygen reqs.\n"); while ((ecdh_keygen_req_array[req_num] = mb_queue_sm2ecdh_keygen_dequeue(tlv->sm2ecdh_keygen_queue)) != NULL) { ecdh_keygen_x[req_num] = ecdh_keygen_req_array[req_num]->x; ecdh_keygen_y[req_num] = ecdh_keygen_req_array[req_num]->y; ecdh_keygen_z[req_num] = ecdh_keygen_req_array[req_num]->z; ecdh_keygen_privkey[req_num] = ecdh_keygen_req_array[req_num]->priv_key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; switch (curve) { case EC_P256: DEBUG("Submitting %d ECDH p256 Keygen requests\n", local_request_no); num_ecdh_sw_keygen_reqs += local_request_no; ecdh_sts = mbx_nistp256_ecpublic_key_ssl_mb8(ecdh_keygen_x, ecdh_keygen_y, ecdh_keygen_z, ecdh_keygen_privkey, NULL); break; case EC_P384: DEBUG("Submitting %d ECDH p384 Keygen requests\n", local_request_no); num_ecdh_sw_keygen_reqs += local_request_no; ecdh_sts = mbx_nistp384_ecpublic_key_ssl_mb8(ecdh_keygen_x, ecdh_keygen_y, ecdh_keygen_z, ecdh_keygen_privkey, NULL); break; case EC_SM2: DEBUG("Submitting %d ECDH sm2 Keygen requests\n", local_request_no); ecdh_sts = mbx_sm2_ecpublic_key_ssl_mb8(ecdh_keygen_x, ecdh_keygen_y, ecdh_keygen_z, ecdh_keygen_privkey, NULL); break; } for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdh_keygen_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(ecdh_sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer keygen request[%d] success\n", req_num); *ecdh_keygen_req_array[req_num]->sts = 1; } else { WARN("Multibuffer keygen request[%d] failure, sts %d \n", req_num, MBX_GET_STS(ecdh_sts, req_num)); *ecdh_keygen_req_array[req_num]->sts = 0; } } if (ecdh_keygen_req_array[req_num]->job) { qat_wake_job(ecdh_keygen_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdh_keygen_req_array[req_num], sizeof(ecdh_keygen_op_data)); mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (curve) { case EC_P256: mb_ecdhp256_keygen_req_rates.req_this_period += local_request_no; break; case EC_P384: mb_ecdhp384_keygen_req_rates.req_this_period += local_request_no; break; case EC_SM2: mb_sm2ecdh_keygen_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&ecdh_cycles_keygen_execute, 1, "[ECDH:keygen_execute]"); DEBUG("Processed Final Request\n"); } void process_ecdh_compute_reqs(mb_thread_data *tlv, int curve) { ecdh_compute_op_data *ecdh_compute_req_array[MULTIBUFF_BATCH] = {0}; unsigned char *ecdh_compute_shared_key[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdh_compute_privkey[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdh_compute_x[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdh_compute_y[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdh_compute_z[MULTIBUFF_BATCH] = {0}; unsigned int ecdh_sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdh_cycles_compute_execute); /* Build Arrays of pointers for call */ switch (curve) { case EC_P256: DEBUG("Dequeue ECDHP256 compute reqs.\n"); while ((ecdh_compute_req_array[req_num] = mb_queue_ecdhp256_compute_dequeue(tlv->ecdhp256_compute_queue)) != NULL) { ecdh_compute_shared_key[req_num] = ecdh_compute_req_array[req_num]->shared_key; ecdh_compute_privkey[req_num] = ecdh_compute_req_array[req_num]->priv_key; ecdh_compute_x[req_num] = ecdh_compute_req_array[req_num]->x; ecdh_compute_y[req_num] = ecdh_compute_req_array[req_num]->y; ecdh_compute_z[req_num] = ecdh_compute_req_array[req_num]->z; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_P384: DEBUG("Dequeue ECDHP384 compute reqs.\n"); while ((ecdh_compute_req_array[req_num] = mb_queue_ecdhp384_compute_dequeue(tlv->ecdhp384_compute_queue)) != NULL) { ecdh_compute_shared_key[req_num] = ecdh_compute_req_array[req_num]->shared_key; ecdh_compute_privkey[req_num] = ecdh_compute_req_array[req_num]->priv_key; ecdh_compute_x[req_num] = ecdh_compute_req_array[req_num]->x; ecdh_compute_y[req_num] = ecdh_compute_req_array[req_num]->y; ecdh_compute_z[req_num] = ecdh_compute_req_array[req_num]->z; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case EC_SM2: DEBUG("Dequeue SM2ECDH compute reqs.\n"); while ((ecdh_compute_req_array[req_num] = mb_queue_sm2ecdh_compute_dequeue(tlv->sm2ecdh_compute_queue)) != NULL) { ecdh_compute_shared_key[req_num] = ecdh_compute_req_array[req_num]->shared_key; ecdh_compute_privkey[req_num] = ecdh_compute_req_array[req_num]->priv_key; ecdh_compute_x[req_num] = ecdh_compute_req_array[req_num]->x; ecdh_compute_y[req_num] = ecdh_compute_req_array[req_num]->y; ecdh_compute_z[req_num] = ecdh_compute_req_array[req_num]->z; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; switch (curve) { case EC_P256: DEBUG("Submitting %d ECDH p256 Compute requests\n", local_request_no); num_ecdh_sw_derive_reqs += local_request_no; ecdh_sts = mbx_nistp256_ecdh_ssl_mb8(ecdh_compute_shared_key, ecdh_compute_privkey, ecdh_compute_x, ecdh_compute_y, ecdh_compute_z, /* Use Jacobian coordinates */ NULL); break; case EC_P384: DEBUG("Submitting %d ECDH p384 Compute requests\n", local_request_no); num_ecdh_sw_derive_reqs += local_request_no; ecdh_sts = mbx_nistp384_ecdh_ssl_mb8(ecdh_compute_shared_key, ecdh_compute_privkey, ecdh_compute_x, ecdh_compute_y, ecdh_compute_z, /* Use Jacobian coordinates */ NULL); break; case EC_SM2: DEBUG("Submitting %d SM2 ECDH Compute requests\n", local_request_no); ecdh_sts = mbx_sm2_ecdh_ssl_mb8(ecdh_compute_shared_key, ecdh_compute_privkey, ecdh_compute_x, ecdh_compute_y, ecdh_compute_z, /* Use Jacobian coordinates */ NULL); break; } for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdh_compute_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(ecdh_sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer compute request[%d] success\n", req_num); *ecdh_compute_req_array[req_num]->sts = 1; } else { WARN("Multibuffer compute request[%d] failure, sts %d \n", req_num, MBX_GET_STS(ecdh_sts, req_num)); *ecdh_compute_req_array[req_num]->sts = 0; } } if (ecdh_compute_req_array[req_num]->job) { qat_wake_job(ecdh_compute_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdh_compute_req_array[req_num], sizeof(ecdh_compute_op_data)); mb_flist_ecdh_compute_push(tlv->ecdh_compute_freelist, ecdh_compute_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (curve) { case EC_P256: mb_ecdhp256_compute_req_rates.req_this_period += local_request_no; break; case EC_P384: mb_ecdhp384_compute_req_rates.req_this_period += local_request_no; break; case EC_SM2: mb_sm2ecdh_compute_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&ecdh_cycles_compute_execute, 1, "[ECDH:compute_execute]"); DEBUG("Processed Final Request\n"); } #endif #ifdef ENABLE_QAT_SW_ECDSA #ifdef QAT_BORINGSSL typedef struct _mb_ecdsa_async_ctx { mb_async_ctx async_ctx; BN_CTX *ctx; ECDSA_SIG *s; unsigned char *sig; unsigned char *dgst; int dlen; BIGNUM *ecdsa_sig_r; BIGNUM *ecdsa_sig_s; size_t buflen; int sts; } mb_ecdsa_async_ctx; static void mb_ecdsa_sign_callback_fn(void *async_ctx, unsigned char *out_buffer, unsigned long *size, unsigned long max_size) { mb_ecdsa_async_ctx *ecdsa_async_ctx = (mb_ecdsa_async_ctx *)async_ctx; if (async_ctx == NULL || out_buffer == NULL || size == NULL || max_size <= 0) { return; } if (ecdsa_async_ctx->sts) { /* Convert the buffers to BN */ BN_bin2bn(ecdsa_async_ctx->sig, ecdsa_async_ctx->buflen, ecdsa_async_ctx->ecdsa_sig_r); BN_bin2bn(ecdsa_async_ctx->sig + ecdsa_async_ctx->buflen, ecdsa_async_ctx->buflen, ecdsa_async_ctx->ecdsa_sig_s); *size = i2d_ECDSA_SIG(ecdsa_async_ctx->s, &(out_buffer)); ECDSA_SIG_free(ecdsa_async_ctx->s); } else { *size = 0; WARN("Failure in ECDSA Sign\n"); ECDSA_SIG_free(ecdsa_async_ctx->s); } if (ecdsa_async_ctx->ctx) { BN_CTX_end(ecdsa_async_ctx->ctx); BN_CTX_free(ecdsa_async_ctx->ctx); } OPENSSL_free(ecdsa_async_ctx->dgst); OPENSSL_free(ecdsa_async_ctx->sig); OPENSSL_free(ecdsa_async_ctx); } #endif /* QAT_BORINGSSL */ int mb_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) { int ret = 0, len = 0, job_ret = 0, sts = 0, alloc_buf = 0, bit_len = 0; BN_CTX *ctx = NULL; ECDSA_SIG *s; ASYNC_JOB *job; size_t buflen; static __thread int req_num = 0; const EC_GROUP *group; BIGNUM *k = NULL; const BIGNUM *priv_key, *order; const EC_POINT *pub_key = NULL; BIGNUM *ecdsa_sig_r = NULL, *ecdsa_sig_s = NULL; unsigned char *dgst_buf = NULL; #ifndef QAT_BORINGSSL PFUNC_SIGN sign_pfunc = NULL; #endif /* QAT_BORINGSSL */ ecdsa_sign_op_data *ecdsa_sign_req = NULL; mb_thread_data *tlv = NULL; #ifdef QAT_BORINGSSL ASYNC_WAIT_CTX *waitctx = NULL; mb_ecdsa_async_ctx *ecdsa_async_ctx = NULL; int alloc_sig = 0; #endif /* QAT_BORINGSSL */ DEBUG("Entering \n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(dgst == NULL || dlen <= 0 || eckey == NULL)) { *siglen = 0; WARN("Invalid Input param\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_INPUT_PARAM_INVALID); return ret; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || priv_key == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return ret; } /* Check if curve is p256 or p384 */ if ((bit_len = mb_ec_check_curve(EC_GROUP_get_curve_name(group))) == 0) { DEBUG("Curve type not supported, using SW Method %d\n", EC_GROUP_get_curve_name(group)); #ifdef ENABLE_QAT_FIPS return ret; #else goto use_sw_method; #endif } #ifdef ENABLE_QAT_FIPS if (qat_fips_kat_test == 1) { if (bit_len == EC_P256) { if ((kinv = BN_bin2bn(KINV_256, sizeof(KINV_256), NULL)) == 0) return ret; if ((r = BN_bin2bn(R_256, sizeof(R_256), NULL)) == 0) return ret; } else { if ((kinv = BN_bin2bn(KINV_384, sizeof(KINV_384), NULL)) == 0) return ret; if ((r = BN_bin2bn(R_384, sizeof(R_384), NULL)) == 0) return ret; } } #endif /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return ret; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif if (!EC_KEY_can_sign(eckey)) { WARN("Curve doesn't support Signing\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return ret; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return ret; #else goto use_sw_method; #endif } while ((ecdsa_sign_req = mb_flist_ecdsa_sign_pop(tlv->ecdsa_sign_freelist)) == NULL) { #ifndef QAT_BORINGSSL # ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); # else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } # endif #else /* QAT_BORINGSSL */ goto use_sw_method; #endif /* QAT_BORINGSSL */ } DEBUG("QAT SW ECDSA Started %p\n", ecdsa_sign_req); START_RDTSC(&ecdsa_cycles_sign_setup); /* Buffer up the requests and call the new functions when we have enough * requests buffered up */ if ((s = ECDSA_SIG_new()) == NULL) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate ECDSA_SIG\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_SIG_MALLOC_FAILURE); return ret; } ecdsa_sig_r = BN_new(); ecdsa_sig_s = BN_new(); /* NULL checking of ecdsa_sig_r & ecdsa_sig_s done in ECDSA_SIG_set0() */ if (ECDSA_SIG_set0(s, ecdsa_sig_r, ecdsa_sig_s) == 0) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate r and s values to assign to the ECDSA_SIG\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_SIG_SET_R_S_FAILURE); goto err; } if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); k = BN_CTX_get(ctx); if ((order = EC_GROUP_get0_order(group)) == NULL) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to get order from group\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_GET_ORDER_FAILURE); goto err; } len = BN_num_bits(order); buflen = (len + 7) / 8; /* If digest size is less, expand length with zero as crypto_mb * expects digest being sign length */ if (8 * dlen < len) { dgst_buf = OPENSSL_zalloc(buflen); if (dgst_buf == NULL) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate dgst_buf\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } alloc_buf = 1; memcpy(dgst_buf + buflen - dlen, dgst, dlen); } else { dgst_buf = (unsigned char *)dgst; } if (kinv == NULL || r == NULL) { /* Get random k */ do { #ifndef QAT_BORINGSSL if (!BN_priv_rand_range(k, order)) { #else /* QAT_BORINGSSL */ if (!BN_rand_range(k, order)) { #endif /* QAT_BORINGSSL */ mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure in BN_priv_rand_range\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_RAND_GENERATE_FAILURE); goto err; } } while (BN_is_zero(k)); } else { BN_mod_inverse(k, kinv, order, ctx); DEBUG("Not Generating Random K\n"); } #ifdef QAT_BORINGSSL waitctx = ASYNC_get_wait_ctx(job); if (!waitctx) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("waitctx == NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_CTX_NULL); goto err; } sig = OPENSSL_zalloc(ECDSA_size(eckey)); if (!sig) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate sig buf\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } alloc_sig = 1; if (!alloc_buf) { dgst_buf = OPENSSL_zalloc(dlen); if (!dgst_buf) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate dgst buf\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } alloc_buf = 1; memcpy(dgst_buf, dgst, dlen); } ecdsa_async_ctx = OPENSSL_zalloc(sizeof(mb_ecdsa_async_ctx)); if (!ecdsa_async_ctx) { mb_flist_ecdsa_sign_push(tlv->ecdsa_sign_freelist, ecdsa_sign_req); WARN("Failure to allocate ecdsa_async_ctx\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } ecdsa_async_ctx->async_ctx.callback_func = mb_ecdsa_sign_callback_fn; ecdsa_async_ctx->async_ctx.ctx = ecdsa_async_ctx; ecdsa_async_ctx->dgst = dgst_buf; ecdsa_async_ctx->dlen = dlen; ecdsa_async_ctx->ctx = ctx; ecdsa_async_ctx->s = s; ecdsa_async_ctx->sig = sig; ecdsa_async_ctx->ecdsa_sig_r = ecdsa_sig_r; ecdsa_async_ctx->ecdsa_sig_s = ecdsa_sig_s; ecdsa_async_ctx->buflen = buflen; ecdsa_sign_req->sts = &(ecdsa_async_ctx->sts); waitctx->data = &(ecdsa_async_ctx->async_ctx); #else /* QAT_BORINGSSL */ ecdsa_sign_req->sts = &sts; #endif/* QAT_BORINGSSL */ ecdsa_sign_req->sign_r = sig; ecdsa_sign_req->sign_s = sig + buflen; ecdsa_sign_req->digest = dgst_buf; ecdsa_sign_req->eph_key = k; ecdsa_sign_req->priv_key = priv_key; ecdsa_sign_req->job = job; switch (bit_len) { case EC_P256: mb_queue_ecdsap256_sign_enqueue(tlv->ecdsap256_sign_queue, ecdsa_sign_req); break; case EC_P384: mb_queue_ecdsap384_sign_enqueue(tlv->ecdsap384_sign_queue, ecdsa_sign_req); break; } STOP_RDTSC(&ecdsa_cycles_sign_setup, 1, "[ECDSA:sign_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_ecdsa_sign_reqs(tlv, bit_len); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } #ifdef QAT_BORINGSSL if (job) { job->tlv_destructor(NULL); return -1; } #endif DEBUG("Pausing: %p status = %d\n", ecdsa_sign_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdsa_sign_req, sts); #ifdef ENABLE_QAT_FIPS } #endif if (sts) { /* Convert the buffers to BN */ BN_bin2bn(sig, buflen, ecdsa_sig_r); BN_bin2bn(sig + buflen, buflen, ecdsa_sig_s); *siglen = i2d_ECDSA_SIG(s, &sig); DEBUG("siglen %d, dlen %d\n", *siglen, dlen); ECDSA_SIG_free(s); ret = 1; } else { WARN("Failure in ECDSA Sign\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_ECDSA_SIGN_FAILURE); goto err; } err: if (!ret) { ECDSA_SIG_free(s); if (siglen != NULL) *siglen = 0; } if (alloc_buf) OPENSSL_free(dgst_buf); if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } #ifdef QAT_BORINGSSL if (alloc_sig) { OPENSSL_free(sig); } if (ecdsa_async_ctx) { OPENSSL_free(ecdsa_async_ctx); } #endif /* QAT_BORINGSSL */ return ret; use_sw_method: # ifndef QAT_BORINGSSL EC_KEY_METHOD_get_sign((EC_KEY_METHOD *) EC_KEY_OpenSSL(), &sign_pfunc, NULL, NULL); if (sign_pfunc == NULL) { WARN("sign_pfunc is NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN, QAT_R_SW_GET_SIGN_PFUNC_NULL); return ret; } return (*sign_pfunc)(type, dgst, dlen, sig, siglen, kinv, r, eckey); # else /* QAT_BORINGSSL */ ret = bssl_ecdsa_sign(dgst, dlen, sig, siglen, eckey); if ((job = ASYNC_get_current_job())) { job->tlv_destructor(NULL); waitctx = ASYNC_get_wait_ctx(job); if (waitctx && siglen && ret == 1) { waitctx->data = (void *)(long long)(*siglen); bssl_mb_async_job_finish_wait(job, ASYNC_JOB_OPER_COMPLETE, ASYNC_STATUS_OK); } else { bssl_mb_async_job_finish_wait(job, ASYNC_JOB_STOPPED, ASYNC_STATUS_OK); } } return ret; # endif /* QAT_BORINGSSL */ } #ifndef QAT_BORINGSSL int mb_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { int ret = 0, job_ret = 0, sts = 0, bit_len = 0; const EC_GROUP *group; const BIGNUM *priv_key; ASYNC_JOB *job; static __thread int req_num = 0; BIGNUM *k = NULL, *r = NULL; PFUNC_SIGN_SETUP sign_setup_pfunc = NULL; ecdsa_sign_setup_op_data *ecdsa_sign_setup_req = NULL; mb_thread_data *tlv = NULL; DEBUG("Entering\n" ); if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (priv_key = EC_KEY_get0_private_key(eckey)) == NULL) { WARN("eckey, group or priv_key is NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SETUP, QAT_R_EC_KEY_GROUP_PRIV_KEY_NULL); return 0; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if curve is p256 or p384 */ if ((bit_len = mb_ec_check_curve(EC_GROUP_get_curve_name(group))) == 0) { DEBUG("Curve type not supported, using SW Method %d\n", EC_GROUP_get_curve_name(group)); goto use_sw_method; } /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } if (!EC_KEY_can_sign(eckey)) { WARN("Curve doesn't support Signing\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SETUP, QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return ret; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((ecdsa_sign_setup_req = mb_flist_ecdsa_sign_setup_pop(tlv->ecdsa_sign_setup_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW ECDSA Started %p\n", ecdsa_sign_setup_req); START_RDTSC(&ecdsa_cycles_sign_setup_setup); /* Buffer up the requests and call the new functions when we have enough * requests buffered up */ k = BN_new(); r = BN_new(); if (k == NULL || r == NULL) { mb_flist_ecdsa_sign_setup_push(tlv->ecdsa_sign_setup_freelist, ecdsa_sign_setup_req); WARN("Failure to allocate k or r\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SETUP, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } ecdsa_sign_setup_req->k_inv = k; ecdsa_sign_setup_req->sig_rp = r; ecdsa_sign_setup_req->eph_key = priv_key; ecdsa_sign_setup_req->job = job; ecdsa_sign_setup_req->sts = &sts; switch (bit_len) { case EC_P256: mb_queue_ecdsap256_sign_setup_enqueue(tlv->ecdsap256_sign_setup_queue, ecdsa_sign_setup_req); break; case EC_P384: mb_queue_ecdsap384_sign_setup_enqueue(tlv->ecdsap384_sign_setup_queue, ecdsa_sign_setup_req); break; } STOP_RDTSC(&ecdsa_cycles_sign_setup_setup, 1, "[ECDSA:sign_setup_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdsa_sign_setup_req, sts); do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdsa_sign_setup_req, sts); /* Clear old values */ BN_clear_free(*rp); BN_clear_free(*kinvp); if (sts) { /* Save the pre-computed values */ *rp = r; *kinvp = k; ret = 1; } else { WARN("Failure in ECDSA Sign\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SETUP, QAT_R_ECDSA_SIGN_FAILURE); goto err; } return ret; err: if (!ret) { BN_clear_free(k); BN_clear_free(r); } return ret; use_sw_method: EC_KEY_METHOD_get_sign((EC_KEY_METHOD *) EC_KEY_OpenSSL(), NULL, &sign_setup_pfunc, NULL); if (sign_setup_pfunc == NULL) { WARN("sign_setup_pfunc is NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SETUP, QAT_R_SW_GET_SIGN_SETUP_PFUNC_NULL); return ret; } return (*sign_setup_pfunc)(eckey, ctx_in, kinvp, rp); } ECDSA_SIG *mb_ecdsa_sign_sig(const unsigned char *dgst, int dlen, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) { int ok = 0, len = 0, job_ret = 0, sts = 0, alloc_buf = 0, bit_len = 0; BN_CTX *ctx = NULL; ECDSA_SIG *ret; ASYNC_JOB *job; size_t buflen; static __thread int req_num = 0; const EC_GROUP *group; const BIGNUM *priv_key, *order; const EC_POINT *pub_key = NULL; unsigned char *sig_buf = NULL, *dgst_buf = NULL; BIGNUM *ecdsa_sig_r = NULL, *ecdsa_sig_s = NULL; BIGNUM *kinv = NULL, *rp = NULL; PFUNC_SIGN_SIG sign_sig_pfunc = NULL; ecdsa_sign_sig_op_data *ecdsa_sign_sig_req = NULL; mb_thread_data *tlv = NULL; DEBUG("Entering\n" ); if (unlikely(dgst == NULL || dlen <= 0 || eckey == NULL)) { WARN("Invalid Input param\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_INPUT_PARAM_INVALID); return NULL; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || priv_key == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return NULL; } /* Check if curve is p256 or p384 */ if ((bit_len = mb_ec_check_curve(EC_GROUP_get_curve_name(group))) == 0) { DEBUG("Curve type not supported, using SW Method %d\n", EC_GROUP_get_curve_name(group)); goto use_sw_method; } /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } if (!EC_KEY_can_sign(eckey)) { WARN("Curve doesn't support Signing\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return NULL; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((ecdsa_sign_sig_req = mb_flist_ecdsa_sign_sig_pop(tlv->ecdsa_sign_sig_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW ECDSA Started %p\n", ecdsa_sign_sig_req); START_RDTSC(&ecdsa_cycles_sign_sig_setup); /* Buffer up the requests and call the new functions when we have enough * requests buffered up */ ret = ECDSA_SIG_new(); if (ret == NULL) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure to allocate sig\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_MALLOC_FAILURE); return NULL; } ecdsa_sig_r = BN_new(); ecdsa_sig_s = BN_new(); /* NULL checking of ecdsa_sig_r & ecdsa_sig_s done in ECDSA_SIG_set0() */ if (ECDSA_SIG_set0(ret, ecdsa_sig_r, ecdsa_sig_s) == 0) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure to allocate r and s values to assign to the ECDSA_SIG\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_ECDSA_SIG_SET_R_S_FAILURE); goto err; } if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); if ((order = EC_GROUP_get0_order(group)) == NULL) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure to get order from group\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_GET_ORDER_FAILURE); goto err; } len = BN_num_bits(order); buflen = (len + 7) / 8; /* If digest size is less, expand length with zero as crypto_mb * expects digest being sign length */ if (8 * dlen < len) { dgst_buf = OPENSSL_zalloc(buflen); if (dgst_buf == NULL) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure to allocate dgst_buf\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } alloc_buf = 1; memcpy(dgst_buf + buflen - dlen, dgst, dlen); } else { dgst_buf = (unsigned char *)dgst; } if (in_kinv == NULL || in_r == NULL) { if (!ECDSA_sign_setup(eckey, ctx, &kinv, &rp)) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure in sign setup\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_ECDSA_SIGN_SETUP_FAILURE); goto err; } in_kinv = kinv; in_r = rp; } sig_buf = OPENSSL_malloc(buflen + buflen); if (sig_buf == NULL) { mb_flist_ecdsa_sign_sig_push(tlv->ecdsa_sign_sig_freelist, ecdsa_sign_sig_req); WARN("Failure to allocate sig_buf\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } ecdsa_sign_sig_req->sign_r = sig_buf; ecdsa_sign_sig_req->sign_s = sig_buf + buflen; ecdsa_sign_sig_req->digest = dgst_buf; ecdsa_sign_sig_req->sig_rp = in_r; ecdsa_sign_sig_req->k_inv = in_kinv; ecdsa_sign_sig_req->priv_key = priv_key; ecdsa_sign_sig_req->job = job; ecdsa_sign_sig_req->sts = &sts; switch (bit_len) { case EC_P256: mb_queue_ecdsap256_sign_sig_enqueue(tlv->ecdsap256_sign_sig_queue, ecdsa_sign_sig_req); break; case EC_P384: mb_queue_ecdsap384_sign_sig_enqueue(tlv->ecdsap384_sign_sig_queue, ecdsa_sign_sig_req); break; } STOP_RDTSC(&ecdsa_cycles_sign_sig_setup, 1, "[ECDSA:sign_sig_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdsa_sign_sig_req, sts); do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdsa_sign_sig_req, sts); /* Convert the buffers to BN */ BN_bin2bn(sig_buf, buflen, ecdsa_sig_r); BN_bin2bn(sig_buf + buflen, buflen, ecdsa_sig_s); ok = 1; err: if (!ok) { ECDSA_SIG_free(ret); ret = NULL; } if (sig_buf) OPENSSL_free(sig_buf); if (alloc_buf) OPENSSL_free(dgst_buf); if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ret; use_sw_method: EC_KEY_METHOD_get_sign((EC_KEY_METHOD *) EC_KEY_OpenSSL(), NULL, NULL, &sign_sig_pfunc); if (sign_sig_pfunc == NULL) { WARN("sign_sig_pfunc is NULL\n"); QATerr(QAT_F_MB_ECDSA_SIGN_SIG, QAT_R_SW_GET_SIGN_SIG_PFUNC_NULL); return NULL; } return (*sign_sig_pfunc)(dgst, dlen, in_kinv, in_r, eckey); } #else /* QAT_BORINGSSL */ int mb_ecdsa_sign_bssl(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey) { int type = 0; const EC_GROUP *ecgroup = NULL; if (eckey && (ecgroup = EC_KEY_get0_group(eckey))) { type = EC_GROUP_get_curve_name(ecgroup); } return mb_ecdsa_sign(type, digest, digest_len, sig, sig_len, NULL, NULL, eckey); } #endif /* QAT_BORINGSSL */ #endif #ifdef ENABLE_QAT_SW_ECDSA # ifndef QAT_BORINGSSL int mb_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) { ECDSA_SIG *s; const unsigned char *p = sigbuf; unsigned char *der = NULL; int derlen = -1; int ret = -1; ASYNC_JOB *job; PFUNC_VERIFY verify_pfunc = NULL; /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return ret; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif if ((s = ECDSA_SIG_new()) == NULL) { WARN("Failure to allocate ECDSA_SIG\n"); return ret; } if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) { WARN("Failure to get ECDSA_SIG\n"); goto err; } /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_ECDSA_SIG(s, &der); if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0) { WARN("Failure to get ECDSA_SIG\n"); goto err; } ret = mb_ecdsa_do_verify(dgst, dgst_len, s, eckey); err: OPENSSL_free(der); ECDSA_SIG_free(s); return ret; use_sw_method: EC_KEY_METHOD_get_verify((EC_KEY_METHOD *) EC_KEY_OpenSSL(), &verify_pfunc, NULL); if (verify_pfunc == NULL) { WARN("verify_pfunc is NULL\n"); QATerr(QAT_F_MB_ECDSA_VERIFY, QAT_R_SW_GET_VERIFY_PFUNC_NULL); return ret; } return (*verify_pfunc)(type, dgst, dgst_len, sigbuf, sig_len, eckey); } int mb_ecdsa_do_verify(const unsigned char *dgst, int dlen, const ECDSA_SIG *sig, EC_KEY *eckey) { int ret = -1, len = 0, job_ret = 0, sts = 0, alloc_buf = 0, bit_len = 0; BN_CTX *ctx = NULL; ASYNC_JOB *job; size_t buflen; static __thread int req_num = 0; const EC_GROUP *group; const BIGNUM *order; const EC_POINT *pub_key = NULL; unsigned char *dgst_buf = NULL; PFUNC_VERIFY_SIG verify_sig_pfunc = NULL; ecdsa_verify_op_data *ecdsa_verify_req = NULL; mb_thread_data *tlv = NULL; BIGNUM *x = NULL, *y = NULL, *z = NULL; DEBUG("Entering \n"); #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(dgst == NULL || dlen <= 0 || eckey == NULL)) { WARN("Invalid Input param\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_INPUT_PARAM_INVALID); return ret; } group = EC_KEY_get0_group(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_GROUP_PUB_KEY_NULL); return ret; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if curve is p256 or p384 */ if ((bit_len = mb_ec_check_curve(EC_GROUP_get_curve_name(group))) == 0) { DEBUG("Curve type not supported, using SW Method %d\n", EC_GROUP_get_curve_name(group)); #ifdef ENABLE_QAT_FIPS return ret; #else goto use_sw_method; #endif } /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif if (!EC_KEY_can_sign(eckey)) { WARN("Curve doesn't support Signing\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_CURVE_DOES_NOT_SUPPORT_SIGNING); return ret; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return ret; #else goto use_sw_method; #endif } while ((ecdsa_verify_req = mb_flist_ecdsa_verify_pop(tlv->ecdsa_verify_freelist)) == NULL) { # ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); # else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } # endif } DEBUG("QAT SW ECDSA Verify Started %p\n", ecdsa_verify_req); START_RDTSC(&ecdsa_cycles_verify_setup); if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdsa_verify_push(tlv->ecdsa_verify_freelist, ecdsa_verify_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); z = BN_CTX_get(ctx); if (x == NULL || y == NULL || z == NULL) { mb_flist_ecdsa_verify_push(tlv->ecdsa_verify_freelist, ecdsa_verify_req); WARN("Failed to allocate x or y or z\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_X_Y_Z_MALLOC_FAILURE); goto err; } if (!EC_POINT_get_Jprojective_coordinates_GFp(group, pub_key, x, y, z,ctx)) { mb_flist_ecdsa_verify_push(tlv->ecdsa_verify_freelist, ecdsa_verify_req); WARN("Failure to get the Jacobian coordinates for public Key\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_INTERNAL_ERROR); goto err; } if ((order = EC_GROUP_get0_order(group)) == NULL) { mb_flist_ecdsa_verify_push(tlv->ecdsa_verify_freelist, ecdsa_verify_req); WARN("Failure to get order from group\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_GET_ORDER_FAILURE); goto err; } len = BN_num_bits(order); buflen = (len + 7) / 8; /* If digest size is less, expand length with zero as crypto_mb * expects digest being sign length */ if (8 * dlen < len) { dgst_buf = OPENSSL_zalloc(buflen); if (dgst_buf == NULL) { mb_flist_ecdsa_verify_push(tlv->ecdsa_verify_freelist, ecdsa_verify_req); WARN("Failure to allocate dgst_buf\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_ECDSA_MALLOC_FAILURE); goto err; } alloc_buf = 1; memcpy(dgst_buf + buflen - dlen, dgst, dlen); } else { dgst_buf = (unsigned char *)dgst; } ecdsa_verify_req->sts = &sts; ecdsa_verify_req->s = sig; ecdsa_verify_req->x = x; ecdsa_verify_req->y = y; ecdsa_verify_req->z = z; ecdsa_verify_req->digest = dgst_buf; ecdsa_verify_req->job = job; switch (bit_len) { case EC_P256: mb_queue_ecdsap256_verify_enqueue(tlv->ecdsap256_verify_queue, ecdsa_verify_req); break; case EC_P384: mb_queue_ecdsap384_verify_enqueue(tlv->ecdsap384_verify_queue, ecdsa_verify_req); break; } STOP_RDTSC(&ecdsa_cycles_verify_setup, 1, "[ECDSA:verify_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_ecdsa_verify_reqs(tlv, bit_len); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdsa_verify_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdsa_verify_req, sts); #ifdef ENABLE_QAT_FIPS } #endif if (sts) { ret = 1; if (alloc_buf) OPENSSL_free(dgst_buf); } else { WARN("Failure in ECDSA Verify\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_ECDSA_VERIFY_FAILURE); goto err; } err: if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ret; use_sw_method: EC_KEY_METHOD_get_verify((EC_KEY_METHOD *) EC_KEY_OpenSSL(), NULL, &verify_sig_pfunc); if (verify_sig_pfunc == NULL) { WARN("verify_sig_pfunc is NULL\n"); QATerr(QAT_F_MB_ECDSA_DO_VERIFY, QAT_R_SW_GET_VERIFY_PFUNC_NULL); return ret; } return (*verify_sig_pfunc)(dgst, dlen, sig, eckey); } # endif /* QAT_BORINGSSL */ #endif /* ENABLE_QAT_SW_ECDSA */ #ifdef ENABLE_QAT_SW_ECDH int mb_ecdh_generate_key(EC_KEY *ecdh) { BN_CTX *ctx = NULL; const EC_GROUP *group; EC_POINT *pub_key = NULL; BIGNUM *priv_key = NULL; const BIGNUM *order; BIGNUM *x = NULL, *y = NULL, *z = NULL; int ret = 0, job_ret = 0, sts = 0, curve = 0; int alloc_priv = 0, alloc_pub = 0; PFUNC_GEN_KEY gen_key_pfunc = NULL; ecdh_keygen_op_data *ecdh_keygen_req = NULL; ASYNC_JOB *job; static __thread int req_num = 0; mb_thread_data *tlv = NULL; if (unlikely(ecdh == NULL || ((group = EC_KEY_get0_group(ecdh)) == NULL))) { WARN("Either ecdh or group are NULL\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_ECDH_GROUP_NULL); return ret; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if curve is p256 or p384 or sm2*/ if ((curve = mb_ec_check_curve(EC_GROUP_get_curve_name(group))) == 0) { DEBUG("Curve type not supported, using SW Method %d\n", EC_GROUP_get_curve_name(group)); goto use_sw_method; } /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((ecdh_keygen_req = mb_flist_ecdh_keygen_pop(tlv->ecdh_keygen_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW ECDH Started %p\n", ecdh_keygen_req); START_RDTSC(&ecdh_cycles_keygen_setup); if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); if ((order = EC_GROUP_get0_order(group)) == NULL) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failure to retrieve order\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_GET_ORDER_FAILURE); goto err; } if ((priv_key = (BIGNUM *)EC_KEY_get0_private_key(ecdh)) == NULL) { priv_key = BN_new(); if (priv_key == NULL) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failure to get priv_key\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_GET_PRIV_KEY_FAILURE); goto err; } alloc_priv = 1; } do { if (!BN_priv_rand_range(priv_key, order)) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failure to generate random value\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_PRIV_KEY_RAND_GENERATE_FAILURE); goto err; } } while (BN_is_zero(priv_key)) ; if (alloc_priv) { if (!EC_KEY_set_private_key(ecdh, priv_key)) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failure to set private key\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_SET_PRIV_KEY_FAILURE); goto err; } } if ((pub_key = (EC_POINT *)EC_KEY_get0_public_key(ecdh)) == NULL) { pub_key = EC_POINT_new(group); if (pub_key == NULL) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failure to allocate pub_key\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_PUB_KEY_MALLOC_FAILURE); goto err; } alloc_pub = 1; } x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); z = BN_CTX_get(ctx); if (x == NULL || y == NULL || z == NULL) { mb_flist_ecdh_keygen_push(tlv->ecdh_keygen_freelist, ecdh_keygen_req); WARN("Failed to allocate x or y or z\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_X_Y_Z_MALLOC_FAILURE); goto err; } ecdh_keygen_req->x = x; ecdh_keygen_req->y = y; ecdh_keygen_req->z = z; ecdh_keygen_req->priv_key = priv_key; ecdh_keygen_req->job = job; ecdh_keygen_req->sts = &sts; switch (curve) { case EC_P256: mb_queue_ecdhp256_keygen_enqueue(tlv->ecdhp256_keygen_queue, ecdh_keygen_req); break; case EC_P384: mb_queue_ecdhp384_keygen_enqueue(tlv->ecdhp384_keygen_queue, ecdh_keygen_req); break; case EC_SM2: mb_queue_sm2ecdh_keygen_enqueue(tlv->sm2ecdh_keygen_queue, ecdh_keygen_req); break; } STOP_RDTSC(&ecdh_cycles_keygen_setup, 1, "[ECDH:keygen_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdh_keygen_req, sts); do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdh_keygen_req, sts); if (!EC_POINT_set_Jprojective_coordinates_GFp(group, pub_key, x, y, z, ctx)) { WARN("Failure to set the Jacobian coordinates for public Key\n"); goto err; } if (sts) { if (!EC_KEY_set_public_key(ecdh, pub_key)) { WARN("Error setting pub_key\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, ERR_R_INTERNAL_ERROR); goto err; } ret = 1; } else { WARN("Failure in Keygen\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_KEYGEN_FAILURE); goto err; } err: if (alloc_pub) EC_POINT_free(pub_key); if (alloc_priv) BN_clear_free(priv_key); if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ret; use_sw_method: EC_KEY_METHOD_get_keygen((EC_KEY_METHOD *) EC_KEY_OpenSSL(), &gen_key_pfunc); if (gen_key_pfunc == NULL) { WARN("get keygen failed\n"); QATerr(QAT_F_MB_ECDH_GENERATE_KEY, QAT_R_SW_GET_KEYGEN_PFUNC_NULL); return ret; } else { return (*gen_key_pfunc)(ecdh); } } int mb_ecdh_compute_key(unsigned char **out, size_t *outlen, const EC_POINT *pub_key, const EC_KEY *ecdh) { BN_CTX *ctx; const BIGNUM *priv_key; const EC_GROUP *group; unsigned char *buf = NULL; int ret = 0,job_ret = 0, sts = 0, curve = 0; BIGNUM *x = NULL, *y = NULL, *z = NULL; PFUNC_COMP_KEY comp_key_pfunc = NULL; ecdh_compute_op_data *ecdh_compute_req = NULL; ASYNC_JOB *job; size_t buflen; static __thread int req_num = 0; mb_thread_data *tlv = NULL; #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (unlikely(ecdh == NULL || pub_key == NULL || ((priv_key = EC_KEY_get0_private_key(ecdh)) == NULL) || ((group = EC_KEY_get0_group(ecdh)) == NULL))) { WARN("Either ecdh or pub_key or priv_key or group is NULL\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, QAT_R_ECDH_PRIV_KEY_PUB_KEY_NULL); return ret; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if curve is p256 or p384 or sm2 */ if ((curve = mb_ec_check_curve(EC_GROUP_get_curve_name(group))) == 0) { DEBUG("Curve type not supported, using SW Method %d\n", EC_GROUP_get_curve_name(group)); #ifdef ENABLE_QAT_FIPS return ret; #else goto use_sw_method; #endif } /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return ret; #else goto use_sw_method; #endif } while ((ecdh_compute_req = mb_flist_ecdh_compute_pop(tlv->ecdh_compute_freelist)) == NULL) { #ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); #else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } #endif } DEBUG("QAT SW ECDH Started %p\n", ecdh_compute_req); START_RDTSC(&ecdh_cycles_compute_setup); if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdh_compute_push(tlv->ecdh_compute_freelist, ecdh_compute_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); z = BN_CTX_get(ctx); if (x == NULL || y == NULL || z == NULL) { mb_flist_ecdh_compute_push(tlv->ecdh_compute_freelist, ecdh_compute_req); WARN("Failed to allocate x or y or z\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, QAT_R_X_Y_Z_MALLOC_FAILURE); goto err; } buflen = (EC_GROUP_get_degree(group) + 7) / 8; if ((buf = OPENSSL_zalloc(buflen)) == NULL) { mb_flist_ecdh_compute_push(tlv->ecdh_compute_freelist, ecdh_compute_req); WARN("Failed to allocate buf\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_get_Jprojective_coordinates_GFp(group, pub_key, x, y, z,ctx)) { mb_flist_ecdh_compute_push(tlv->ecdh_compute_freelist, ecdh_compute_req); WARN("Failure to get the Jacobian coordinates for public Key\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } ecdh_compute_req->shared_key = buf; ecdh_compute_req->priv_key = priv_key; ecdh_compute_req->x = x; ecdh_compute_req->y = y; ecdh_compute_req->z = z; ecdh_compute_req->job = job; ecdh_compute_req->sts = &sts; switch (curve) { case EC_P256: mb_queue_ecdhp256_compute_enqueue(tlv->ecdhp256_compute_queue, ecdh_compute_req); break; case EC_P384: mb_queue_ecdhp384_compute_enqueue(tlv->ecdhp384_compute_queue, ecdh_compute_req); break; case EC_SM2: mb_queue_sm2ecdh_compute_enqueue(tlv->sm2ecdh_compute_queue, ecdh_compute_req); break; } STOP_RDTSC(&ecdh_cycles_compute_setup, 1, "[ECDH:compute_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_ecdh_compute_reqs(tlv, curve); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdh_compute_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdh_compute_req, sts); #ifdef ENABLE_QAT_FIPS } #endif if (sts) { *out = buf; *outlen = buflen; buf = NULL; ret = 1; } else { WARN("Failure in compute key\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, QAT_R_COMPUTE_FAILURE); goto err; } err: if (ctx != NULL) { BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_free(buf); } return ret; use_sw_method: EC_KEY_METHOD_get_compute_key((EC_KEY_METHOD *)EC_KEY_OpenSSL(), &comp_key_pfunc); if (comp_key_pfunc == NULL) { WARN("comp_key_pfunc is NULL\n"); QATerr(QAT_F_MB_ECDH_COMPUTE_KEY, QAT_R_SW_GET_COMPUTE_KEY_PFUNC_NULL); return ret; } return (*comp_key_pfunc)(out, outlen, pub_key, ecdh); } #endif qatengine-1.9.0/qat_sw_ec.h000066400000000000000000000077411500416242000156150ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_ec.h * * This file provides an interface to ECDH & ECDSA Multi-buffer operations * *****************************************************************************/ #ifndef QAT_SW_EC_H # define QAT_SW_EC_H # define EC_P256 1 # define EC_P384 2 # define EC_SM2 3 # include # ifdef ENABLE_QAT_SW_SM2 EVP_PKEY_METHOD *mb_sm2_pmeth(void); void process_ecdsa_sm2_sign_reqs(mb_thread_data *tlv); void process_ecdsa_sm2_verify_reqs(mb_thread_data *tlv); # endif # ifdef ENABLE_QAT_SW_ECDSA int mb_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey); int mb_ecdsa_do_verify(const unsigned char *dgst, int dlen, const ECDSA_SIG *sig, EC_KEY *eckey); int mb_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); #ifndef QAT_BORINGSSL int mb_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); ECDSA_SIG *mb_ecdsa_sign_sig(const unsigned char *dgst, int dlen, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); #else /* QAT_BORINGSSL */ int mb_ecdsa_sign_bssl(const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, EC_KEY *eckey); #endif /* QAT_BORINGSSL */ void process_ecdsa_sign_reqs(mb_thread_data *tlv, int bits); void process_ecdsa_sign_setup_reqs(mb_thread_data *tlv, int bits); void process_ecdsa_sign_sig_reqs(mb_thread_data *tlv, int bits); void process_ecdsa_verify_reqs(mb_thread_data *tlv, int bits); # endif # ifdef ENABLE_QAT_SW_ECDH int mb_ecdh_compute_key(unsigned char **out, size_t *outlen, const EC_POINT *pub_key, const EC_KEY *ecdh); int mb_ecdh_generate_key(EC_KEY *ecdh); void process_ecdh_keygen_reqs(mb_thread_data *tlv, int bits); void process_ecdh_compute_reqs(mb_thread_data *tlv, int bits); # endif #endif /* QAT_SW_EC_H */ qatengine-1.9.0/qat_sw_ecx.c000066400000000000000000000506441500416242000160000ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_ecx.c * * This file contains the engine implementation for X25519 MultiBuffer operations * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include #include /* Local includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" #ifdef QAT_OPENSSL_PROVIDER #include "qat_prov_ecx.h" #else #include "qat_evp.h" #endif #include "qat_sw_ecx.h" #include "qat_sw_request.h" /* Crypto_mb includes */ #include "crypto_mb/x25519.h" #define X25519_MULTIBUFF_BIT_DEPTH 2048 #define X25519_MULTIBUFF_KEYGEN 1 #define X25519_MULTIBUFF_DERIVE 2 /* X25519 nid */ int x25519_nid[] = { EVP_PKEY_X25519 }; #ifdef ENABLE_QAT_SW_ECX void process_x25519_keygen_reqs(mb_thread_data *tlv) { x25519_keygen_op_data *x25519_keygen_req_array[MULTIBUFF_BATCH] = {0}; const unsigned char *x25519_keygen_privkey[MULTIBUFF_BATCH] = {0}; unsigned char *x25519_keygen_pubkey[MULTIBUFF_BATCH] = {0}; unsigned int x25519_sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&x25519_cycles_keygen_execute); /* Build Arrays of pointers for call */ while ((x25519_keygen_req_array[req_num] = mb_queue_x25519_keygen_dequeue(tlv->x25519_keygen_queue)) != NULL) { x25519_keygen_privkey[req_num] = x25519_keygen_req_array[req_num]->privkey; x25519_keygen_pubkey[req_num] = x25519_keygen_req_array[req_num]->pubkey; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d keygen requests\n", local_request_no); num_ecx_sw_keygen_reqs += local_request_no; x25519_sts = mbx_x25519_public_key_mb8(x25519_keygen_pubkey, x25519_keygen_privkey); for (req_num = 0; req_num < local_request_no; req_num++) { if (x25519_keygen_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(x25519_sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer Keygen request[%d] success\n", req_num); *x25519_keygen_req_array[req_num]->sts = 1; } else { WARN("Multibuffer Keygen request[%d] failure\n", req_num); *x25519_keygen_req_array[req_num]->sts = 0; } } if (x25519_keygen_req_array[req_num]->job) { qat_wake_job(x25519_keygen_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(x25519_keygen_req_array[req_num], sizeof(x25519_keygen_op_data)); mb_flist_x25519_keygen_push(tlv->x25519_keygen_freelist, x25519_keygen_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_x25519_keygen_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&x25519_cycles_keygen_execute, 1, "[X25519:keygen_execute]"); DEBUG("Processed Final Request\n"); } void process_x25519_derive_reqs(mb_thread_data *tlv) { x25519_derive_op_data *x25519_derive_req_array[MULTIBUFF_BATCH] = {0}; const unsigned char *x25519_derive_privkey[MULTIBUFF_BATCH] = {0}; const unsigned char *x25519_derive_pubkey[MULTIBUFF_BATCH] = {0}; unsigned char *x25519_derive_sharedkey[MULTIBUFF_BATCH] = {0}; unsigned int x25519_sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&x25519_cycles_derive_execute); /* Build Arrays of pointers for call */ while ((x25519_derive_req_array[req_num] = mb_queue_x25519_derive_dequeue(tlv->x25519_derive_queue)) != NULL) { x25519_derive_privkey[req_num] = x25519_derive_req_array[req_num]->privkey; x25519_derive_pubkey[req_num] = x25519_derive_req_array[req_num]->pubkey; x25519_derive_sharedkey[req_num] = x25519_derive_req_array[req_num]->key; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d derive requests\n", local_request_no); num_ecx_sw_derive_reqs += local_request_no; x25519_sts = mbx_x25519_mb8(x25519_derive_sharedkey, x25519_derive_privkey, x25519_derive_pubkey); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(x25519_sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer Derive request[%d] success\n", req_num); *x25519_derive_req_array[req_num]->sts = 1; } else { WARN("Multibuffer Derive request[%d] Failure\n", req_num); *x25519_derive_req_array[req_num]->sts = 0; } if (x25519_derive_req_array[req_num]->job) { qat_wake_job(x25519_derive_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(x25519_derive_req_array[req_num], sizeof(x25519_derive_op_data)); mb_flist_x25519_derive_push(tlv->x25519_derive_freelist, x25519_derive_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_x25519_derive_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&x25519_cycles_derive_execute, 1, "[X25519:derive_execute]"); DEBUG("Processed Final Request\n"); } #ifdef QAT_OPENSSL_PROVIDER void* multibuff_x25519_keygen(void *ctx, OSSL_CALLBACK *osslcb, void *cbarg) #else int multibuff_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) #endif { ASYNC_JOB *job; int sts = 0, job_ret = 0; x25519_keygen_op_data *x25519_keygen_req = NULL; #ifdef QAT_OPENSSL_PROVIDER typedef void* (*sw_prov_fn_ptr)(void *, OSSL_CALLBACK*, void*); sw_prov_fn_ptr sw_fn_ptr = get_default_x25519_keymgmt().gen; ECX_KEY *key = NULL; #else int (*sw_fn_ptr)(EVP_PKEY_CTX *, EVP_PKEY *) = NULL; QAT_SW_ECX_KEY *key = NULL; #endif unsigned char *privkey = NULL, *pubkey = NULL; mb_thread_data *tlv = NULL; static __thread int req_num = 0; /* Check input parameters */ if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL.\n"); QATerr(QAT_F_MULTIBUFF_X25519_KEYGEN, QAT_R_CTX_NULL); #ifdef QAT_OPENSSL_PROVIDER return NULL; #else return sts; #endif } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return NULL; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return NULL; #else goto use_sw_method; #endif } while ((x25519_keygen_req = mb_flist_x25519_keygen_pop(tlv->x25519_keygen_freelist)) == NULL) { #ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); #else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } #endif } DEBUG("QAT SW ECX Started %p\n", x25519_keygen_req); START_RDTSC(&x25519_cycles_keygen_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ key = OPENSSL_zalloc(sizeof(*key)); if (key == NULL) { WARN("Cannot allocate key.\n"); QATerr(QAT_F_MULTIBUFF_X25519_KEYGEN, ERR_R_MALLOC_FAILURE); #ifdef QAT_OPENSSL_PROVIDER return NULL; #else return sts; #endif } #ifdef QAT_OPENSSL_3 key->keylen = X25519_KEYLEN; # if OPENSSL_VERSION_NUMBER < 0x30200000 key->references = 1; # else key->references.val = 1; # endif #endif pubkey = key->pubkey; privkey = key->privkey = OPENSSL_secure_malloc(X25519_KEYLEN); if (privkey == NULL) { WARN("Cannot allocate privkey.\n"); QATerr(QAT_F_MULTIBUFF_X25519_KEYGEN, ERR_R_MALLOC_FAILURE); OPENSSL_free(key); key = NULL; #ifdef QAT_OPENSSL_PROVIDER return NULL; #else return sts; #endif } if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0) { WARN("RAND function failed for privkey.\n"); QATerr(QAT_F_MULTIBUFF_X25519_KEYGEN, ERR_R_INTERNAL_ERROR); goto err; } #ifndef QAT_OPENSSL_PROVIDER x25519_keygen_req->pkey = pkey; #endif x25519_keygen_req->privkey = privkey; x25519_keygen_req->pubkey = pubkey; x25519_keygen_req->job = job; x25519_keygen_req->sts = &sts; mb_queue_x25519_keygen_enqueue(tlv->x25519_keygen_queue, x25519_keygen_req); STOP_RDTSC(&x25519_cycles_keygen_setup, 1, "[X25519:keygen_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_x25519_keygen_reqs(tlv); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", x25519_keygen_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", x25519_keygen_req, sts); #ifdef ENABLE_QAT_FIPS } #endif if (sts) { #ifdef QAT_OPENSSL_PROVIDER return key; #else EVP_PKEY_assign(pkey, EVP_PKEY_X25519, key); return sts; #endif } else { WARN("Failure in Keygen\n"); QATerr(QAT_F_MULTIBUFF_X25519_KEYGEN, QAT_R_KEYGEN_FAILURE); goto err; } err: if (sts == 0) { if (NULL != privkey) { OPENSSL_secure_free(privkey); if (NULL != key) { key->privkey = NULL; OPENSSL_free(key); key = NULL; } } } #ifdef QAT_OPENSSL_PROVIDER return NULL; #else return sts; #endif use_sw_method: # ifdef QAT_OPENSSL_PROVIDER DEBUG("SW Finished\n"); return sw_fn_ptr(ctx, osslcb, cbarg); # else EVP_PKEY_meth_get_keygen((EVP_PKEY_METHOD *)sw_x25519_pmeth, NULL, &sw_fn_ptr); sts = (*sw_fn_ptr)(ctx, pkey); DEBUG("SW Finished\n"); return sts; # endif } #ifdef QAT_OPENSSL_PROVIDER static int multibuff_validate_ecx_derive(void *ctx, const unsigned char **privkey, const unsigned char **pubkey) #else static int multibuff_validate_ecx_derive(EVP_PKEY_CTX *ctx, const unsigned char **privkey, const unsigned char **pubkey) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_ECX_CTX *ecxctx = (QAT_ECX_CTX *)ctx; if (ecxctx == NULL || ecxctx->key->privkey == NULL) { WARN("ecxctx or ecxctx->key->privkey is NULL\n"); QATerr(QAT_F_MULTIBUFF_VALIDATE_ECX_DERIVE, QAT_R_INVALID_PRIVATE_KEY); return 0; } *privkey = ecxctx->key->privkey; *pubkey = ecxctx->peerkey->pubkey; #else const QAT_SW_ECX_KEY *ecxkey, *peerecxkey; EVP_PKEY *pkey = NULL; EVP_PKEY *peerkey = NULL; if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx)) == NULL || (peerkey = EVP_PKEY_CTX_get0_peerkey(ctx)) == NULL) { DEBUG("ctx->pkey or ctx->peerkey is NULL\n"); QATerr(QAT_F_MULTIBUFF_VALIDATE_ECX_DERIVE, QAT_R_KEYS_NOT_SET); return 0; } ecxkey = (const QAT_SW_ECX_KEY *)EVP_PKEY_get0((const EVP_PKEY *)pkey); peerecxkey = (const QAT_SW_ECX_KEY *)EVP_PKEY_get0((const EVP_PKEY *)peerkey); if (ecxkey == NULL || ecxkey->privkey == NULL) { DEBUG("ecxkey or ecxkey->privkey is NULL\n"); QATerr(QAT_F_MULTIBUFF_VALIDATE_ECX_DERIVE, QAT_R_INVALID_PRIVATE_KEY); return 0; } if (peerecxkey == NULL) { DEBUG("peerecxkey is NULL\n"); QATerr(QAT_F_MULTIBUFF_VALIDATE_ECX_DERIVE, QAT_R_INVALID_PEER_KEY); return 0; } *privkey = ecxkey->privkey; *pubkey = peerecxkey->pubkey; #endif return 1; } #ifdef QAT_OPENSSL_PROVIDER int multibuff_x25519_derive(void *ctx, unsigned char *key, size_t *keylen, size_t outlen) #else int multibuff_x25519_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) #endif { ASYNC_JOB *job; int sts = 0, job_ret = 0; x25519_derive_op_data *x25519_derive_req = NULL; #ifdef QAT_OPENSSL_PROVIDER typedef int (*sw_prov_fn_ptr)(void *, unsigned char*, size_t*, size_t); sw_prov_fn_ptr sw_fn_ptr = get_default_x25519_keyexch().derive; #else int (*sw_fn_ptr)(EVP_PKEY_CTX *, unsigned char *, size_t *) = NULL; #endif const unsigned char *privkey = NULL, *pubkey = NULL; mb_thread_data *tlv = NULL; static __thread int req_num = 0; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL.\n"); QATerr(QAT_F_MULTIBUFF_X25519_DERIVE, QAT_R_CTX_NULL); return 0; } if (key == NULL) { *keylen = X25519_KEYLEN; return 1; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } while ((x25519_derive_req = mb_flist_x25519_derive_pop(tlv->x25519_derive_freelist)) == NULL) { #ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); #else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } #endif } DEBUG("QAT SW ECX Started %p\n", x25519_derive_req); START_RDTSC(&x25519_cycles_derive_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ if (!multibuff_validate_ecx_derive(ctx, &privkey, &pubkey)) return sts; x25519_derive_req->key = key; x25519_derive_req->privkey = privkey; x25519_derive_req->pubkey = pubkey; x25519_derive_req->job = job; x25519_derive_req->sts = &sts; mb_queue_x25519_derive_enqueue(tlv->x25519_derive_queue, x25519_derive_req); STOP_RDTSC(&x25519_cycles_derive_setup, 1, "[X25519:derive_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_x25519_derive_reqs(tlv); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", x25519_derive_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", x25519_derive_req, sts); #ifdef ENABLE_QAT_FIPS } #endif if (sts) { *keylen = X25519_KEYLEN; return sts; } else { WARN("Failure in derive\n"); QATerr(QAT_F_MULTIBUFF_X25519_DERIVE, QAT_R_DERIVE_FAILURE); return sts; } use_sw_method: # ifdef QAT_OPENSSL_PROVIDER DEBUG("SW Finished\n"); return sw_fn_ptr(ctx, key, keylen, outlen); # else EVP_PKEY_meth_get_derive((EVP_PKEY_METHOD *)sw_x25519_pmeth, NULL, &sw_fn_ptr); sts = (*sw_fn_ptr)(ctx, key, keylen); DEBUG("SW Finished\n"); return sts; # endif } # ifndef QAT_OPENSSL_PROVIDER int multibuff_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { /* Only need to handle peer key for derivation */ if (type == EVP_PKEY_CTRL_PEER_KEY) return 1; return -2; } # endif #endif /*ENABLE_QAT_HW_ECX*/ qatengine-1.9.0/qat_sw_ecx.h000066400000000000000000000045401500416242000157770ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_ecx.h * * This file provides an X25519 interface for an OpenSSL engine * *****************************************************************************/ #ifndef QAT_SW_ECX_H # define QAT_SW_ECX_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include /* Multibuff X25519 methods declaration */ void process_x25519_keygen_reqs(mb_thread_data *tlv); void process_x25519_derive_reqs(mb_thread_data *tlv); #endif /* QAT_SW_ECX_H */ qatengine-1.9.0/qat_sw_freelist.c000066400000000000000000001367031500416242000170370ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_freelist.c * * This file provides multibuffer implementations of a freelist * *****************************************************************************/ #include #include #include /* Local Includes */ #include "e_qat.h" #include "qat_sw_freelist.h" #include "qat_sw_request.h" #include "qat_utils.h" /* OpenSSL Includes */ #include mb_flist_rsa_priv * mb_flist_rsa_priv_create() { mb_flist_rsa_priv *freelist = NULL; rsa_priv_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_rsa_priv)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(rsa_priv_op_data)); if (item == NULL) { mb_flist_rsa_priv_cleanup(freelist); return NULL; } if (mb_flist_rsa_priv_push(freelist, item) != 0) { mb_flist_rsa_priv_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_rsa_priv_cleanup(mb_flist_rsa_priv *freelist) { rsa_priv_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_rsa_priv_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_rsa_priv_push(mb_flist_rsa_priv *freelist, rsa_priv_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } rsa_priv_op_data *mb_flist_rsa_priv_pop(mb_flist_rsa_priv *freelist) { rsa_priv_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_rsa_pub * mb_flist_rsa_pub_create() { mb_flist_rsa_pub *freelist = NULL; rsa_pub_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_rsa_pub)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(rsa_pub_op_data)); if (item == NULL) { mb_flist_rsa_pub_cleanup(freelist); return NULL; } if (mb_flist_rsa_pub_push(freelist, item) != 0) { mb_flist_rsa_pub_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_rsa_pub_cleanup(mb_flist_rsa_pub *freelist) { rsa_pub_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_rsa_pub_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_rsa_pub_push(mb_flist_rsa_pub *freelist, rsa_pub_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } rsa_pub_op_data * mb_flist_rsa_pub_pop(mb_flist_rsa_pub *freelist) { rsa_pub_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_x25519_keygen * mb_flist_x25519_keygen_create() { mb_flist_x25519_keygen *freelist = NULL; x25519_keygen_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_x25519_keygen)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(x25519_keygen_op_data)); if (item == NULL) { mb_flist_x25519_keygen_cleanup(freelist); return NULL; } if (mb_flist_x25519_keygen_push(freelist, item) != 0) { mb_flist_x25519_keygen_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_x25519_keygen_cleanup(mb_flist_x25519_keygen *freelist) { x25519_keygen_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_x25519_keygen_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_x25519_keygen_push(mb_flist_x25519_keygen *freelist, x25519_keygen_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } x25519_keygen_op_data *mb_flist_x25519_keygen_pop(mb_flist_x25519_keygen *freelist) { x25519_keygen_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_x25519_derive *mb_flist_x25519_derive_create() { mb_flist_x25519_derive *freelist = NULL; x25519_derive_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_x25519_derive)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(x25519_derive_op_data)); if (item == NULL) { mb_flist_x25519_derive_cleanup(freelist); return NULL; } if (mb_flist_x25519_derive_push(freelist, item) != 0) { mb_flist_x25519_derive_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_x25519_derive_cleanup(mb_flist_x25519_derive *freelist) { x25519_derive_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_x25519_derive_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_x25519_derive_push(mb_flist_x25519_derive *freelist, x25519_derive_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } x25519_derive_op_data *mb_flist_x25519_derive_pop(mb_flist_x25519_derive *freelist) { x25519_derive_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) { pthread_mutex_unlock(&freelist->mb_flist_mutex); } return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdsa_sign * mb_flist_ecdsa_sign_create() { mb_flist_ecdsa_sign *freelist = NULL; ecdsa_sign_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdsa_sign)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdsa_sign_op_data)); if (item == NULL) { mb_flist_ecdsa_sign_cleanup(freelist); return NULL; } if (mb_flist_ecdsa_sign_push(freelist, item) != 0) { mb_flist_ecdsa_sign_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdsa_sign_cleanup(mb_flist_ecdsa_sign *freelist) { ecdsa_sign_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdsa_sign_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdsa_sign_push(mb_flist_ecdsa_sign *freelist, ecdsa_sign_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdsa_sign_op_data *mb_flist_ecdsa_sign_pop(mb_flist_ecdsa_sign *freelist) { ecdsa_sign_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdsa_sign_setup * mb_flist_ecdsa_sign_setup_create() { mb_flist_ecdsa_sign_setup *freelist = NULL; ecdsa_sign_setup_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdsa_sign_setup)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdsa_sign_setup_op_data)); if (item == NULL) { mb_flist_ecdsa_sign_setup_cleanup(freelist); return NULL; } if (mb_flist_ecdsa_sign_setup_push(freelist, item) != 0) { mb_flist_ecdsa_sign_setup_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdsa_sign_setup_cleanup(mb_flist_ecdsa_sign_setup *freelist) { ecdsa_sign_setup_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdsa_sign_setup_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdsa_sign_setup_push(mb_flist_ecdsa_sign_setup *freelist, ecdsa_sign_setup_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdsa_sign_setup_op_data *mb_flist_ecdsa_sign_setup_pop(mb_flist_ecdsa_sign_setup *freelist) { ecdsa_sign_setup_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdsa_sign_sig * mb_flist_ecdsa_sign_sig_create() { mb_flist_ecdsa_sign_sig *freelist = NULL; ecdsa_sign_sig_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdsa_sign_sig)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdsa_sign_sig_op_data)); if (item == NULL) { mb_flist_ecdsa_sign_sig_cleanup(freelist); return NULL; } if (mb_flist_ecdsa_sign_sig_push(freelist, item) != 0) { mb_flist_ecdsa_sign_sig_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdsa_sign_sig_cleanup(mb_flist_ecdsa_sign_sig *freelist) { ecdsa_sign_sig_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdsa_sign_sig_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdsa_sign_sig_push(mb_flist_ecdsa_sign_sig *freelist, ecdsa_sign_sig_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdsa_sign_sig_op_data *mb_flist_ecdsa_sign_sig_pop(mb_flist_ecdsa_sign_sig *freelist) { ecdsa_sign_sig_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdsa_verify * mb_flist_ecdsa_verify_create() { mb_flist_ecdsa_verify *freelist = NULL; ecdsa_verify_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdsa_verify)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdsa_verify_op_data)); if (item == NULL) { mb_flist_ecdsa_verify_cleanup(freelist); return NULL; } if (mb_flist_ecdsa_verify_push(freelist, item) != 0) { mb_flist_ecdsa_verify_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdsa_verify_cleanup(mb_flist_ecdsa_verify *freelist) { ecdsa_verify_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdsa_verify_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdsa_verify_push(mb_flist_ecdsa_verify *freelist, ecdsa_verify_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdsa_verify_op_data *mb_flist_ecdsa_verify_pop(mb_flist_ecdsa_verify *freelist) { ecdsa_verify_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdsa_sm2_sign * mb_flist_ecdsa_sm2_sign_create() { mb_flist_ecdsa_sm2_sign *freelist = NULL; ecdsa_sm2_sign_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdsa_sm2_sign)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdsa_sm2_sign_op_data)); if (item == NULL) { mb_flist_ecdsa_sm2_sign_cleanup(freelist); return NULL; } if (mb_flist_ecdsa_sm2_sign_push(freelist, item) != 0) { mb_flist_ecdsa_sm2_sign_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdsa_sm2_sign_cleanup(mb_flist_ecdsa_sm2_sign *freelist) { ecdsa_sm2_sign_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdsa_sm2_sign_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdsa_sm2_sign_push(mb_flist_ecdsa_sm2_sign *freelist, ecdsa_sm2_sign_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdsa_sm2_sign_op_data *mb_flist_ecdsa_sm2_sign_pop(mb_flist_ecdsa_sm2_sign *freelist) { ecdsa_sm2_sign_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdsa_sm2_verify * mb_flist_ecdsa_sm2_verify_create() { mb_flist_ecdsa_sm2_verify *freelist = NULL; ecdsa_sm2_verify_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdsa_sm2_verify)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdsa_sm2_verify_op_data)); if (item == NULL) { mb_flist_ecdsa_sm2_verify_cleanup(freelist); return NULL; } if (mb_flist_ecdsa_sm2_verify_push(freelist, item) != 0) { mb_flist_ecdsa_sm2_verify_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdsa_sm2_verify_cleanup(mb_flist_ecdsa_sm2_verify *freelist) { ecdsa_sm2_verify_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdsa_sm2_verify_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdsa_sm2_verify_push(mb_flist_ecdsa_sm2_verify *freelist, ecdsa_sm2_verify_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdsa_sm2_verify_op_data *mb_flist_ecdsa_sm2_verify_pop(mb_flist_ecdsa_sm2_verify *freelist) { ecdsa_sm2_verify_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdh_keygen * mb_flist_ecdh_keygen_create() { mb_flist_ecdh_keygen *freelist = NULL; ecdh_keygen_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdh_keygen)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdh_keygen_op_data)); if (item == NULL) { mb_flist_ecdh_keygen_cleanup(freelist); return NULL; } if (mb_flist_ecdh_keygen_push(freelist, item) != 0) { mb_flist_ecdh_keygen_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdh_keygen_cleanup(mb_flist_ecdh_keygen *freelist) { ecdh_keygen_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdh_keygen_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdh_keygen_push(mb_flist_ecdh_keygen *freelist, ecdh_keygen_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdh_keygen_op_data *mb_flist_ecdh_keygen_pop(mb_flist_ecdh_keygen *freelist) { ecdh_keygen_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_ecdh_compute * mb_flist_ecdh_compute_create() { mb_flist_ecdh_compute *freelist = NULL; ecdh_compute_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_ecdh_compute)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(ecdh_compute_op_data)); if (item == NULL) { mb_flist_ecdh_compute_cleanup(freelist); return NULL; } if (mb_flist_ecdh_compute_push(freelist, item) != 0) { mb_flist_ecdh_compute_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_ecdh_compute_cleanup(mb_flist_ecdh_compute *freelist) { ecdh_compute_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_ecdh_compute_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_ecdh_compute_push(mb_flist_ecdh_compute *freelist, ecdh_compute_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } ecdh_compute_op_data *mb_flist_ecdh_compute_pop(mb_flist_ecdh_compute *freelist) { ecdh_compute_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_sm3_init * mb_flist_sm3_init_create() { mb_flist_sm3_init *freelist = NULL; sm3_init_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm3_init)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm3_init_op_data)); if (item == NULL) { mb_flist_sm3_init_cleanup(freelist); return NULL; } if (mb_flist_sm3_init_push(freelist, item) != 0) { mb_flist_sm3_init_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm3_init_cleanup(mb_flist_sm3_init *freelist) { sm3_init_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm3_init_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm3_init_push(mb_flist_sm3_init *freelist, sm3_init_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm3_init_op_data *mb_flist_sm3_init_pop(mb_flist_sm3_init *freelist) { sm3_init_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_sm3_update * mb_flist_sm3_update_create() { mb_flist_sm3_update *freelist = NULL; sm3_update_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm3_update)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm3_update_op_data)); if (item == NULL) { mb_flist_sm3_update_cleanup(freelist); return NULL; } if (mb_flist_sm3_update_push(freelist, item) != 0) { mb_flist_sm3_update_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm3_update_cleanup(mb_flist_sm3_update *freelist) { sm3_update_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm3_update_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm3_update_push(mb_flist_sm3_update *freelist, sm3_update_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm3_update_op_data *mb_flist_sm3_update_pop(mb_flist_sm3_update *freelist) { sm3_update_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_sm3_final * mb_flist_sm3_final_create() { mb_flist_sm3_final *freelist = NULL; sm3_final_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm3_final)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm3_final_op_data)); if (item == NULL) { mb_flist_sm3_final_cleanup(freelist); return NULL; } if (mb_flist_sm3_final_push(freelist, item) != 0) { mb_flist_sm3_final_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm3_final_cleanup(mb_flist_sm3_final *freelist) { sm3_final_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm3_final_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm3_final_push(mb_flist_sm3_final *freelist, sm3_final_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm3_final_op_data *mb_flist_sm3_final_pop(mb_flist_sm3_final *freelist) { sm3_final_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_sm4_cbc_cipher *mb_flist_sm4_cbc_cipher_create() { mb_flist_sm4_cbc_cipher *freelist = NULL; sm4_cbc_cipher_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm4_cbc_cipher)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm4_cbc_cipher_op_data)); if (item == NULL) { mb_flist_sm4_cbc_cipher_cleanup(freelist); return NULL; } if (mb_flist_sm4_cbc_cipher_push(freelist, item) != 0) { mb_flist_sm4_cbc_cipher_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm4_cbc_cipher_cleanup(mb_flist_sm4_cbc_cipher *freelist) { sm4_cbc_cipher_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm4_cbc_cipher_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm4_cbc_cipher_push(mb_flist_sm4_cbc_cipher *freelist, sm4_cbc_cipher_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm4_cbc_cipher_op_data *mb_flist_sm4_cbc_cipher_pop(mb_flist_sm4_cbc_cipher *freelist) { sm4_cbc_cipher_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } #ifdef ENABLE_QAT_SW_SM4_GCM mb_flist_sm4_gcm_encrypt *mb_flist_sm4_gcm_encrypt_create() { mb_flist_sm4_gcm_encrypt *freelist = NULL; sm4_gcm_encrypt_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm4_gcm_encrypt)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm4_gcm_encrypt_op_data)); if (item == NULL) { mb_flist_sm4_gcm_encrypt_cleanup(freelist); return NULL; } if (mb_flist_sm4_gcm_encrypt_push(freelist, item) != 0) { mb_flist_sm4_gcm_encrypt_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm4_gcm_encrypt_cleanup(mb_flist_sm4_gcm_encrypt *freelist) { sm4_gcm_encrypt_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm4_gcm_encrypt_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm4_gcm_encrypt_push(mb_flist_sm4_gcm_encrypt *freelist, sm4_gcm_encrypt_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm4_gcm_encrypt_op_data *mb_flist_sm4_gcm_encrypt_pop(mb_flist_sm4_gcm_encrypt *freelist) { sm4_gcm_encrypt_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_sm4_gcm_decrypt *mb_flist_sm4_gcm_decrypt_create() { mb_flist_sm4_gcm_decrypt *freelist = NULL; sm4_gcm_decrypt_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm4_gcm_decrypt)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm4_gcm_decrypt_op_data)); if (item == NULL) { mb_flist_sm4_gcm_decrypt_cleanup(freelist); return NULL; } if (mb_flist_sm4_gcm_decrypt_push(freelist, item) != 0) { mb_flist_sm4_gcm_decrypt_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm4_gcm_decrypt_cleanup(mb_flist_sm4_gcm_decrypt *freelist) { sm4_gcm_decrypt_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm4_gcm_decrypt_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm4_gcm_decrypt_push(mb_flist_sm4_gcm_decrypt *freelist, sm4_gcm_decrypt_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm4_gcm_decrypt_op_data *mb_flist_sm4_gcm_decrypt_pop(mb_flist_sm4_gcm_decrypt *freelist) { sm4_gcm_decrypt_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } #endif #ifdef ENABLE_QAT_SW_SM4_CCM mb_flist_sm4_ccm_encrypt *mb_flist_sm4_ccm_encrypt_create() { mb_flist_sm4_ccm_encrypt *freelist = NULL; sm4_ccm_encrypt_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm4_ccm_encrypt)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm4_ccm_encrypt_op_data)); if (item == NULL) { mb_flist_sm4_ccm_encrypt_cleanup(freelist); return NULL; } if (mb_flist_sm4_ccm_encrypt_push(freelist, item) != 0) { mb_flist_sm4_ccm_encrypt_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm4_ccm_encrypt_cleanup(mb_flist_sm4_ccm_encrypt *freelist) { sm4_ccm_encrypt_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm4_ccm_encrypt_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm4_ccm_encrypt_push(mb_flist_sm4_ccm_encrypt *freelist, sm4_ccm_encrypt_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm4_ccm_encrypt_op_data *mb_flist_sm4_ccm_encrypt_pop(mb_flist_sm4_ccm_encrypt *freelist) { sm4_ccm_encrypt_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } mb_flist_sm4_ccm_decrypt *mb_flist_sm4_ccm_decrypt_create() { mb_flist_sm4_ccm_decrypt *freelist = NULL; sm4_ccm_decrypt_op_data *item = NULL; int num_items = MULTIBUFF_MAX_INFLIGHTS; freelist = OPENSSL_zalloc(sizeof(mb_flist_sm4_ccm_decrypt)); if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_init(&freelist->mb_flist_mutex, NULL); DEBUG("Freelist Created %p\n", freelist); freelist->head = NULL; while (num_items > 0) { item = OPENSSL_zalloc(sizeof(sm4_ccm_decrypt_op_data)); if (item == NULL) { mb_flist_sm4_ccm_decrypt_cleanup(freelist); return NULL; } if (mb_flist_sm4_ccm_decrypt_push(freelist, item) != 0) { mb_flist_sm4_ccm_decrypt_cleanup(freelist); return NULL; } num_items--; } return freelist; } int mb_flist_sm4_ccm_decrypt_cleanup(mb_flist_sm4_ccm_decrypt *freelist) { sm4_ccm_decrypt_op_data *item = NULL; if (freelist == NULL) return 1; while ((item = mb_flist_sm4_ccm_decrypt_pop(freelist)) != NULL) { OPENSSL_free(item); } if (!enable_external_polling) { pthread_mutex_destroy(&freelist->mb_flist_mutex); OPENSSL_free(freelist); } return 0; } int mb_flist_sm4_ccm_decrypt_push(mb_flist_sm4_ccm_decrypt *freelist, sm4_ccm_decrypt_op_data *item) { if (freelist == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); item->next = freelist->head; freelist->head = item; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return 0; } sm4_ccm_decrypt_op_data *mb_flist_sm4_ccm_decrypt_pop(mb_flist_sm4_ccm_decrypt *freelist) { sm4_ccm_decrypt_op_data *item = NULL; if (freelist == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&freelist->mb_flist_mutex); if (freelist->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return NULL; } item = freelist->head; freelist->head = item->next; if (!enable_external_polling) pthread_mutex_unlock(&freelist->mb_flist_mutex); return item; } #endif qatengine-1.9.0/qat_sw_freelist.h000066400000000000000000000352131500416242000170360ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_freelist.h * * This file provides the data structure for storing unused multibuff requests * avoiding expensive malloc/frees in the data path. * *****************************************************************************/ #ifndef QAT_SW_FREELIST_H # define QAT_SW_FREELIST_H # include # include "qat_sw_request.h" # include "qat_sw_queue.h" #include typedef struct _mb_flist_rsa_priv { pthread_mutex_t mb_flist_mutex; rsa_priv_op_data *head; } mb_flist_rsa_priv; typedef struct _mb_flist_rsa_pub { pthread_mutex_t mb_flist_mutex; rsa_pub_op_data *head; } mb_flist_rsa_pub; typedef struct _mb_flist_x25519_keygen { pthread_mutex_t mb_flist_mutex; x25519_keygen_op_data *head; } mb_flist_x25519_keygen; typedef struct _mb_flist_x25519_derive { pthread_mutex_t mb_flist_mutex; x25519_derive_op_data *head; } mb_flist_x25519_derive; typedef struct _mb_flist_ecdsa_sign { pthread_mutex_t mb_flist_mutex; ecdsa_sign_op_data *head; } mb_flist_ecdsa_sign; typedef struct _mb_flist_ecdsa_sign_setup { pthread_mutex_t mb_flist_mutex; ecdsa_sign_setup_op_data *head; } mb_flist_ecdsa_sign_setup; typedef struct _mb_flist_ecdsa_sign_sig { pthread_mutex_t mb_flist_mutex; ecdsa_sign_sig_op_data *head; } mb_flist_ecdsa_sign_sig; typedef struct _mb_flist_ecdsa_verify { pthread_mutex_t mb_flist_mutex; ecdsa_verify_op_data *head; } mb_flist_ecdsa_verify; typedef struct _mb_flist_ecdsa_sm2_sign { pthread_mutex_t mb_flist_mutex; ecdsa_sm2_sign_op_data *head; } mb_flist_ecdsa_sm2_sign; typedef struct _mb_flist_ecdsa_sm2_verify { pthread_mutex_t mb_flist_mutex; ecdsa_sm2_verify_op_data *head; } mb_flist_ecdsa_sm2_verify; typedef struct _mb_flist_ecdh_keygen { pthread_mutex_t mb_flist_mutex; ecdh_keygen_op_data *head; } mb_flist_ecdh_keygen; typedef struct _mb_flist_ecdh_compute { pthread_mutex_t mb_flist_mutex; ecdh_compute_op_data *head; } mb_flist_ecdh_compute; typedef struct _mb_flist_sm3_init { pthread_mutex_t mb_flist_mutex; sm3_init_op_data *head; } mb_flist_sm3_init; typedef struct _mb_flist_sm3_update { pthread_mutex_t mb_flist_mutex; sm3_update_op_data *head; } mb_flist_sm3_update; typedef struct _mb_flist_sm3_final { pthread_mutex_t mb_flist_mutex; sm3_final_op_data *head; } mb_flist_sm3_final; typedef struct _mb_flist_sm4_cbc_cipher { pthread_mutex_t mb_flist_mutex; sm4_cbc_cipher_op_data *head; } mb_flist_sm4_cbc_cipher; # ifdef ENABLE_QAT_SW_SM4_GCM typedef struct _mb_flist_sm4_gcm_encrypt { pthread_mutex_t mb_flist_mutex; sm4_gcm_encrypt_op_data *head; } mb_flist_sm4_gcm_encrypt; typedef struct _mb_flist_sm4_gcm_decrypt { pthread_mutex_t mb_flist_mutex; sm4_gcm_decrypt_op_data *head; } mb_flist_sm4_gcm_decrypt; # endif # ifdef ENABLE_QAT_SW_SM4_CCM typedef struct _mb_flist_sm4_ccm_encrypt { pthread_mutex_t mb_flist_mutex; sm4_ccm_encrypt_op_data *head; } mb_flist_sm4_ccm_encrypt; typedef struct _mb_flist_sm4_ccm_decrypt { pthread_mutex_t mb_flist_mutex; sm4_ccm_decrypt_op_data *head; } mb_flist_sm4_ccm_decrypt; # endif typedef struct _mb_thread_data{ pthread_t polling_thread; int keep_polling; sem_t mb_polling_thread_sem; /* RSA */ mb_flist_rsa_priv *rsa_priv_freelist; mb_flist_rsa_pub *rsa_pub_freelist; mb_queue_rsa2k_priv *rsa2k_priv_queue; mb_queue_rsa2k_pub *rsa2k_pub_queue; mb_queue_rsa3k_priv *rsa3k_priv_queue; mb_queue_rsa3k_pub *rsa3k_pub_queue; mb_queue_rsa4k_priv *rsa4k_priv_queue; mb_queue_rsa4k_pub *rsa4k_pub_queue; /* X25519 */ mb_flist_x25519_keygen *x25519_keygen_freelist; mb_flist_x25519_derive *x25519_derive_freelist; mb_queue_x25519_keygen *x25519_keygen_queue; mb_queue_x25519_derive *x25519_derive_queue; /* ECDSA p256 */ mb_flist_ecdsa_sign *ecdsa_sign_freelist; mb_flist_ecdsa_sign_setup *ecdsa_sign_setup_freelist; mb_flist_ecdsa_sign_sig *ecdsa_sign_sig_freelist; mb_flist_ecdsa_verify *ecdsa_verify_freelist; mb_queue_ecdsap256_sign *ecdsap256_sign_queue; mb_queue_ecdsap256_sign_setup *ecdsap256_sign_setup_queue; mb_queue_ecdsap256_sign_sig *ecdsap256_sign_sig_queue; mb_queue_ecdsap256_verify *ecdsap256_verify_queue; /* ECDSA p384 */ mb_queue_ecdsap384_sign *ecdsap384_sign_queue; mb_queue_ecdsap384_sign_setup *ecdsap384_sign_setup_queue; mb_queue_ecdsap384_sign_sig *ecdsap384_sign_sig_queue; mb_queue_ecdsap384_verify *ecdsap384_verify_queue; /* ECDSA sm2 */ mb_flist_ecdsa_sm2_sign *ecdsa_sm2_sign_freelist; mb_flist_ecdsa_sm2_verify *ecdsa_sm2_verify_freelist; mb_queue_ecdsa_sm2_sign *ecdsa_sm2_sign_queue; mb_queue_ecdsa_sm2_verify *ecdsa_sm2_verify_queue; /* ECDH p256*/ mb_flist_ecdh_keygen *ecdh_keygen_freelist; mb_flist_ecdh_compute *ecdh_compute_freelist; mb_queue_ecdhp256_keygen *ecdhp256_keygen_queue; mb_queue_ecdhp256_compute *ecdhp256_compute_queue; /* ECDH p384*/ mb_queue_ecdhp384_keygen *ecdhp384_keygen_queue; mb_queue_ecdhp384_compute *ecdhp384_compute_queue; /* ECDH sm2*/ mb_queue_sm2ecdh_keygen *sm2ecdh_keygen_queue; mb_queue_sm2ecdh_compute *sm2ecdh_compute_queue; /* SM3 */ mb_flist_sm3_init *sm3_init_freelist; mb_flist_sm3_update *sm3_update_freelist; mb_flist_sm3_final *sm3_final_freelist; mb_queue_sm3_init *sm3_init_queue; mb_queue_sm3_update *sm3_update_queue; mb_queue_sm3_final *sm3_final_queue; /* SM4_CBC */ mb_flist_sm4_cbc_cipher *sm4_cbc_cipher_freelist; mb_flist_sm4_cbc_cipher *sm4_cbc_cipher_dec_freelist; mb_queue_sm4_cbc_cipher *sm4_cbc_cipher_queue; mb_queue_sm4_cbc_cipher *sm4_cbc_cipher_dec_queue; /* SM4_GCM */ # ifdef ENABLE_QAT_SW_SM4_GCM mb_flist_sm4_gcm_encrypt *sm4_gcm_encrypt_freelist; mb_flist_sm4_gcm_decrypt *sm4_gcm_decrypt_freelist; mb_queue_sm4_gcm_encrypt *sm4_gcm_encrypt_queue; mb_queue_sm4_gcm_decrypt *sm4_gcm_decrypt_queue; # endif /* SM4_CCM */ # ifdef ENABLE_QAT_SW_SM4_CCM mb_flist_sm4_ccm_encrypt *sm4_ccm_encrypt_freelist; mb_flist_sm4_ccm_decrypt *sm4_ccm_decrypt_freelist; mb_queue_sm4_ccm_encrypt *sm4_ccm_encrypt_queue; mb_queue_sm4_ccm_decrypt *sm4_ccm_decrypt_queue; # endif } mb_thread_data; mb_flist_rsa_priv * mb_flist_rsa_priv_create(); int mb_flist_rsa_priv_cleanup(mb_flist_rsa_priv *freelist); int mb_flist_rsa_priv_push(mb_flist_rsa_priv *freelist, rsa_priv_op_data *item); rsa_priv_op_data * mb_flist_rsa_priv_pop(mb_flist_rsa_priv *flist); mb_flist_rsa_pub * mb_flist_rsa_pub_create(); int mb_flist_rsa_pub_cleanup(mb_flist_rsa_pub *freelist); int mb_flist_rsa_pub_push(mb_flist_rsa_pub *freelist, rsa_pub_op_data *item); rsa_pub_op_data * mb_flist_rsa_pub_pop(mb_flist_rsa_pub *flist); mb_flist_x25519_keygen * mb_flist_x25519_keygen_create(); int mb_flist_x25519_keygen_cleanup(mb_flist_x25519_keygen *freelist); int mb_flist_x25519_keygen_push(mb_flist_x25519_keygen *freelist, x25519_keygen_op_data *item); x25519_keygen_op_data * mb_flist_x25519_keygen_pop(mb_flist_x25519_keygen *flist); mb_flist_x25519_derive * mb_flist_x25519_derive_create(); int mb_flist_x25519_derive_cleanup(mb_flist_x25519_derive *freelist); int mb_flist_x25519_derive_push(mb_flist_x25519_derive *freelist, x25519_derive_op_data *item); x25519_derive_op_data * mb_flist_x25519_derive_pop(mb_flist_x25519_derive *flist); mb_flist_ecdsa_sm2_sign * mb_flist_ecdsa_sm2_sign_create(); int mb_flist_ecdsa_sm2_sign_cleanup(mb_flist_ecdsa_sm2_sign *freelist); int mb_flist_ecdsa_sm2_sign_push(mb_flist_ecdsa_sm2_sign *freelist, ecdsa_sm2_sign_op_data *item); ecdsa_sm2_sign_op_data *mb_flist_ecdsa_sm2_sign_pop(mb_flist_ecdsa_sm2_sign *flist); mb_flist_ecdsa_sm2_verify * mb_flist_ecdsa_sm2_verify_create(); int mb_flist_ecdsa_sm2_verify_cleanup(mb_flist_ecdsa_sm2_verify *freelist); int mb_flist_ecdsa_sm2_verify_push(mb_flist_ecdsa_sm2_verify *freelist, ecdsa_sm2_verify_op_data *item); ecdsa_sm2_verify_op_data *mb_flist_ecdsa_sm2_verify_pop(mb_flist_ecdsa_sm2_verify *flist); mb_flist_ecdsa_sign * mb_flist_ecdsa_sign_create(); int mb_flist_ecdsa_sign_cleanup(mb_flist_ecdsa_sign *freelist); int mb_flist_ecdsa_sign_push(mb_flist_ecdsa_sign *freelist, ecdsa_sign_op_data *item); ecdsa_sign_op_data *mb_flist_ecdsa_sign_pop(mb_flist_ecdsa_sign *flist); mb_flist_ecdsa_sign_setup * mb_flist_ecdsa_sign_setup_create(); int mb_flist_ecdsa_sign_setup_cleanup(mb_flist_ecdsa_sign_setup *freelist); int mb_flist_ecdsa_sign_setup_push(mb_flist_ecdsa_sign_setup *freelist, ecdsa_sign_setup_op_data *item); ecdsa_sign_setup_op_data *mb_flist_ecdsa_sign_setup_pop(mb_flist_ecdsa_sign_setup *flist); mb_flist_ecdsa_sign_sig * mb_flist_ecdsa_sign_sig_create(); int mb_flist_ecdsa_sign_sig_cleanup(mb_flist_ecdsa_sign_sig *freelist); int mb_flist_ecdsa_sign_sig_push(mb_flist_ecdsa_sign_sig *freelist, ecdsa_sign_sig_op_data *item); ecdsa_sign_sig_op_data *mb_flist_ecdsa_sign_sig_pop(mb_flist_ecdsa_sign_sig *flist); mb_flist_ecdsa_verify * mb_flist_ecdsa_verify_create(); int mb_flist_ecdsa_verify_cleanup(mb_flist_ecdsa_verify *freelist); int mb_flist_ecdsa_verify_push(mb_flist_ecdsa_verify *freelist, ecdsa_verify_op_data *item); ecdsa_verify_op_data *mb_flist_ecdsa_verify_pop(mb_flist_ecdsa_verify *flist); mb_flist_ecdh_keygen * mb_flist_ecdh_keygen_create(); int mb_flist_ecdh_keygen_cleanup(mb_flist_ecdh_keygen *freelist); int mb_flist_ecdh_keygen_push(mb_flist_ecdh_keygen *freelist, ecdh_keygen_op_data *item); ecdh_keygen_op_data *mb_flist_ecdh_keygen_pop(mb_flist_ecdh_keygen *flist); mb_flist_ecdh_compute * mb_flist_ecdh_compute_create(); int mb_flist_ecdh_compute_cleanup(mb_flist_ecdh_compute *freelist); int mb_flist_ecdh_compute_push(mb_flist_ecdh_compute *freelist, ecdh_compute_op_data *item); ecdh_compute_op_data *mb_flist_ecdh_compute_pop(mb_flist_ecdh_compute *flist); mb_flist_sm3_init * mb_flist_sm3_init_create(); int mb_flist_sm3_init_cleanup(mb_flist_sm3_init *freelist); int mb_flist_sm3_init_push(mb_flist_sm3_init *freelist, sm3_init_op_data *item); sm3_init_op_data *mb_flist_sm3_init_pop(mb_flist_sm3_init *flist); mb_flist_sm3_update * mb_flist_sm3_update_create(); int mb_flist_sm3_update_cleanup(mb_flist_sm3_update *freelist); int mb_flist_sm3_update_push(mb_flist_sm3_update *freelist, sm3_update_op_data *item); sm3_update_op_data *mb_flist_sm3_update_pop(mb_flist_sm3_update *flist); mb_flist_sm3_final * mb_flist_sm3_final_create(); int mb_flist_sm3_final_cleanup(mb_flist_sm3_final *freelist); int mb_flist_sm3_final_push(mb_flist_sm3_final *freelist, sm3_final_op_data *item); sm3_final_op_data *mb_flist_sm3_final_pop(mb_flist_sm3_final *flist); mb_flist_sm4_cbc_cipher * mb_flist_sm4_cbc_cipher_create(); int mb_flist_sm4_cbc_cipher_cleanup(mb_flist_sm4_cbc_cipher *freelist); int mb_flist_sm4_cbc_cipher_push(mb_flist_sm4_cbc_cipher *freelist, sm4_cbc_cipher_op_data *item); sm4_cbc_cipher_op_data *mb_flist_sm4_cbc_cipher_pop(mb_flist_sm4_cbc_cipher *flist); # ifdef ENABLE_QAT_SW_SM4_GCM mb_flist_sm4_gcm_encrypt * mb_flist_sm4_gcm_encrypt_create(); int mb_flist_sm4_gcm_encrypt_cleanup(mb_flist_sm4_gcm_encrypt *freelist); int mb_flist_sm4_gcm_encrypt_push(mb_flist_sm4_gcm_encrypt *freelist, sm4_gcm_encrypt_op_data *item); sm4_gcm_encrypt_op_data *mb_flist_sm4_gcm_encrypt_pop(mb_flist_sm4_gcm_encrypt *flist); mb_flist_sm4_gcm_decrypt * mb_flist_sm4_gcm_decrypt_create(); int mb_flist_sm4_gcm_decrypt_cleanup(mb_flist_sm4_gcm_decrypt *freelist); int mb_flist_sm4_gcm_decrypt_push(mb_flist_sm4_gcm_decrypt *freelist, sm4_gcm_decrypt_op_data *item); sm4_gcm_decrypt_op_data *mb_flist_sm4_gcm_decrypt_pop(mb_flist_sm4_gcm_decrypt *flist); # endif # ifdef ENABLE_QAT_SW_SM4_CCM mb_flist_sm4_ccm_encrypt * mb_flist_sm4_ccm_encrypt_create(); int mb_flist_sm4_ccm_encrypt_cleanup(mb_flist_sm4_ccm_encrypt *freelist); int mb_flist_sm4_ccm_encrypt_push(mb_flist_sm4_ccm_encrypt *freelist, sm4_ccm_encrypt_op_data *item); sm4_ccm_encrypt_op_data *mb_flist_sm4_ccm_encrypt_pop(mb_flist_sm4_ccm_encrypt *flist); mb_flist_sm4_ccm_decrypt * mb_flist_sm4_ccm_decrypt_create(); int mb_flist_sm4_ccm_decrypt_cleanup(mb_flist_sm4_ccm_decrypt *freelist); int mb_flist_sm4_ccm_decrypt_push(mb_flist_sm4_ccm_decrypt *freelist, sm4_ccm_decrypt_op_data *item); sm4_ccm_decrypt_op_data *mb_flist_sm4_ccm_decrypt_pop(mb_flist_sm4_ccm_decrypt *flist); # endif #endif /* QAT_SW_FREELIST_H */ qatengine-1.9.0/qat_sw_gcm.c000066400000000000000000001257011500416242000157640ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_gcm.c * * This file provides an interface for engine vectorized AES-GCM * cipher operations * ****************************************************************************/ /* Standard Includes */ #include #include /* OpenSSL Includes */ #include #include #include #include /* Intel IPsec library include */ #include /* Local Includes */ #include "e_qat.h" #include "qat_evp.h" #include "qat_utils.h" #include "qat_sw_gcm.h" #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_ciphers.h" #endif #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif #define QAT_GCM_TLS_TOTAL_IV_LEN (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN) #define QAT_GCM_TLS_PAYLOADLENGTH_MSB_OFFSET 2 #define QAT_GCM_TLS_PAYLOADLENGTH_LSB_OFFSET 1 #define QAT_BYTE_SHIFT 8 #define AES_GCM_BLOCK_SIZE 1 #define TLS_VIRT_HDR_SIZE 13 #define AES_KEY_SIZE_128 16 #define AES_KEY_SIZE_192 24 #define AES_KEY_SIZE_256 32 /* The length of valid GCM Tag must be between 0 and 16 Bytes */ #define QAT_GCM_TAG_MIN_LEN 0 #define QAT_GCM_TAG_MAX_LEN 16 #define GET_TLS_HDR(qctx) ((qctx)->tls_aad) #define GET_TLS_VERSION(hdr) (((hdr)[9]) << QAT_BYTE_SHIFT | (hdr)[10]) #define GET_TLS_PAYLOAD_LEN(hdr) (((((hdr)[11]) << QAT_BYTE_SHIFT) & 0xff00) | ((hdr)[12] & 0x00ff)) #define SET_TLS_PAYLOAD_LEN(hdr, len) \ do { \ hdr[11] = (len & 0xff00) >> QAT_BYTE_SHIFT; \ hdr[12] = len & 0xff; \ } while (0) #ifdef ENABLE_QAT_SW_GCM # ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; # endif IMB_MGR *ipsec_mgr = NULL; #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_init_key(void *ctx, const unsigned char* inkey); int vaesgcm_init_gcm(void *ctx); #else int vaesgcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char* inkey); int vaesgcm_init_gcm(EVP_CIPHER_CTX *ctx); #endif static int qat_check_gcm_nid(int nid) { if (nid == NID_aes_128_gcm || nid == NID_aes_192_gcm || nid == NID_aes_256_gcm) return 1; else return 0; } #endif #ifdef ENABLE_QAT_SW_GCM /****************************************************************************** * function: * vaesgcm_ciphers_init(EVP_CIPHER_CTX *ctx, * const unsigned char *inkey, * const unsigned char *iv, * int enc) * * @param ctx [IN] - pointer to existing cipher ctx * @param inKey [IN] - cipher key * @param iv [IN] - initialisation vector * @param enc [IN] - 1 = encrypt, 0 = decrypt, -1 = keep prior setting * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the cipher parameters for this EVP context. * This function can and will be **called multiple times** with some args * being NULL as happens with 'openssl speed -evp aes-128-gcm' * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_ciphers_init(void *ctx, const unsigned char* inkey, const unsigned char* iv, int enc) #else int vaesgcm_ciphers_init(EVP_CIPHER_CTX *ctx, const unsigned char* inkey, const unsigned char* iv, int enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #else vaesgcm_ctx* qctx = NULL; #endif int retval = 1; /* Make sure we have an initialized ipsec mb manager before we start calling APIs */ if (!ipsec_mgr) { WARN("Intel IPsec MB Manager not Initialized.\n"); QATerr(QAT_F_VAESGCM_CIPHERS_INIT, QAT_R_INIT_FAILURE); return 0; } DEBUG("QAT SW GCM Started CTX = %p, key = %p, iv = %p, enc = %d\n", (void*)ctx, (void*)inkey, (void*)iv, enc); if (ctx == NULL) { WARN("ctx == NULL\n"); QATerr(QAT_F_VAESGCM_CIPHERS_INIT, QAT_R_CTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER qctx->enc = enc; #else qctx = vaesgcm_data(ctx); #endif if (qctx == NULL) { WARN("qctx == NULL\n"); QATerr(QAT_F_VAESGCM_CIPHERS_INIT, QAT_R_QCTX_NULL); return 0; } /* If a key is set and a tag has already been calculated * this cipher ctx is being reused, so zero the gcm ctx and tag state variables */ if (qctx->ckey_set && qctx->tag_calculated) { memset(&(qctx->gcm_ctx), 0, sizeof(qctx->gcm_ctx)); qctx->tag_set = 0; qctx->tag_calculated = 0; } /* Allocate gcm auth tag */ if (!qctx->tag) { qctx->tag = OPENSSL_zalloc(EVP_GCM_TLS_TAG_LEN); if (qctx->tag) { qctx->tag_len = EVP_GCM_TLS_TAG_LEN; qctx->tag_set = 0; } else { qctx->tag_len = 0; WARN("Failed to allocate qctx->tag\n"); QATerr(QAT_F_VAESGCM_CIPHERS_INIT, QAT_R_ALLOC_TAG_FAILURE); return 0; } } #ifdef QAT_OPENSSL_PROVIDER /* The OpenSSL 3.0 provider framework has different flow * control of the AES-GCM encryption. So we need to init * tag_set every time before doing qat_imb_aes_gcm_enc_finalize. * Otherwise, the tag will not be calculated. * */ qctx->tag_set = 0; #endif /* Allocate gcm calculated_tag */ if (!qctx->calculated_tag) { qctx->calculated_tag = OPENSSL_zalloc(EVP_GCM_TLS_TAG_LEN); if (qctx->calculated_tag) { qctx->tag_calculated = 0; } else { qctx->tag_len = 0; WARN("Failed to allocate qctx->calculated_tag\n"); QATerr(QAT_F_VAESGCM_CIPHERS_INIT, QAT_R_ALLOC_TAG_FAILURE); return 0; } } /* If we have an IV passed in, and the iv_len has not yet been set * default to QAT_GCM_TLS_TOTAL_IV_LEN (if IV size isn't 12 bytes, * it would have been set via ctrl function before we got here) */ if (qctx->iv_len <=0) { qctx->iv_len = QAT_GCM_TLS_TOTAL_IV_LEN; DEBUG("Setting IV length = %d\n", qctx->iv_len); } /* If we have an IV passed in and have yet to allocate memory for the IV */ qctx->iv = OPENSSL_realloc(qctx->iv, qctx->iv_len); DEBUG("Reallocated IV Buffer = %p, with size %d\n", qctx->iv, qctx->iv_len); qctx->next_iv = OPENSSL_realloc(qctx->next_iv, qctx->iv_len); DEBUG("Reallocated Next_IV Buffer = %p, with size %d\n", qctx->next_iv, qctx->iv_len); qctx->iv_set = 0; /* IV passed in */ if (iv != NULL) { if (qctx->iv) { DEBUG("Copying iv to qctx->iv with qctx->iv_len = %d\n", qctx->iv_len); memcpy(qctx->iv, iv, qctx->iv_len); memcpy(qctx->next_iv, iv, qctx->iv_len); qctx->iv_set = 1; } qctx->iv_gen = 0; } qctx->tls_aad_len = -1; /* If we got a key passed in, inialize the key schedule */ if (inkey) retval = vaesgcm_init_key(ctx, inkey); /* If both the cipher key and the IV have been set, * then init the gcm context */ if (qctx->ckey_set && qctx->iv_set) retval = vaesgcm_init_gcm(ctx); return retval; } /**************************************************************************** * function: * aes_gcm_increment_counter(unsigned char *ifc) * * @param ifc [IN,OUT] - pointer to invocation field counter * * description: * Increment provided invocation field counter (64-bit int) by 1 * * *************************************************************************/ static inline void aes_gcm_increment_counter(unsigned char* ifc) { int inv_field_size = 8; unsigned char byte; /* Loop over ifc starting with the least significant byte * and work towards the most significant byte of ifc*/ do { --inv_field_size; byte = ifc[inv_field_size]; /* Increment by one and copy back to invocation field */ ++byte; ifc[inv_field_size] = byte; if (byte) return; } while (inv_field_size); } /****************************************************************************** * function: * vaesgcm_ciphers_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) * * @param ctx [IN] - pointer to existing ctx * @param type [IN] - type of request either * EVP_CTRL_AEAD_SET_MAC_KEY or EVP_CTRL_AEAD_TLS1_AAD * @param arg [IN] - size of the pointed to by ptr * @param ptr [IN] - input buffer contain the necessary parameters * * @retval x The return value is dependent on the type of request being made * EVP_CTRL_AEAD_TLS1_AAD return value indicates the amount of * padding to be applied to the SSL/TLS record * @retval 0, -1 function failed * * description: * This function is a generic control interface provided by the EVP API. * The second type is used to specify the TLS virtual header which is * used in the authentication calculation and to identify record payload size. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_ciphers_ctrl(void* ctx, int type, int arg, void* ptr) #else int vaesgcm_ciphers_ctrl(EVP_CIPHER_CTX* ctx, int type, int arg, void* ptr) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX* qctx = (QAT_GCM_CTX*)ctx; #else vaesgcm_ctx* qctx = NULL; #endif int ret_val = 0; int enc = 0; if (ctx == NULL) { WARN("ctx == NULL\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_CTX_NULL); return -1; } #ifndef QAT_OPENSSL_PROVIDER qctx = vaesgcm_data(ctx); #endif if (qctx == NULL) { WARN("qctx == NULL\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_QCTX_NULL); return -1; } #ifdef QAT_OPENSSL_PROVIDER enc = qctx->enc; #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif switch (type) { case EVP_CTRL_INIT: { DEBUG("CTRL Type = EVP_CTRL_INIT, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); memset(qctx, 0, sizeof(vaesgcm_ctx)); qctx->tls_aad_len = -1; qctx->iv_gen = -1; ret_val = 1; break; } case EVP_CTRL_GCM_SET_IVLEN: { DEBUG("CTRL Type = EVP_CTRL_GCM_SET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (arg <= 0) { WARN("Invalid IV length provided\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } qctx->iv_len = arg; qctx->iv_set = 0; ret_val = 1; break; } case EVP_CTRL_GCM_SET_TAG: { DEBUG("CTRL Type = EVP_CTRL_GCM_SET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (enc || arg <= QAT_GCM_TAG_MIN_LEN || arg > QAT_GCM_TAG_MAX_LEN) { ret_val = 0; WARN("Bad input parameters\n"); break; } if (qctx->tag) { OPENSSL_free(qctx->tag); qctx->tag = NULL; } qctx->tag = OPENSSL_zalloc(arg); if (qctx->tag) { memcpy(qctx->tag, ptr, arg); qctx->tag_len = arg; DUMPL("Setting Tag", (const unsigned char*)qctx->tag, arg); qctx->tag_set = 1; ret_val = 1; } else { WARN("Tag alloc failure\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_ALLOC_TAG_FAILURE); ret_val = 0; } break; } case EVP_CTRL_GCM_GET_TAG: { DEBUG("CTRL Type = EVP_CTRL_GCM_GET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (!enc || arg <= QAT_GCM_TAG_MIN_LEN || arg > QAT_GCM_TAG_MAX_LEN || qctx->tag_len <= 0) { WARN("Bad input parameters\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_TAG_LEN); ret_val = 0; break; } if (!qctx->tag_set || (ptr == NULL)) { WARN("Tag not set\n"); ret_val = 0; break; } else memcpy(ptr, qctx->tag, arg); DUMPL("Getting Tag", (const unsigned char*)qctx->tag, arg); qctx->iv_set = 0; qctx->tag_calculated = 0; qctx->tag_set = 0; ret_val = 1; break; } case EVP_CTRL_GCM_SET_IV_FIXED: { DEBUG("CTRL Type = EVP_CTRL_GCM_SET_IV_FIXED, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (ptr == NULL || qctx->next_iv == NULL) { WARN("ptr || next_iv == NULL \n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_PTR_IV); ret_val = 0; break; } /* Special case: -1 length restores whole IV */ if (arg == -1) { DEBUG("Special case - Restoring IV, arg = %d\n", arg); memcpy(qctx->next_iv, ptr, qctx->iv_len); qctx->iv_gen = 1; ret_val = 1; break; } /* Fixed field must be at least 4 bytes (EVP_GCM_TLS_FIXED_IV_LEN) * and invocation field at least 8 (EVP_GCM_TLS_EXPLICIT_IV_LEN) */ if ((arg < EVP_GCM_TLS_FIXED_IV_LEN) || (qctx->iv_len - arg) < EVP_GCM_TLS_EXPLICIT_IV_LEN) { WARN("Length is not valid\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } if (arg != EVP_GCM_TLS_FIXED_IV_LEN) { WARN("IV length is not currently supported, iv_len = %d\n", arg); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } int iv_len = EVP_GCM_TLS_FIXED_IV_LEN; if (!qctx->iv) { qctx->iv = OPENSSL_zalloc(iv_len); if (qctx->iv == NULL) { WARN("Failed to allocate %d bytes\n", arg); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_IV_ALLOC_FAILURE); qctx->iv_len = 0; qctx->iv_gen = 0; ret_val = 0; break; } else qctx->iv_len = iv_len; } if (!qctx->next_iv) { qctx->next_iv = OPENSSL_zalloc(iv_len); if (qctx->next_iv == NULL) { WARN("Failed to allocate %d bytes\n", arg); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_IV_ALLOC_FAILURE); qctx->iv_len = 0; qctx->iv_gen = 0; ret_val = 0; break; } else qctx->iv_len = iv_len; } DUMPL("EVP_CTRL_GCM_SET_IV_FIXED - next_iv Pre", (const unsigned char*)qctx->next_iv, qctx->iv_len); if (arg) { memcpy(qctx->next_iv, ptr, arg); } DUMPL("EVP_CTRL_GCM_SET_IV_FIXED - next_iv Post", (const unsigned char*)qctx->next_iv, qctx->iv_len); /* Generate the explicit part of the IV for encryption */ if (enc && RAND_bytes(qctx->next_iv + arg, qctx->iv_len - arg) <= 0) { WARN("RAND_Bytes Failed to generate explicit IV\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_RAND_BYTES_FAILURE); ret_val = 0; break; } DUMPL("EVP_CTRL_GCM_SET_IV_FIXED - next _iv explicit", (const unsigned char*)qctx->next_iv, qctx->iv_len); qctx->iv_gen = 1; ret_val = 1; break; } case EVP_CTRL_GCM_IV_GEN: { DEBUG("CTRL Type = EVP_CTRL_GCM_IV_GEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); /* Called in TLS case before encryption */ if (NULL == qctx->iv || NULL == qctx->next_iv || NULL == ptr) { WARN("Invalid memory ptr\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_QCTX_MEMORY); ret_val = 0; break; } if (0 == qctx->iv_gen) { WARN("Operation not valid\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_QCTX_MEMORY); ret_val = 0; break; } /* Set the IV that will be used in the current operation */ memcpy(qctx->iv, qctx->next_iv, qctx->iv_len); if (arg <= 0 || arg > qctx->iv_len) { arg = qctx->iv_len; } /* Copy the explicit IV in the output buffer */ memcpy(ptr, qctx->next_iv + qctx->iv_len - arg, arg); /* Increment invocation field counter (last 8 bytes of IV) */ aes_gcm_increment_counter(qctx->next_iv + qctx->iv_len - 8); qctx->iv_set = 1; ret_val = 1; break; } case EVP_CTRL_GCM_SET_IV_INV: { /* Called in TLS case before decryption */ DEBUG("CTRL Type = EVP_CTRL_GCM_SET_IV_INV, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (0 == qctx->iv_gen || enc) { WARN("Operation not valid\n"); ret_val = 0; break; } if (NULL == qctx->iv || NULL == qctx->next_iv || NULL == ptr) { WARN("Memory Pointer not valid\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_QCTX_MEMORY); ret_val = 0; break; } /* Retrieve the explicit IV from the message buffer */ memcpy(qctx->next_iv + qctx->iv_len - arg, ptr, arg); /* Set the IV that will be used in the current operation */ memcpy(qctx->iv, qctx->next_iv, qctx->iv_len); qctx->iv_set = 1; ret_val = 1; break; } case EVP_CTRL_AEAD_TLS1_AAD: { DEBUG("CTRL Type = EVP_CTRL_AEAD_TLS1_AAD, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (arg != EVP_AEAD_TLS1_AAD_LEN) { WARN("AAD Length not valid %d\n", arg); ret_val = 0; break; } /* Check to see if tls_aad already allocated with correct size, * if so, reuse and save ourselves a free and malloc */ if ((qctx->tls_aad_len == EVP_AEAD_TLS1_AAD_LEN) && qctx->tls_aad) memcpy(qctx->tls_aad, ptr, qctx->tls_aad_len); else { if (qctx->tls_aad) { OPENSSL_free(qctx->tls_aad); qctx->tls_aad_len = -1; qctx->tls_aad_set = 0; } qctx->tls_aad_len = EVP_AEAD_TLS1_AAD_LEN; qctx->tls_aad = OPENSSL_malloc(qctx->tls_aad_len); if (qctx->tls_aad) { /* Copy the header from payload into the buffer */ memcpy(qctx->tls_aad, ptr, qctx->tls_aad_len); } else { WARN("AAD alloc failed\n"); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_MALLOC_FAILURE); ret_val = 0; break; } } /* Extract the length of the payload from the TLS header */ unsigned int plen = qctx->tls_aad[arg - QAT_GCM_TLS_PAYLOADLENGTH_MSB_OFFSET] << QAT_BYTE_SHIFT | qctx->tls_aad[arg - QAT_GCM_TLS_PAYLOADLENGTH_LSB_OFFSET]; /* The payload contains the explicit IV -> correct the length */ plen -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!enc) { plen -= EVP_GCM_TLS_TAG_LEN; } /* Fix the length like in the SW version of GCM */ qctx->tls_aad[EVP_AEAD_TLS1_AAD_LEN - QAT_GCM_TLS_PAYLOADLENGTH_MSB_OFFSET] = plen >> QAT_BYTE_SHIFT; qctx->tls_aad[EVP_AEAD_TLS1_AAD_LEN - QAT_GCM_TLS_PAYLOADLENGTH_LSB_OFFSET] = plen; // & 0xff; qctx->tls_aad_set = 1; /* Extra padding: tag appended to record */ ret_val = EVP_GCM_TLS_TAG_LEN; break; } case EVP_CTRL_GET_IVLEN: { DEBUG("CTRL Type = EVP_CTRL_GET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); *(int*)ptr = qctx->iv_len; ret_val = 1; break; } default: { WARN("Invalid type %d\n", type); QATerr(QAT_F_VAESGCM_CIPHERS_CTRL, QAT_R_INVALID_TYPE); ret_val = -1; break; } } return ret_val; } /****************************************************************************** * function: * vaesgcm_ciphers_cleanup(EVP_CIPHER_CTX *ctx) * * @param ctx [IN] - pointer to existing ctx * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_ciphers_cleanup(void* ctx) #else int vaesgcm_ciphers_cleanup(EVP_CIPHER_CTX* ctx) #endif { #ifdef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; # endif QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #else vaesgcm_ctx* qctx = vaesgcm_data(ctx); #endif if (qctx) { OPENSSL_cleanse(&qctx->key_data, sizeof(qctx->key_data)); if (qctx->iv) { DEBUG("qctx->iv_len = %d\n", qctx->iv_len); OPENSSL_clear_free(qctx->iv, qctx->iv_len); qctx->iv = NULL; qctx->iv_set = 0; } if (qctx->next_iv) { OPENSSL_clear_free(qctx->next_iv, qctx->iv_len); qctx->next_iv = NULL; qctx->iv_len = 0; } if (qctx->tls_aad) { DEBUG("qctx->tls_aad_len = %d\n", qctx->tls_aad_len); OPENSSL_clear_free(qctx->tls_aad, EVP_AEAD_TLS1_AAD_LEN); qctx->tls_aad = NULL; qctx->tls_aad_len = -1; qctx->tls_aad_set = 0; } if (qctx->calculated_tag) { OPENSSL_clear_free(qctx->calculated_tag, qctx->tag_len); qctx->calculated_tag = NULL; qctx->tag_calculated = 0; } if (qctx->tag) { #ifdef QAT_OPENSSL_PROVIDER DEBUG("qctx->tag_len = %d\n", qctx->tag_len); #else DEBUG("qctx->tag_len = %u\n", qctx->tag_len); #endif OPENSSL_clear_free(qctx->tag, qctx->tag_len); qctx->tag = NULL; qctx->tag_len = 0; qctx->tag_set = 0; } } #ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); #endif return 1; } #ifdef QAT_OPENSSL_PROVIDER int QAT_AES_CIPHER_CTX_encrypting(QAT_GCM_CTX *qctx) { return qctx->enc; } #endif /****************************************************************************** * function: * aes_gcm_tls_cipher(EVP_CIPHER_CTX *evp_ctx, unsigned char *out, * const unsigned char *in, size_t len) * * @param evp_ctx [IN] - pointer to existing context * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval 1 function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * This is the function used in the TLS case. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int aes_gcm_tls_cipher(void *ctx, unsigned char* out, size_t * padlen, const unsigned char* in, size_t len, int enc) #else int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char* out, const unsigned char* in, size_t len, vaesgcm_ctx* qctx, int enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #endif unsigned int message_len = 0; int nid = 0; void* tag = NULL; unsigned int tag_offset = len - EVP_GCM_TLS_TAG_LEN; unsigned char* orig_payload_loc = (unsigned char*)in; struct gcm_key_data* key_data_ptr = NULL; struct gcm_context_data* gcm_ctx_ptr = NULL; DEBUG("enc = %d - ctx = %p, out = %p, in = %p, len = %zu\n", enc, (void*)ctx, (void*)out, (void*)in, len); if (NULL == in || out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) { WARN("Input parameters are not valid\n"); QATerr(QAT_F_AES_GCM_TLS_CIPHER, QAT_R_INVALID_INPUT_PARAMETER); return -1; } #ifdef QAT_OPENSSL_PROVIDER if (vaesgcm_ciphers_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) { WARN("vaesgcm_ciphers_ctrl Failed\n"); return -1; } #else /* Encryption: generate explicit IV and write to start of buffer. * Decryption: read the explicit IV from start of buffer */ if (EVP_CIPHER_CTX_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) { WARN("EVP_CIPHER_CTRL Failed\n"); return -1; } #endif #ifdef QAT_OPENSSL_PROVIDER nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); #else nid = EVP_CIPHER_CTX_nid(ctx); #endif key_data_ptr = &(qctx->key_data); /* The key has been set in the init function: no need to check it here*/ /* Initialize the session if not done before */ if (0 == vaesgcm_init_gcm(ctx)) { WARN("Failed to initialize GCM Context\n"); QATerr(QAT_F_AES_GCM_TLS_CIPHER, QAT_R_INITIALIZE_CTX_FAILURE); return -1; } /* Include the explicit part of the IV at the beginning of the output */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; /* This is the length of the message that must be encrypted */ message_len = len - (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN); gcm_ctx_ptr = &(qctx->gcm_ctx); tag = orig_payload_loc + tag_offset; if (enc) { /* Encrypt the payload */ qat_imb_aes_gcm_enc_update(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, message_len); /* Finalize to get the GCM Tag */ qat_imb_aes_gcm_enc_finalize(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, tag, EVP_GCM_TLS_TAG_LEN); qctx->tag_set = 1; } else { qat_imb_aes_gcm_dec_update(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, message_len); DUMPL("Payload Dump After - Decrypt Update", (const unsigned char*)orig_payload_loc, len); uint8_t tempTag[EVP_GCM_TLS_TAG_LEN]; memset(tempTag, 0, EVP_GCM_TLS_TAG_LEN); qat_imb_aes_gcm_enc_finalize(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, tempTag, EVP_GCM_TLS_TAG_LEN); if (memcmp(tag, tempTag, EVP_GCM_TLS_TAG_LEN) == 0) { DEBUG("ctx = %p, nid = %d,GCM TAG Verification Successful\n", ctx, nid); } else { WARN("ctx = %p, nid = %d, GCM TAG Verification Failed\n", ctx, nid); DUMPL("Expected GCM TAG", (const unsigned char*)tag, EVP_GCM_TLS_TAG_LEN); DUMPL("Computed GCM TAG", (const unsigned char*)tempTag, EVP_GCM_TLS_TAG_LEN); DUMPL("Payload After Decrypt Finalize", (const unsigned char*)orig_payload_loc, len); QATerr(QAT_F_AES_GCM_TLS_CIPHER, QAT_R_GCM_TAG_VERIFY_FAILURE); return -1; } } #ifdef QAT_OPENSSL_PROVIDER if (enc) *padlen = len; else *padlen = message_len; return 1; #else if (enc) return len; else return message_len; #endif } /****************************************************************************** * function: * vaesgcm_ciphers_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * size_t *padlen,, const unsigned char *in, * size_t len) * * @param ctx [IN] - pointer to existing ctx * @param out [OUT] - output buffer for transform result * @param in [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval 0,1 function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_ciphers_do_cipher(void *ctx, unsigned char* out, size_t *padlen, const unsigned char* in, size_t len) #else int vaesgcm_ciphers_do_cipher(EVP_CIPHER_CTX* ctx, unsigned char* out, const unsigned char* in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #else vaesgcm_ctx* qctx = NULL; #endif int enc = 0; int nid = 0; struct gcm_key_data* key_data_ptr = NULL; struct gcm_context_data* gcm_ctx_ptr = NULL; #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif if (ctx == NULL) { WARN("ctx == NULL\n"); QATerr(QAT_F_VAESGCM_CIPHERS_DO_CIPHER, QAT_R_CTX_NULL); return -1; } #ifndef QAT_OPENSSL_PROVIDER qctx = vaesgcm_data(ctx); #endif if (qctx == NULL) { WARN("qctx == NULL\n"); QATerr(QAT_F_VAESGCM_CIPHERS_DO_CIPHER, QAT_R_QCTX_NULL); return -1; } #ifdef QAT_OPENSSL_PROVIDER enc = QAT_AES_CIPHER_CTX_encrypting(qctx); nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)qctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); nid = EVP_CIPHER_CTX_nid(ctx); #endif key_data_ptr = &(qctx->key_data); if (!qat_check_gcm_nid(nid)) { WARN("NID not supported %d\n", nid); QATerr(QAT_F_VAESGCM_CIPHERS_DO_CIPHER, QAT_R_NID_NOT_SUPPORTED); return -1; } DEBUG("enc = %d - ctx = %p, NID = %d out = %p, in = %p, len = %zu\n", enc, (void*)ctx, nid, (void*)out, (void*)in, len); /* Distinguish between a regular crypto update and the TLS case * qctx->tls_aad_len only set when EVP_CTRL_AEAD_TLS1_AAD control is sent */ if (qctx->tls_aad_len >= 0) #ifdef QAT_OPENSSL_PROVIDER return aes_gcm_tls_cipher(ctx, out, padlen, in, len, enc); #else return aes_gcm_tls_cipher(ctx, out, in, len, qctx, enc); #endif gcm_ctx_ptr = &(qctx->gcm_ctx); /* If we have a case where out == NULL, and in != NULL, * then its aad being passed */ if ((out == NULL) && (in != NULL)) { qat_imb_aes_gcm_init_var_iv(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, qctx->iv, qctx->iv_len, in, len); DEBUG("AAD passed in\n"); #ifdef QAT_OPENSSL_PROVIDER *padlen = len; return 1; #else return 0; #endif } /* Handle the case where EVP_EncryptFinal_ex is called with a NULL input buffer. * Note: Null CT/PT provided to EVP_Encrypt|DecryptUpdate shares the same function * signature as if EVP_Encrypt|DecryptFinal_ex() was called */ if (in == NULL && out != NULL) { if (enc) { if (qctx->tag == NULL || qctx->tag_len <= 0) { WARN("AES-GCM Tag == NULL || tag_len <=0\n"); return -1; } /* if we haven't already calculated and the set the tag, * then do so */ if (qctx->tag_set < 1) { qat_imb_aes_gcm_enc_finalize(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, qctx->tag, qctx->tag_len); } qctx->tag_set = 1; #ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->buf,qctx->tag,qctx->tag_len); #else return len; #endif } else { /* Decrypt Flow */ if (qctx->tag_len < 0 || qctx->calculated_tag == NULL) { WARN("AES-GCM tag_len <0 or calculated tag NULL\n"); return -1; } if (qctx->tag_calculated < 1) { qat_imb_aes_gcm_dec_finalize(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, qctx->tag_len); /* Stash the calculated tag from the decryption, * so it can get compared to expected value below */ memcpy(qctx->calculated_tag, out, qctx->tag_len); DUMPL("Decrypt - Calculated Tag", (const unsigned char*)qctx->calculated_tag , qctx->tag_len); qctx->tag_calculated = 1; } #ifdef ENABLE_QAT_FIPS memcpy(qctx->tag, qctx->buf, qctx->tag_len); qctx->tag_set = 1; #endif DUMPL("Decrypt - Set Tag", (const unsigned char*)qctx->tag, qctx->tag_len); /* Wait until signaled by EVP_CTRL_GCM_SET_TAG, that a tag * has been set via the control function before we compared * the one we calculated if qctx->tag_set == 0, then it is * likely that NULL plaintext was sent in and this looksi * just like a DecryptFinal_Ex() call, so wait until control * function calls to set the tag */ if (qctx->tag_set) { DEBUG("Decrypt - GCM Tag Set so calling memcmp\n"); if (memcmp(qctx->calculated_tag, qctx->tag, qctx->tag_len) == 0) { #ifdef ENABLE_QAT_FIPS return 1; #else return 0; #endif } else { WARN("AES-GCM calculated tag comparison failed\n"); DUMPL("Expected Tag:", (const unsigned char *)qctx->tag, qctx->tag_len); DUMPL("Calculated Tag:", (const unsigned char *)qctx->calculated_tag, qctx->tag_len); DUMPL("Decrypt - Calculated Tag", (const unsigned char*)qctx->calculated_tag , qctx->tag_len); return -1; } } } } else { if (enc) qat_imb_aes_gcm_enc_update(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); else qat_imb_aes_gcm_dec_update(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); } #ifdef QAT_OPENSSL_PROVIDER *padlen = len; return 1; #else return len; #endif } /****************************************************************************** * function: * vaesgcm_init_key(EVP_CIPHER_CTX* ctx, const unsigned char* inkey) * * @param evp_ctx [IN] - pointer to existing context * @param inkey [IN] - pointer to input key * * @retval 0 function failed * @retval 1 function succeeded * * description: * Allocate and Initialize the Key * * ***************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_init_key(void *ctx, const unsigned char* inkey) #else int vaesgcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char* inkey) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #else vaesgcm_ctx* qctx = NULL; #endif struct gcm_key_data* key_data_ptr = NULL; int nid = 0; const void* key = NULL; if (ctx == NULL || inkey == NULL) { WARN("Either ctx or inkey is NULL \n"); QATerr(QAT_F_VAESGCM_INIT_KEY, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER qctx = vaesgcm_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_VAESGCM_INIT_KEY, QAT_R_QCTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); #else nid = EVP_CIPHER_CTX_nid(ctx); #endif if (!qat_check_gcm_nid(nid)) { WARN("NID not supported %d\n", nid); QATerr(QAT_F_VAESGCM_INIT_KEY, QAT_R_NID_NOT_SUPPORTED); return -1; } key = (const void*)(inkey); key_data_ptr = &(qctx->key_data); qat_imb_aes_gcm_precomp(nid, ipsec_mgr, key, key_data_ptr); qctx->ckey_set = 1; return 1; } /****************************************************************************** * function: * vaesgcm_init_gcm(EVP_CIPHER_CTX* ctx) * * @param evp_ctx [IN] - pointer to cipher context * * @retval 0 function failed * @retval 1 function succeeded * * description: * Allocate and Initialize the gcm ctx * ******************************************************************************/ #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_init_gcm(void *ctx) #else int vaesgcm_init_gcm(EVP_CIPHER_CTX *ctx) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_GCM_CTX *qctx = (QAT_GCM_CTX *)ctx; #else vaesgcm_ctx* qctx = NULL; #endif int nid = 0; int aad_len = 0; struct gcm_key_data* key_data_ptr = NULL; struct gcm_context_data* gcm_ctx_ptr = NULL; const unsigned char* aad_ptr = NULL; if (ctx == NULL) { WARN("ctx is NULL\n"); QATerr(QAT_F_VAESGCM_INIT_GCM, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER qctx = vaesgcm_data(ctx); #endif if (qctx == NULL) { WARN("qctx == NULL\n"); QATerr(QAT_F_VAESGCM_INIT_GCM, QAT_R_QCTX_NULL); return 0; } #ifdef QAT_OPENSSL_PROVIDER nid = qat_aes_gcm_ctx_get_nid((QAT_AES_GCM_CTX *)ctx); #else nid = EVP_CIPHER_CTX_nid(ctx); #endif if (!qat_check_gcm_nid(nid)) { WARN("NID not supported %d\n", nid); QATerr(QAT_F_VAESGCM_INIT_GCM, QAT_R_NID_NOT_SUPPORTED); return 0; } /* if both the cipher key and the IV have been set, then init */ if (qctx->ckey_set && (qctx->iv_set || qctx->iv_gen)) { key_data_ptr = &(qctx->key_data); gcm_ctx_ptr = &(qctx->gcm_ctx); aad_ptr = qctx->tls_aad; aad_len = qctx->tls_aad_len; if (qctx->tls_aad_len < 0) aad_len = 0; qat_imb_aes_gcm_init_var_iv(nid, ipsec_mgr, key_data_ptr, gcm_ctx_ptr, qctx->iv, qctx->iv_len, aad_ptr, aad_len); return 1; } else { WARN("Cipher key, IV and iv_gen not set\n"); QATerr(QAT_F_VAESGCM_INIT_GCM, QAT_R_INVALID_INPUT_PARAMETER); return 0; } } /****************************************************************************** * function: * vaesgcm_init_ipsec_mb_mgr(void) * * @retval 0 function failed * @retval 1 function succeeded * * description: * Allocate and Initialize the Intel IPsec Multi-Buffer Library Manager * to help dispatch AVX512 APIS * ******************************************************************************/ int vaesgcm_init_ipsec_mb_mgr() { if (ipsec_mgr == NULL) { ipsec_mgr = alloc_mb_mgr(0); if (ipsec_mgr == NULL) { WARN("Error allocating Intel IPsec MB_MGR!\n"); QATerr(QAT_F_VAESGCM_INIT_IPSEC_MB_MGR, QAT_R_IPSEC_MGR_NULL); return 0; } else { /* Initialize the manager to dispatch AVX2 and AVX512 IPsec APIs */ init_mb_mgr_auto(ipsec_mgr, NULL); return 1; } } if (qat_reload_algo) return 1; WARN("Intel IPsec MB_MGR already allocated\n"); return 0; } /****************************************************************************** * function: * vaesgcm_free_ipsec_mb_mgr(void) * * description: * Free Intel IPsec Multi-Buffer Library Manager resources * ******************************************************************************/ void vaesgcm_free_ipsec_mb_mgr() { if (ipsec_mgr) { free_mb_mgr(ipsec_mgr); ipsec_mgr = NULL; } } #endif qatengine-1.9.0/qat_sw_gcm.h000066400000000000000000000142271500416242000157710ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_gcm.h * * This file provides an interface for engine vectorized AES-GCM * cipher operations * ****************************************************************************/ #ifndef QAT_SW_GCM_H # define QAT_SW_GCM_H # include # include # include # define VAESGCM_COMMON_CIPHER_FLAG EVP_CIPH_FLAG_DEFAULT_ASN1 # define VAESGCM_FLAGS (VAESGCM_COMMON_CIPHER_FLAG | EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV) # define VAESGCM_FLAG \ (VAESGCM_FLAGS | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER | \ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY) # define vaesgcm_data(ctx) ((vaesgcm_ctx*)EVP_CIPHER_CTX_get_cipher_data(ctx)) # pragma pack(push, 16) typedef struct vaesgcm_ctx_t { struct gcm_key_data key_data; struct gcm_context_data gcm_ctx; int init_flags; unsigned int ckey_set; unsigned char* tls_aad; int tls_aad_len; unsigned int tls_aad_set; unsigned char* tag; unsigned char* calculated_tag; int tag_len; unsigned int tag_set; unsigned int tag_calculated; unsigned char* iv; unsigned char* next_iv; int iv_len; unsigned int iv_set; int iv_gen; } __attribute__((aligned(64))) vaesgcm_ctx; # pragma pack(pop) #ifdef QAT_OPENSSL_PROVIDER int vaesgcm_ciphers_init(void *ctx, const unsigned char* inkey, const unsigned char* iv, int enc); int vaesgcm_ciphers_ctrl(void* ctx, int type, int arg, void* ptr); int vaesgcm_ciphers_do_cipher(void *ctx, unsigned char* out, size_t *padlen, const unsigned char* in, size_t len); int vaesgcm_ciphers_cleanup(void* ctx); #else int vaesgcm_ciphers_init(EVP_CIPHER_CTX *ctx, const unsigned char* inkey, const unsigned char* iv, int enc); int vaesgcm_ciphers_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char* out, const unsigned char* in, size_t len); int vaesgcm_ciphers_ctrl(EVP_CIPHER_CTX* ctx, int type, int arg, void* ptr); int vaesgcm_ciphers_cleanup(EVP_CIPHER_CTX* ctx); #endif int vaesgcm_init_ipsec_mb_mgr(void); void vaesgcm_free_ipsec_mb_mgr(void); void qat_imb_aes_gcm_precomp(int nid, IMB_MGR *ipsec_mgr, const void *key, struct gcm_key_data *key_data_ptr); void qat_imb_aes_gcm_init_var_iv(int nid, IMB_MGR *ipsec_mgr, struct gcm_key_data *key_data_ptr, struct gcm_context_data *context_data, const uint8_t *iv, const uint64_t iv_len, const uint8_t *aad, const uint64_t aad_len); void qat_imb_aes_gcm_enc_update(int nid, IMB_MGR *ipsec_mgr, struct gcm_key_data *key_data_ptr, struct gcm_context_data *context_data, uint8_t *out, const uint8_t *in, uint64_t len); void qat_imb_aes_gcm_dec_update(int nid, IMB_MGR *ipsec_mgr, struct gcm_key_data *key_data_ptr, struct gcm_context_data *context_data, uint8_t *out, const uint8_t *in, uint64_t len); void qat_imb_aes_gcm_enc_finalize(int nid, IMB_MGR *ipsec_mgr, const struct gcm_key_data *key_data_ptr, struct gcm_context_data *context_data, uint8_t *auth_tag, uint64_t auth_tag_len); void qat_imb_aes_gcm_dec_finalize(int nid, IMB_MGR *ipsec_mgr, const struct gcm_key_data *key_data_ptr, struct gcm_context_data *context_data, uint8_t *auth_tag, uint64_t auth_tag_len); #endif /* QAT_SW_GCM_H */ qatengine-1.9.0/qat_sw_init.c000066400000000000000000000432561500416242000161650ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_init.c * * This file provides an Multibuff initialization functions. * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Standard Includes */ #include #include #include #include #include #include #include # ifndef __FreeBSD__ #include # endif #include #include #include #include #include /* Local Includes */ #include "e_qat.h" #include "qat_sw_polling.h" #include "qat_sw_rsa.h" #include "qat_sw_ecx.h" #include "qat_sw_ec.h" #include "qat_sw_sm3.h" #ifndef QAT_BORINGSSL #include "qat_sw_sm4_cbc.h" #endif /* QAT_BORINGSSL */ #include "qat_sw_request.h" #include "qat_sw_freelist.h" #include "qat_sw_queue.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" /* OpenSSL Includes */ #include #include #include void mb_thread_local_destructor(void *tlv_ptr) { mb_thread_data *tlv = (mb_thread_data *)tlv_ptr; if (tlv == NULL) return; DEBUG("Thread local Destructor\n"); tlv->keep_polling = 0; if (!enable_external_polling) { if (qat_join_thread(tlv->polling_thread, NULL) != 0) WARN("Polling thread join failed\n"); } #ifdef ENABLE_QAT_SW_RSA QAT_SW_CLEANUP(rsa2k_priv, rsa_priv_op_data, tlv->rsa2k_priv_queue); QAT_SW_CLEANUP(rsa2k_pub, rsa_pub_op_data, tlv->rsa2k_pub_queue); QAT_SW_CLEANUP(rsa3k_priv, rsa_priv_op_data, tlv->rsa3k_priv_queue); QAT_SW_CLEANUP(rsa3k_pub, rsa_pub_op_data, tlv->rsa3k_pub_queue); QAT_SW_CLEANUP(rsa4k_priv, rsa_priv_op_data, tlv->rsa4k_priv_queue); QAT_SW_CLEANUP(rsa4k_pub, rsa_pub_op_data, tlv->rsa4k_pub_queue); if (tlv->rsa_priv_freelist) mb_flist_rsa_priv_cleanup(tlv->rsa_priv_freelist); if (tlv->rsa_pub_freelist) mb_flist_rsa_pub_cleanup(tlv->rsa_pub_freelist); #endif #ifdef ENABLE_QAT_SW_ECX QAT_SW_CLEANUP(x25519_keygen, x25519_keygen_op_data, tlv->x25519_keygen_queue); QAT_SW_CLEANUP(x25519_derive, x25519_derive_op_data, tlv->x25519_derive_queue); if (tlv->x25519_keygen_freelist) mb_flist_x25519_keygen_cleanup(tlv->x25519_keygen_freelist); if (tlv->x25519_derive_freelist) mb_flist_x25519_derive_cleanup(tlv->x25519_derive_freelist); #endif #ifdef ENABLE_QAT_SW_ECDSA QAT_SW_CLEANUP(ecdsap256_sign, ecdsa_sign_op_data, tlv->ecdsap256_sign_queue); QAT_SW_CLEANUP(ecdsap256_sign_setup, ecdsa_sign_setup_op_data,tlv->ecdsap256_sign_setup_queue); QAT_SW_CLEANUP(ecdsap256_sign_sig, ecdsa_sign_sig_op_data, tlv->ecdsap256_sign_sig_queue); QAT_SW_CLEANUP(ecdsap256_verify, ecdsa_verify_op_data, tlv->ecdsap256_verify_queue); QAT_SW_CLEANUP(ecdsap384_sign, ecdsa_sign_op_data, tlv->ecdsap384_sign_queue); QAT_SW_CLEANUP(ecdsap384_sign_setup, ecdsa_sign_setup_op_data, tlv->ecdsap384_sign_setup_queue); QAT_SW_CLEANUP(ecdsap384_sign_sig, ecdsa_sign_sig_op_data,tlv->ecdsap384_sign_sig_queue); QAT_SW_CLEANUP(ecdsap384_verify, ecdsa_verify_op_data,tlv->ecdsap384_verify_queue); if (tlv->ecdsa_sign_freelist) mb_flist_ecdsa_sign_cleanup(tlv->ecdsa_sign_freelist); if (tlv->ecdsa_sign_setup_freelist) mb_flist_ecdsa_sign_setup_cleanup(tlv->ecdsa_sign_setup_freelist); if (tlv->ecdsa_sign_sig_freelist) mb_flist_ecdsa_sign_sig_cleanup(tlv->ecdsa_sign_sig_freelist); if (tlv->ecdsa_verify_freelist) mb_flist_ecdsa_verify_cleanup(tlv->ecdsa_verify_freelist); #endif #ifdef ENABLE_QAT_SW_SM2 QAT_SW_CLEANUP(ecdsa_sm2_sign, ecdsa_sm2_sign_op_data, tlv->ecdsa_sm2_sign_queue); QAT_SW_CLEANUP(ecdsa_sm2_verify, ecdsa_sm2_verify_op_data, tlv->ecdsa_sm2_verify_queue); if (tlv->ecdsa_sm2_sign_freelist) mb_flist_ecdsa_sm2_sign_cleanup(tlv->ecdsa_sm2_sign_freelist); if (tlv->ecdsa_sm2_verify_freelist) mb_flist_ecdsa_sm2_verify_cleanup(tlv->ecdsa_sm2_verify_freelist); #endif #ifdef ENABLE_QAT_SW_ECDH QAT_SW_CLEANUP(ecdhp256_keygen, ecdh_keygen_op_data, tlv->ecdhp256_keygen_queue); QAT_SW_CLEANUP(ecdhp256_compute, ecdh_compute_op_data, tlv->ecdhp256_compute_queue); QAT_SW_CLEANUP(ecdhp384_keygen, ecdh_keygen_op_data, tlv->ecdhp384_keygen_queue); QAT_SW_CLEANUP(ecdhp384_compute, ecdh_compute_op_data, tlv->ecdhp384_compute_queue); QAT_SW_CLEANUP(sm2ecdh_keygen, ecdh_keygen_op_data, tlv->sm2ecdh_keygen_queue); QAT_SW_CLEANUP(sm2ecdh_compute, ecdh_compute_op_data, tlv->sm2ecdh_compute_queue); if (tlv->ecdh_keygen_freelist) mb_flist_ecdh_keygen_cleanup(tlv->ecdh_keygen_freelist); if (tlv->ecdh_compute_freelist) mb_flist_ecdh_compute_cleanup(tlv->ecdh_compute_freelist); #endif #ifdef ENABLE_QAT_SW_SM3 QAT_SW_CLEANUP(sm3_init, sm3_init_op_data, tlv->sm3_init_queue); QAT_SW_CLEANUP(sm3_update, sm3_update_op_data, tlv->sm3_update_queue); QAT_SW_CLEANUP(sm3_final, sm3_final_op_data, tlv->sm3_final_queue); if (tlv->sm3_init_freelist) mb_flist_sm3_init_cleanup(tlv->sm3_init_freelist); if (tlv->sm3_update_freelist) mb_flist_sm3_update_cleanup(tlv->sm3_update_freelist); if (tlv->sm3_final_freelist) mb_flist_sm3_final_cleanup(tlv->sm3_final_freelist); #endif #ifdef ENABLE_QAT_SW_SM4_CBC QAT_SW_CLEANUP(sm4_cbc_cipher, sm4_cbc_cipher_op_data, tlv->sm4_cbc_cipher_queue); QAT_SW_CLEANUP(sm4_cbc_cipher_dec, sm4_cbc_cipher_op_data, tlv->sm4_cbc_cipher_dec_queue); if (tlv->sm4_cbc_cipher_freelist) mb_flist_sm4_cbc_cipher_cleanup(tlv->sm4_cbc_cipher_freelist); if (tlv->sm4_cbc_cipher_dec_freelist) mb_flist_sm4_cbc_cipher_cleanup(tlv->sm4_cbc_cipher_dec_freelist); #endif #ifdef ENABLE_QAT_SW_SM4_GCM QAT_SW_CLEANUP(sm4_gcm_encrypt, sm4_gcm_encrypt_op_data, tlv->sm4_gcm_encrypt_queue); QAT_SW_CLEANUP(sm4_gcm_decrypt, sm4_gcm_decrypt_op_data, tlv->sm4_gcm_decrypt_queue); if (tlv->sm4_gcm_encrypt_freelist) mb_flist_sm4_gcm_encrypt_cleanup(tlv->sm4_gcm_encrypt_freelist); if (tlv->sm4_gcm_decrypt_freelist) mb_flist_sm4_gcm_decrypt_cleanup(tlv->sm4_gcm_decrypt_freelist); #endif #ifdef ENABLE_QAT_SW_SM4_CCM QAT_SW_CLEANUP(sm4_ccm_encrypt, sm4_ccm_encrypt_op_data, tlv->sm4_ccm_encrypt_queue); QAT_SW_CLEANUP(sm4_ccm_decrypt, sm4_ccm_decrypt_op_data, tlv->sm4_ccm_decrypt_queue); if (tlv->sm4_ccm_encrypt_freelist) mb_flist_sm4_ccm_encrypt_cleanup(tlv->sm4_ccm_encrypt_freelist); if (tlv->sm4_ccm_decrypt_freelist) mb_flist_sm4_ccm_decrypt_cleanup(tlv->sm4_ccm_decrypt_freelist); #endif sem_destroy(&tlv->mb_polling_thread_sem); OPENSSL_free(tlv); if (pthread_key_delete(mb_thread_key) != 0) { WARN("Failed to delete pthread key.\n"); } } mb_thread_data* mb_check_thread_local(void) { mb_thread_data *tlv = (mb_thread_data *)pthread_getspecific(mb_thread_key); if (tlv != NULL) { return tlv; } tlv = OPENSSL_zalloc(sizeof(mb_thread_data)); if (tlv != NULL) { DEBUG("TLV NULL allocate memory and create polling thread\n"); /* Create Multibuffer Freelists and Queues*/ #ifdef ENABLE_QAT_SW_RSA if (((tlv->rsa_priv_freelist = mb_flist_rsa_priv_create()) == NULL) || ((tlv->rsa_pub_freelist = mb_flist_rsa_pub_create()) == NULL) || ((tlv->rsa2k_priv_queue = mb_queue_rsa2k_priv_create()) == NULL) || ((tlv->rsa2k_pub_queue = mb_queue_rsa2k_pub_create()) == NULL) || ((tlv->rsa3k_priv_queue = mb_queue_rsa3k_priv_create()) == NULL) || ((tlv->rsa3k_pub_queue = mb_queue_rsa3k_pub_create()) == NULL) || ((tlv->rsa4k_priv_queue = mb_queue_rsa4k_priv_create()) == NULL) || ((tlv->rsa4k_pub_queue = mb_queue_rsa4k_pub_create()) == NULL)) { WARN("Failure to allocate RSA Freelist and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_ECX if (((tlv->x25519_keygen_freelist = mb_flist_x25519_keygen_create()) == NULL) || ((tlv->x25519_derive_freelist = mb_flist_x25519_derive_create()) == NULL) || ((tlv->x25519_keygen_queue = mb_queue_x25519_keygen_create()) == NULL) || ((tlv->x25519_derive_queue = mb_queue_x25519_derive_create()) == NULL)) { WARN("Failure to allocate X25519 Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_ECDSA if(((tlv->ecdsa_sign_freelist = mb_flist_ecdsa_sign_create()) == NULL) || ((tlv->ecdsa_sign_setup_freelist = mb_flist_ecdsa_sign_setup_create()) == NULL) || ((tlv->ecdsa_sign_sig_freelist = mb_flist_ecdsa_sign_sig_create()) == NULL) || ((tlv->ecdsa_verify_freelist = mb_flist_ecdsa_verify_create()) == NULL) || ((tlv->ecdsap256_sign_queue= mb_queue_ecdsap256_sign_create()) == NULL) || ((tlv->ecdsap256_sign_setup_queue= mb_queue_ecdsap256_sign_setup_create()) == NULL) || ((tlv->ecdsap256_sign_sig_queue= mb_queue_ecdsap256_sign_sig_create()) == NULL) || ((tlv->ecdsap256_verify_queue= mb_queue_ecdsap256_verify_create()) == NULL) || ((tlv->ecdsap384_sign_queue= mb_queue_ecdsap384_sign_create()) == NULL) || ((tlv->ecdsap384_sign_setup_queue= mb_queue_ecdsap384_sign_setup_create()) == NULL) || ((tlv->ecdsap384_sign_sig_queue= mb_queue_ecdsap384_sign_sig_create()) == NULL) || ((tlv->ecdsap384_verify_queue= mb_queue_ecdsap384_verify_create()) == NULL)) { WARN("Failure to allocate ECDSA P256/P384 Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_ECDH if(((tlv->ecdh_keygen_freelist = mb_flist_ecdh_keygen_create()) == NULL) || ((tlv->ecdh_compute_freelist = mb_flist_ecdh_compute_create()) == NULL) || ((tlv->ecdhp256_keygen_queue= mb_queue_ecdhp256_keygen_create()) == NULL) || ((tlv->ecdhp256_compute_queue= mb_queue_ecdhp256_compute_create()) == NULL) || ((tlv->ecdhp384_keygen_queue= mb_queue_ecdhp384_keygen_create()) == NULL) || ((tlv->ecdhp384_compute_queue= mb_queue_ecdhp384_compute_create()) == NULL) || ((tlv->sm2ecdh_keygen_queue= mb_queue_sm2ecdh_keygen_create()) == NULL) || ((tlv->sm2ecdh_compute_queue= mb_queue_sm2ecdh_compute_create()) == NULL)) { WARN("Failure to allocate ECDH P256/P384/SM2 Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_SM2 if(((tlv->ecdsa_sm2_sign_freelist = mb_flist_ecdsa_sm2_sign_create()) == NULL) || ((tlv->ecdsa_sm2_verify_freelist = mb_flist_ecdsa_sm2_verify_create()) == NULL) || ((tlv->ecdsa_sm2_sign_queue= mb_queue_ecdsa_sm2_sign_create()) == NULL) || ((tlv->ecdsa_sm2_verify_queue= mb_queue_ecdsa_sm2_verify_create()) == NULL)) { WARN("Failure to allocate ECDSA SM2 Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_SM3 if(((tlv->sm3_init_freelist = mb_flist_sm3_init_create()) == NULL) || ((tlv->sm3_update_freelist = mb_flist_sm3_update_create()) == NULL) || ((tlv->sm3_final_freelist = mb_flist_sm3_final_create()) == NULL) || ((tlv->sm3_init_queue= mb_queue_sm3_init_create()) == NULL) || ((tlv->sm3_update_queue= mb_queue_sm3_update_create()) == NULL) || ((tlv->sm3_final_queue= mb_queue_sm3_final_create()) == NULL) ) { WARN("Failure to allocate SM3 Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_SM4_CBC if(((tlv->sm4_cbc_cipher_freelist = mb_flist_sm4_cbc_cipher_create()) == NULL) || ((tlv->sm4_cbc_cipher_dec_freelist = mb_flist_sm4_cbc_cipher_create()) == NULL) || ((tlv->sm4_cbc_cipher_queue= mb_queue_sm4_cbc_cipher_create()) == NULL) || ((tlv->sm4_cbc_cipher_dec_queue= mb_queue_sm4_cbc_cipher_create()) == NULL) ) { WARN("Failure to allocate SM4_CBC Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_SM4_GCM if(((tlv->sm4_gcm_encrypt_freelist = mb_flist_sm4_gcm_encrypt_create()) == NULL) || ((tlv->sm4_gcm_decrypt_freelist = mb_flist_sm4_gcm_decrypt_create()) == NULL) || ((tlv->sm4_gcm_encrypt_queue= mb_queue_sm4_gcm_encrypt_create()) == NULL) || ((tlv->sm4_gcm_decrypt_queue= mb_queue_sm4_gcm_decrypt_create()) == NULL) ) { WARN("Failure to allocate SM4_GCM Freelists and Queues\n"); goto err; } #endif #ifdef ENABLE_QAT_SW_SM4_CCM if(((tlv->sm4_ccm_encrypt_freelist = mb_flist_sm4_ccm_encrypt_create()) == NULL) || ((tlv->sm4_ccm_decrypt_freelist = mb_flist_sm4_ccm_decrypt_create()) == NULL) || ((tlv->sm4_ccm_encrypt_queue= mb_queue_sm4_ccm_encrypt_create()) == NULL) || ((tlv->sm4_ccm_decrypt_queue= mb_queue_sm4_ccm_decrypt_create()) == NULL) ) { WARN("Failure to allocate SM4_CCM Freelists and Queues\n"); goto err; } #endif if (!enable_external_polling) { /* Qat SW semaphore init. */ if (sem_init(&tlv->mb_polling_thread_sem, 0, 0) == -1) { WARN("sem_init failed!\n"); goto err; } tlv->keep_polling = 1; /* Create Polling thread */ if (qat_create_thread(&tlv->polling_thread, NULL, multibuff_timer_poll_func, tlv)) { WARN("Creation of polling thread failed\n"); goto err; } DEBUG("Polling thread created %lx, tlv %p\n", (uintptr_t)tlv->polling_thread, tlv); } else { /* External Polling assign it to the global pointer */ mb_tlv = tlv; } pthread_setspecific(mb_thread_key, (void *)tlv); } return tlv; err: mb_thread_local_destructor(tlv); return NULL; } int qat_sw_init(ENGINE *e) { int err = 0; DEBUG("QAT_SW initialization\n"); DEBUG("- External polling: %s\n", enable_external_polling ? "ON": "OFF"); DEBUG("- Heuristic polling: %s\n", enable_heuristic_polling ? "ON": "OFF"); INITIALISE_RDTSC_CLOCKS(); e_check = BN_new(); if (NULL == e_check) { WARN("Failure to allocate e_check\n"); QATerr(QAT_F_QAT_SW_INIT, QAT_R_ALLOC_E_CHECK_FAILURE); qat_engine_finish(e); return 0; } BN_add_word(e_check, 65537); if ((err = pthread_key_create(&mb_thread_key, mb_thread_local_destructor)) != 0) { WARN("pthread_key_create failed %s\n", strerror(err)); QATerr(QAT_F_QAT_SW_INIT, QAT_R_PTHREAD_CREATE_FAILURE); qat_engine_finish(e); return 0; } return 1; } int qat_sw_finish_int(ENGINE *e, int reset_globals) { int ret = 1; mb_thread_data *tlv; DEBUG("---- QAT_SW Finishing...\n\n"); if (e_check != NULL) { BN_free(e_check); e_check = NULL; } PRINT_RDTSC_AVERAGES(); tlv = (mb_thread_data *)pthread_getspecific(mb_thread_key); mb_thread_local_destructor(tlv); return ret; } qatengine-1.9.0/qat_sw_ipsec_inf.c000066400000000000000000000224021500416242000171470ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_ipsec_inf.c * * This file provides wrapper functions that calls intel-ipsec APIs based * on the NID * ****************************************************************************/ /* Standard Includes */ #include /* Local Includes */ #include "qat_sw_gcm.h" #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) int qat_imb_sha2(int nid, IMB_MGR *ipsec_mgr, unsigned char hash_type, const void *data, size_t len, unsigned char *out); #endif void qat_imb_aes_gcm_precomp(int nid, IMB_MGR *ipsec_mgr, const void *key, struct gcm_key_data *key_data_ptr) { switch (nid) { case NID_aes_128_gcm: aes_keyexp_128_enc_avx512(key, key_data_ptr); IMB_AES128_GCM_PRECOMP(ipsec_mgr, key_data_ptr); break; case NID_aes_192_gcm: aes_keyexp_192_enc_avx512(key, key_data_ptr); IMB_AES192_GCM_PRECOMP(ipsec_mgr, key_data_ptr); break; case NID_aes_256_gcm: aes_keyexp_256_enc_avx512(key, key_data_ptr); IMB_AES256_GCM_PRECOMP(ipsec_mgr, key_data_ptr); break; } } void qat_imb_aes_gcm_init_var_iv(int nid, IMB_MGR *ipsec_mgr, struct gcm_key_data *key_data_ptr, struct gcm_context_data *gcm_ctx_ptr, const uint8_t *iv, const uint64_t iv_len, const uint8_t *aad, const uint64_t aad_len) { switch (nid) { case NID_aes_128_gcm: IMB_AES128_GCM_INIT_VAR_IV(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, iv, iv_len, aad, aad_len); break; case NID_aes_192_gcm: IMB_AES192_GCM_INIT_VAR_IV(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, iv, iv_len, aad, aad_len); break; case NID_aes_256_gcm: IMB_AES256_GCM_INIT_VAR_IV(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, iv, iv_len, aad, aad_len); break; } } void qat_imb_aes_gcm_enc_update(int nid, IMB_MGR *ipsec_mgr, struct gcm_key_data *key_data_ptr, struct gcm_context_data *gcm_ctx_ptr, uint8_t *out, const uint8_t *in, uint64_t len) { switch (nid) { case NID_aes_128_gcm: IMB_AES128_GCM_ENC_UPDATE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); break; case NID_aes_192_gcm: IMB_AES192_GCM_ENC_UPDATE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); break; case NID_aes_256_gcm: IMB_AES256_GCM_ENC_UPDATE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); break; } } void qat_imb_aes_gcm_dec_update(int nid, IMB_MGR *ipsec_mgr, struct gcm_key_data *key_data_ptr, struct gcm_context_data *gcm_ctx_ptr, uint8_t *out, const uint8_t *in, uint64_t len) { switch (nid) { case NID_aes_128_gcm: IMB_AES128_GCM_DEC_UPDATE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); break; case NID_aes_192_gcm: IMB_AES192_GCM_DEC_UPDATE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); break; case NID_aes_256_gcm: IMB_AES256_GCM_DEC_UPDATE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, out, in, len); break; } } void qat_imb_aes_gcm_enc_finalize(int nid, IMB_MGR *ipsec_mgr, const struct gcm_key_data *key_data_ptr, struct gcm_context_data *gcm_ctx_ptr, uint8_t *auth_tag, uint64_t auth_tag_len) { switch (nid) { case NID_aes_128_gcm: IMB_AES128_GCM_ENC_FINALIZE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, auth_tag, auth_tag_len); break; case NID_aes_192_gcm: IMB_AES192_GCM_ENC_FINALIZE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, auth_tag, auth_tag_len); break; case NID_aes_256_gcm: IMB_AES256_GCM_ENC_FINALIZE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, auth_tag, auth_tag_len); break; } } void qat_imb_aes_gcm_dec_finalize(int nid, IMB_MGR *ipsec_mgr, const struct gcm_key_data *key_data_ptr, struct gcm_context_data *gcm_ctx_ptr, uint8_t *auth_tag, uint64_t auth_tag_len) { switch (nid) { case NID_aes_128_gcm: IMB_AES128_GCM_DEC_FINALIZE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, auth_tag, auth_tag_len); break; case NID_aes_192_gcm: IMB_AES192_GCM_DEC_FINALIZE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, auth_tag, auth_tag_len); break; case NID_aes_256_gcm: IMB_AES256_GCM_DEC_FINALIZE(ipsec_mgr, key_data_ptr, gcm_ctx_ptr, auth_tag, auth_tag_len); break; } } #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) int qat_imb_sha2(int nid, IMB_MGR *ipsec_mgr, unsigned char hash_type, const void *data, size_t len, unsigned char *out) { switch (nid) { case NID_sha224: IMB_SHA224(ipsec_mgr, data, len, out); break; case NID_sha256: IMB_SHA256(ipsec_mgr, data, len, out); break; case NID_sha384: IMB_SHA384(ipsec_mgr, data, len, out); break; case NID_sha512: IMB_SHA512(ipsec_mgr, data, len, out); break; } return 0; } #endif qatengine-1.9.0/qat_sw_polling.c000066400000000000000000002757271500416242000167000ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_polling.c * * This file provides an implementation for multibuff polling in QAT engine * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Standard Includes */ #include #include #include #include #include #include /* Local Includes */ #include "e_qat.h" #include "qat_sw_polling.h" #include "qat_sw_rsa.h" #include "qat_sw_ecx.h" #include "qat_sw_ec.h" #include "qat_utils.h" #include "qat_sw_sm3.h" #ifndef QAT_BORINGSSL #include "qat_sw_sm4_cbc.h" #include "qat_sw_sm4_gcm.h" #include "qat_sw_sm4_ccm.h" #endif /* QAT_BORINGSSL */ /* OpenSSL Includes */ #include #define QAT_SW_NUM_EVENT_RETRIES 5 #define QAT_SW_NSEC_PER_SEC 1000000000L #define QAT_SW_TIMEOUT_LEVEL_1 1 #define QAT_SW_TIMEOUT_LEVEL_2 2 #define QAT_SW_TIMEOUT_LEVEL_3 3 #define QAT_SW_TIMEOUT_LEVEL_4 4 #define QAT_SW_TIMEOUT_LEVEL_5 5 #define QAT_SW_TIMEOUT_LEVEL_6 6 #define QAT_SW_TIMEOUT_LEVEL_7 7 #define QAT_SW_TIMEOUT_LEVEL_MIN QAT_SW_TIMEOUT_LEVEL_1 #define QAT_SW_TIMEOUT_LEVEL_MAX QAT_SW_TIMEOUT_LEVEL_7 #define QAT_SW_POLL_TIMEOUT_NSEC_L1 200000000 #define QAT_SW_POLL_TIMEOUT_NSEC_L2 100000000 #define QAT_SW_POLL_TIMEOUT_NSEC_L3 50000000 #define QAT_SW_POLL_TIMEOUT_NSEC_L4 25000000 #define QAT_SW_POLL_TIMEOUT_NSEC_L5 16666667 #define QAT_SW_POLL_TIMEOUT_NSEC_L6 12500000 #define QAT_SW_POLL_TIMEOUT_NSEC_L7 10000000 /* default 100th sec */ #ifndef QAT_SW_POLL_TIMEOUT_NSEC # define QAT_SW_POLL_TIMEOUT_NSEC QAT_SW_POLL_TIMEOUT_NSEC_L7 #endif struct timespec mb_poll_timeout_time = { 0, QAT_SW_POLL_TIMEOUT_NSEC }; unsigned int mb_timeout_level = QAT_SW_TIMEOUT_LEVEL_MAX; /* RSA */ struct timespec rsa2k_priv_previous_time = { 0 }; struct timespec rsa2k_pub_previous_time = { 0 }; struct timespec rsa3k_priv_previous_time = { 0 }; struct timespec rsa3k_pub_previous_time = { 0 }; struct timespec rsa4k_priv_previous_time = { 0 }; struct timespec rsa4k_pub_previous_time = { 0 }; mb_req_rates mb_rsa2k_priv_req_rates = { 0 }; mb_req_rates mb_rsa2k_pub_req_rates = { 0 }; mb_req_rates mb_rsa3k_priv_req_rates = { 0 }; mb_req_rates mb_rsa3k_pub_req_rates = { 0 }; mb_req_rates mb_rsa4k_priv_req_rates = { 0 }; mb_req_rates mb_rsa4k_pub_req_rates = { 0 }; /* X25519 */ struct timespec x25519_keygen_previous_time = { 0 }; struct timespec x25519_derive_previous_time = { 0 }; mb_req_rates mb_x25519_keygen_req_rates = { 0 }; mb_req_rates mb_x25519_derive_req_rates = { 0 }; /* ECDSA p256 */ struct timespec ecdsap256_sign_previous_time = { 0 }; struct timespec ecdsap256_sign_setup_previous_time = { 0 }; struct timespec ecdsap256_sign_sig_previous_time = { 0 }; struct timespec ecdsap256_verify_previous_time = { 0 }; mb_req_rates mb_ecdsap256_sign_req_rates = { 0 }; mb_req_rates mb_ecdsap256_sign_setup_req_rates = { 0 }; mb_req_rates mb_ecdsap256_sign_sig_req_rates = { 0 }; mb_req_rates mb_ecdsap256_verify_req_rates = { 0 }; /* ECDSA p384 */ struct timespec ecdsap384_sign_previous_time = { 0 }; struct timespec ecdsap384_sign_setup_previous_time = { 0 }; struct timespec ecdsap384_sign_sig_previous_time = { 0 }; struct timespec ecdsap384_verify_previous_time = { 0 }; mb_req_rates mb_ecdsap384_sign_req_rates = { 0 }; mb_req_rates mb_ecdsap384_sign_setup_req_rates = { 0 }; mb_req_rates mb_ecdsap384_sign_sig_req_rates = { 0 }; mb_req_rates mb_ecdsap384_verify_req_rates = { 0 }; /* SM2 ECDSA */ struct timespec ecdsa_sm2_sign_previous_time = { 0 }; struct timespec ecdsa_sm2_verify_previous_time = { 0 }; mb_req_rates mb_ecdsa_sm2_sign_req_rates = { 0 }; mb_req_rates mb_ecdsa_sm2_verify_req_rates = { 0 }; /* ECDH p256 */ struct timespec ecdhp256_keygen_previous_time = { 0 }; struct timespec ecdhp256_compute_previous_time = { 0 }; mb_req_rates mb_ecdhp256_keygen_req_rates = { 0 }; mb_req_rates mb_ecdhp256_compute_req_rates = { 0 }; /* ECDH p384 */ struct timespec ecdhp384_keygen_previous_time = { 0 }; struct timespec ecdhp384_compute_previous_time = { 0 }; mb_req_rates mb_ecdhp384_keygen_req_rates = { 0 }; mb_req_rates mb_ecdhp384_compute_req_rates = { 0 }; /* ECDH sm2 */ struct timespec sm2ecdh_keygen_previous_time = { 0 }; struct timespec sm2ecdh_compute_previous_time = { 0 }; mb_req_rates mb_sm2ecdh_keygen_req_rates = { 0 }; mb_req_rates mb_sm2ecdh_compute_req_rates = { 0 }; /* SM3 */ struct timespec sm3_init_previous_time = { 0 }; struct timespec sm3_update_previous_time = { 0 }; struct timespec sm3_final_previous_time = { 0 }; mb_req_rates mb_sm3_init_req_rates = { 0 }; mb_req_rates mb_sm3_update_req_rates = { 0 }; mb_req_rates mb_sm3_final_req_rates = { 0 }; /* SM4-CBC */ struct timespec sm4_cbc_cipher_previous_time = { 0 }; struct timespec sm4_cbc_cipher_dec_previous_time = { 0 }; mb_req_rates mb_sm4_cbc_cipher_req_rates = { 0 }; mb_req_rates mb_sm4_cbc_cipher_dec_req_rates = { 0 }; /* SM4-GCM */ struct timespec sm4_gcm_encrypt_previous_time = { 0 }; struct timespec sm4_gcm_decrypt_previous_time = { 0 }; mb_req_rates mb_sm4_gcm_encrypt_req_rates = { 0 }; mb_req_rates mb_sm4_gcm_decrypt_req_rates = { 0 }; /* SM4-CCM */ struct timespec sm4_ccm_encrypt_previous_time = { 0 }; struct timespec sm4_ccm_decrypt_previous_time = { 0 }; mb_req_rates mb_sm4_ccm_encrypt_req_rates = { 0 }; mb_req_rates mb_sm4_ccm_decrypt_req_rates = { 0 }; #if defined(ENABLE_QAT_SW_RSA) || defined(ENABLE_QAT_SW_ECX) \ || defined(ENABLE_QAT_SW_ECDSA) || defined(ENABLE_QAT_SW_ECDH) \ || defined(ENABLE_QAT_SW_SM3) || defined(ENABLE_QAT_SW_SM4_CBC) \ || defined(ENABLE_QAT_SW_SM4_GCM) || defined(ENABLE_QAT_SW_SM4_CCM) void multibuff_set_normalized_timespec(struct timespec *ts, time_t sec, long long nsec) { while (nsec >= QAT_SW_NSEC_PER_SEC) { /* * The following asm() prevents the compiler from * optimising this loop into a modulo operation. See * also __iter_div_u64_rem() in include/linux/time.h */ asm("" : "+rm"(nsec)); nsec -= QAT_SW_NSEC_PER_SEC; ++sec; } while (nsec < 0) { asm("" : "+rm"(nsec)); nsec += QAT_SW_NSEC_PER_SEC; --sec; } ts->tv_sec = sec; ts->tv_nsec = nsec; } static int multibuff_timespec_compare(const struct timespec *lhs, const struct timespec *rhs) { if (lhs->tv_sec < rhs->tv_sec) return -1; if (lhs->tv_sec > rhs->tv_sec) return 1; return lhs->tv_nsec - rhs->tv_nsec; } static struct timespec multibuff_timespec_sub(struct timespec lhs, struct timespec rhs) { struct timespec ts_delta; multibuff_set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec, lhs.tv_nsec - rhs.tv_nsec); return ts_delta; } static int multibuff_poll_check_for_timeout(struct timespec timeout_time, struct timespec previous_time, struct timespec current_time) { struct timespec diff_time; /* If someone has changed the system time so the current time is smaller than the previous time or we have wrapped round then flag a timeout regardless */ if (multibuff_timespec_compare(¤t_time, &previous_time) < 0) return 1; /* Calculate the difference between the current time and previous time */ diff_time = multibuff_timespec_sub(current_time, previous_time); /* Check whether the difference is bigger than or equal to the timeout time if it is we have timed out */ if (multibuff_timespec_compare(&diff_time, &timeout_time) >= 0) return 1; return 0; } #endif void multibuff_get_timeout_time(struct timespec *timeout_time, unsigned int timeout_level) { timeout_time->tv_sec = 0; switch (timeout_level) { case QAT_SW_TIMEOUT_LEVEL_1: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L1; break; case QAT_SW_TIMEOUT_LEVEL_2: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L2; break; case QAT_SW_TIMEOUT_LEVEL_3: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L3; break; case QAT_SW_TIMEOUT_LEVEL_4: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L4; break; case QAT_SW_TIMEOUT_LEVEL_5: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L5; break; case QAT_SW_TIMEOUT_LEVEL_6: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L6; break; case QAT_SW_TIMEOUT_LEVEL_7: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L7; break; default: timeout_time->tv_nsec = QAT_SW_POLL_TIMEOUT_NSEC_L7; break; } } #ifdef QAT_SW_HEURISTIC_TIMEOUT void multibuff_init_req_rates(mb_req_rates * req_rates) { req_rates->req_this_period = 0; multibuff_get_timeout_time(&mb_poll_timeout_time, mb_timeout_level); clock_gettime(clock_id, &req_rates->previous_time); req_rates->current_time = req_rates->previous_time; } unsigned int multibuff_calc_timeout_level(unsigned int timeout_level) { if (((mb_rsa2k_priv_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_rsa2k_pub_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_rsa3k_priv_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_rsa3k_pub_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_rsa4k_priv_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_rsa4k_pub_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_x25519_keygen_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_x25519_derive_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap256_sign_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap256_sign_setup_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap256_sign_sig_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap256_verify_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap384_sign_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap384_sign_setup_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap384_sign_sig_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsap384_verify_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsa_sm2_sign_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdsa_sm2_verify_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdhp256_keygen_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdhp256_compute_req_rates.req_this_period < MULTIBUFF_MIN_BATCH)|| (mb_ecdhp384_keygen_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_ecdhp384_compute_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm2ecdh_keygen_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm2ecdh_compute_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm3_init_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm3_update_req_rates.req_this_period < MULTIBUFF_MIN_BATCH)|| (mb_sm3_final_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm4_cbc_cipher_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm4_cbc_cipher_dec_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm4_gcm_encrypt_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm4_gcm_decrypt_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm4_ccm_encrypt_req_rates.req_this_period < MULTIBUFF_MIN_BATCH) || (mb_sm4_ccm_decrypt_req_rates.req_this_period < MULTIBUFF_MIN_BATCH)) && (timeout_level > QAT_SW_TIMEOUT_LEVEL_MIN)) return timeout_level-1; if (((mb_rsa2k_priv_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_rsa2k_pub_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_rsa3k_priv_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_rsa3k_pub_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_rsa4k_priv_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_rsa4k_pub_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_x25519_keygen_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_x25519_derive_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap256_sign_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap256_sign_setup_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap256_sign_sig_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap256_verify_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdhp256_keygen_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdhp256_compute_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap384_sign_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap384_sign_setup_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap384_sign_sig_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsap384_verify_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsa_sm2_sign_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdsa_sm2_verify_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdhp256_keygen_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdhp256_compute_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2)|| (mb_ecdhp384_keygen_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_ecdhp384_compute_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm2ecdh_keygen_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm2ecdh_compute_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm3_init_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2)|| (mb_sm3_update_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm3_final_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm4_cbc_cipher_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm4_cbc_cipher_dec_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm4_gcm_encrypt_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm4_gcm_decrypt_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm4_ccm_encrypt_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2) || (mb_sm4_ccm_decrypt_req_rates.req_this_period > MULTIBUFF_MAX_BATCH*2)) && (timeout_level < QAT_SW_TIMEOUT_LEVEL_MAX)) return timeout_level+1; return timeout_level; } void multibuff_update_req_timeout(mb_req_rates * req_rates) { unsigned int existing_timeout_level; clock_gettime(clock_id, &req_rates->current_time); if (multibuff_poll_check_for_timeout(mb_poll_timeout_time, req_rates->previous_time, req_rates->current_time) == 0) { DEBUG("Currently a timeout period has not elapsed\n"); return; } existing_timeout_level = mb_timeout_level; mb_timeout_level = multibuff_calc_timeout_level(mb_timeout_level); if (mb_timeout_level != existing_timeout_level) { multibuff_get_timeout_time(&mb_poll_timeout_time, mb_timeout_level); DEBUG("Adjusting timeout level to: %d\n", mb_timeout_level); } req_rates->req_this_period = 0; req_rates->previous_time = req_rates->current_time; } #endif void *multibuff_timer_poll_func(void *thread_ptr) { int sig = 0; unsigned int eintr_count = 0; mb_thread_data *tlv = (mb_thread_data *)thread_ptr; struct timespec mb_polling_abs_timeout; #if defined(ENABLE_QAT_SW_RSA) || defined(ENABLE_QAT_SW_ECX) \ || defined(ENABLE_QAT_SW_ECDSA) || defined(ENABLE_QAT_SW_ECDH) \ || defined(ENABLE_QAT_SW_SM3) || defined(ENABLE_QAT_SW_SM4_CBC) \ || defined(ENABLE_QAT_SW_SM4_GCM) || defined(ENABLE_QAT_SW_SM4_CCM) unsigned int submission_count = 0; #endif cleared_to_start = 1; #ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_init_req_rates(&mb_rsa2k_priv_req_rates); multibuff_init_req_rates(&mb_rsa2k_pub_req_rates); multibuff_init_req_rates(&mb_x25519_keygen_req_rates); multibuff_init_req_rates(&mb_x25519_derive_req_rates); multibuff_init_req_rates(&mb_ecdsap256_sign_req_rates); multibuff_init_req_rates(&mb_ecdsap256_sign_setup_req_rates); multibuff_init_req_rates(&mb_ecdsap256_sign_sig_req_rates); multibuff_init_req_rates(&mb_ecdsap256_verify_req_rates); multibuff_init_req_rates(&mb_ecdsap384_sign_req_rates); multibuff_init_req_rates(&mb_ecdsap384_sign_setup_req_rates); multibuff_init_req_rates(&mb_ecdsap384_sign_sig_req_rates); multibuff_init_req_rates(&mb_ecdsap384_verify_req_rates); multibuff_init_req_rates(&mb_ecdsa_sm2_sign_req_rates); multibuff_init_req_rates(&mb_ecdsa_sm2_verify_req_rates); multibuff_init_req_rates(&mb_ecdhp256_keygen_req_rates); multibuff_init_req_rates(&mb_ecdhp256_compute_req_rates); multibuff_init_req_rates(&mb_ecdhp384_keygen_req_rates); multibuff_init_req_rates(&mb_ecdhp384_compute_req_rates); multibuff_init_req_rates(&mb_sm2ecdh_keygen_req_rates); multibuff_init_req_rates(&mb_sm2ecdh_compute_req_rates); multibuff_init_req_rates(&mb_rsa3k_priv_req_rates); multibuff_init_req_rates(&mb_rsa3k_pub_req_rates); multibuff_init_req_rates(&mb_rsa4k_priv_req_rates); multibuff_init_req_rates(&mb_rsa4k_pub_req_rates); multibuff_init_req_rates(&mb_sm3_init_req_rates); multibuff_init_req_rates(&mb_sm3_update_req_rates); multibuff_init_req_rates(&mb_sm3_final_req_rates); multibuff_init_req_rates(&mb_sm4_cbc_cipher_req_rates); multibuff_init_req_rates(&mb_sm4_cbc_cipher_dec_req_rates); multibuff_init_req_rates(&mb_sm4_gcm_encrypt_req_rates); multibuff_init_req_rates(&mb_sm4_gcm_decrypt_req_rates); multibuff_init_req_rates(&mb_sm4_ccm_encrypt_req_rates); multibuff_init_req_rates(&mb_sm4_ccm_decrypt_req_rates); #endif DEBUG("Polling Timeout %ld tlv %p\n", mb_poll_timeout_time.tv_nsec, tlv); while (tlv->keep_polling && qat_sw_keep_polling) { get_sem_wait_abs_time(&mb_polling_abs_timeout, mb_poll_timeout_time); while ((sig = sem_timedwait(&tlv->mb_polling_thread_sem, &mb_polling_abs_timeout)) == -1 && errno == EINTR && eintr_count < QAT_SW_NUM_EVENT_RETRIES) { eintr_count++; } eintr_count = 0; if (unlikely(sig == -1)) { if (errno == ETIMEDOUT || errno == EINTR) { /* Deal with requests less than 8 */ #ifdef ENABLE_QAT_SW_RSA if (mb_queue_rsa2k_priv_get_size(tlv->rsa2k_priv_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_RSA_priv_reqs(tlv, RSA_2K_LENGTH); submission_count--; while ((mb_queue_rsa2k_priv_get_size(tlv->rsa2k_priv_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_RSA_priv_reqs(tlv, RSA_2K_LENGTH); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa2k_priv_req_rates); # endif if (mb_queue_rsa2k_pub_get_size(tlv->rsa2k_pub_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_RSA_pub_reqs(tlv, RSA_2K_LENGTH); submission_count--; while ((mb_queue_rsa2k_pub_get_size(tlv->rsa2k_pub_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_RSA_pub_reqs(tlv, RSA_2K_LENGTH); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa2k_pub_req_rates); # endif if (mb_queue_rsa3k_priv_get_size(tlv->rsa3k_priv_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_RSA_priv_reqs(tlv, RSA_3K_LENGTH); submission_count--; while ((mb_queue_rsa3k_priv_get_size(tlv->rsa3k_priv_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_RSA_priv_reqs(tlv, RSA_3K_LENGTH); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa3k_priv_req_rates); # endif if (mb_queue_rsa3k_pub_get_size(tlv->rsa3k_pub_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_RSA_pub_reqs(tlv, RSA_3K_LENGTH); submission_count--; while ((mb_queue_rsa3k_pub_get_size(tlv->rsa3k_pub_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_RSA_pub_reqs(tlv, RSA_3K_LENGTH); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa3k_pub_req_rates); # endif if (mb_queue_rsa4k_priv_get_size(tlv->rsa4k_priv_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_RSA_priv_reqs(tlv, RSA_4K_LENGTH); submission_count--; while ((mb_queue_rsa4k_priv_get_size(tlv->rsa4k_priv_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_RSA_priv_reqs(tlv, RSA_4K_LENGTH); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa4k_priv_req_rates); # endif if (mb_queue_rsa4k_pub_get_size(tlv->rsa4k_pub_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_RSA_pub_reqs(tlv, RSA_4K_LENGTH); submission_count--; while ((mb_queue_rsa4k_pub_get_size(tlv->rsa4k_pub_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_RSA_pub_reqs(tlv, RSA_4K_LENGTH); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa4k_pub_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_ECX if (mb_queue_x25519_keygen_get_size(tlv->x25519_keygen_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_x25519_keygen_reqs(tlv); submission_count--; while ((mb_queue_x25519_keygen_get_size(tlv->x25519_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_x25519_keygen_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_x25519_keygen_req_rates); # endif if (mb_queue_x25519_derive_get_size(tlv->x25519_derive_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_x25519_derive_reqs(tlv); submission_count--; while ((mb_queue_x25519_derive_get_size(tlv->x25519_derive_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_x25519_derive_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_x25519_derive_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_ECDSA if (mb_queue_ecdsap256_sign_get_size(tlv->ecdsap256_sign_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sign_reqs(tlv, EC_P256); submission_count--; while ((mb_queue_ecdsap256_sign_get_size(tlv->ecdsap256_sign_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sign_reqs(tlv, EC_P256); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_sign_req_rates); # endif if (mb_queue_ecdsap256_sign_setup_get_size(tlv->ecdsap256_sign_setup_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sign_setup_reqs(tlv, EC_P256); submission_count--; while ((mb_queue_ecdsap256_sign_setup_get_size(tlv->ecdsap256_sign_setup_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sign_setup_reqs(tlv, EC_P256); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_sign_setup_req_rates); # endif if (mb_queue_ecdsap256_sign_sig_get_size(tlv->ecdsap256_sign_sig_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sign_sig_reqs(tlv, EC_P256); submission_count--; while ((mb_queue_ecdsap256_sign_sig_get_size(tlv->ecdsap256_sign_sig_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sign_sig_reqs(tlv, EC_P256); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_sign_sig_req_rates); # endif if (mb_queue_ecdsap256_verify_get_size(tlv->ecdsap256_verify_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_verify_reqs(tlv, EC_P256); submission_count--; while ((mb_queue_ecdsap256_verify_get_size(tlv->ecdsap256_verify_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_verify_reqs(tlv, EC_P256); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_verify_req_rates); # endif if (mb_queue_ecdsap384_sign_get_size(tlv->ecdsap384_sign_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sign_reqs(tlv, EC_P384); submission_count--; while ((mb_queue_ecdsap384_sign_get_size(tlv->ecdsap384_sign_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sign_reqs(tlv, EC_P384); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_sign_req_rates); # endif if (mb_queue_ecdsap384_sign_setup_get_size(tlv->ecdsap384_sign_setup_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sign_setup_reqs(tlv, EC_P384); submission_count--; while ((mb_queue_ecdsap384_sign_setup_get_size(tlv->ecdsap384_sign_setup_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sign_setup_reqs(tlv, EC_P384); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_sign_setup_req_rates); # endif if (mb_queue_ecdsap384_sign_sig_get_size(tlv->ecdsap384_sign_sig_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sign_sig_reqs(tlv, EC_P384); submission_count--; while ((mb_queue_ecdsap384_sign_sig_get_size(tlv->ecdsap384_sign_sig_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sign_sig_reqs(tlv, EC_P384); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_sign_sig_req_rates); # endif if (mb_queue_ecdsap384_verify_get_size(tlv->ecdsap384_verify_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_verify_reqs(tlv, EC_P384); submission_count--; while ((mb_queue_ecdsap384_verify_get_size(tlv->ecdsap384_verify_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_verify_reqs(tlv, EC_P384); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_verify_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_SM2 if (mb_queue_ecdsa_sm2_sign_get_size(tlv->ecdsa_sm2_sign_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sm2_sign_reqs(tlv); submission_count--; while ((mb_queue_ecdsa_sm2_sign_get_size(tlv->ecdsa_sm2_sign_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sm2_sign_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsa_sm2_sign_req_rates); # endif if (mb_queue_ecdsa_sm2_verify_get_size(tlv->ecdsa_sm2_verify_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdsa_sm2_verify_reqs(tlv); submission_count--; while ((mb_queue_ecdsa_sm2_verify_get_size(tlv->ecdsa_sm2_verify_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdsa_sm2_verify_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsa_sm2_verify_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_ECDH if (mb_queue_ecdhp256_keygen_get_size(tlv->ecdhp256_keygen_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdh_keygen_reqs(tlv, EC_P256); submission_count--; while ((mb_queue_ecdhp256_keygen_get_size(tlv->ecdhp256_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdh_keygen_reqs(tlv, EC_P256); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp256_keygen_req_rates); # endif if (mb_queue_ecdhp256_compute_get_size(tlv->ecdhp256_compute_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdh_compute_reqs(tlv, EC_P256); submission_count--; while ((mb_queue_ecdhp256_compute_get_size(tlv->ecdhp256_compute_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdh_compute_reqs(tlv, EC_P256); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp256_compute_req_rates); # endif if (mb_queue_ecdhp384_keygen_get_size(tlv->ecdhp384_keygen_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdh_keygen_reqs(tlv, EC_P384); submission_count--; while ((mb_queue_ecdhp384_keygen_get_size(tlv->ecdhp384_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdh_keygen_reqs(tlv, EC_P384); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp384_keygen_req_rates); # endif if (mb_queue_ecdhp384_compute_get_size(tlv->ecdhp384_compute_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdh_compute_reqs(tlv, EC_P384); submission_count--; while ((mb_queue_ecdhp384_compute_get_size(tlv->ecdhp384_compute_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdh_compute_reqs(tlv, EC_P384); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp384_compute_req_rates); # endif if (mb_queue_sm2ecdh_keygen_get_size(tlv->sm2ecdh_keygen_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdh_keygen_reqs(tlv, EC_SM2); submission_count--; while ((mb_queue_sm2ecdh_keygen_get_size(tlv->sm2ecdh_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdh_keygen_reqs(tlv, EC_SM2); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm2ecdh_keygen_req_rates); # endif if (mb_queue_sm2ecdh_compute_get_size(tlv->sm2ecdh_compute_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_ecdh_compute_reqs(tlv, EC_SM2); submission_count--; while ((mb_queue_sm2ecdh_compute_get_size(tlv->sm2ecdh_compute_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)) { process_ecdh_compute_reqs(tlv, EC_SM2); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm2ecdh_compute_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_SM3 if (mb_queue_sm3_init_get_size(tlv->sm3_init_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_sm3_init_reqs(tlv); submission_count--; while ((mb_queue_sm3_init_get_size(tlv->sm3_init_queue) >= MULTIBUFF_SM3_MIN_BATCH) && (submission_count > 0)) { process_sm3_init_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm3_init_req_rates); # endif if (mb_queue_sm3_update_get_size(tlv->sm3_update_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_sm3_update_reqs(tlv); submission_count--; while ((mb_queue_sm3_update_get_size(tlv->sm3_update_queue) >= MULTIBUFF_SM3_MIN_BATCH) && (submission_count > 0)) { process_sm3_update_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm3_update_req_rates); # endif if (mb_queue_sm3_final_get_size(tlv->sm3_final_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_sm3_final_reqs(tlv); submission_count--; while ((mb_queue_sm3_final_get_size(tlv->sm3_final_queue) >= MULTIBUFF_SM3_MIN_BATCH) && (submission_count > 0)) { process_sm3_final_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm3_final_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_SM4_CBC if (mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_mb_sm4_cbc_cipher_enc_reqs(tlv); submission_count--; while ((mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)) { process_mb_sm4_cbc_cipher_enc_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_cbc_cipher_req_rates); # endif if (mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_dec_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_mb_sm4_cbc_cipher_dec_reqs(tlv); submission_count--; while ((mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_dec_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)) { process_mb_sm4_cbc_cipher_dec_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_cbc_cipher_dec_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_SM4_GCM if (mb_queue_sm4_gcm_encrypt_get_size(tlv->sm4_gcm_encrypt_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_mb_sm4_gcm_encrypt_reqs(tlv); submission_count--; while ((mb_queue_sm4_gcm_encrypt_get_size(tlv->sm4_gcm_encrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)) { process_mb_sm4_gcm_encrypt_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_gcm_encrypt_req_rates); # endif if (mb_queue_sm4_gcm_decrypt_get_size(tlv->sm4_gcm_decrypt_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_mb_sm4_gcm_decrypt_reqs(tlv); submission_count--; while ((mb_queue_sm4_gcm_decrypt_get_size(tlv->sm4_gcm_decrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)) { process_mb_sm4_gcm_decrypt_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_gcm_decrypt_req_rates); # endif #endif #ifdef ENABLE_QAT_SW_SM4_CCM if (mb_queue_sm4_ccm_encrypt_get_size(tlv->sm4_ccm_encrypt_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_mb_sm4_ccm_encrypt_reqs(tlv); submission_count--; while ((mb_queue_sm4_ccm_encrypt_get_size(tlv->sm4_ccm_encrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)) { process_mb_sm4_ccm_encrypt_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_ccm_encrypt_req_rates); # endif if (mb_queue_sm4_ccm_decrypt_get_size(tlv->sm4_ccm_decrypt_queue) > 0) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; process_mb_sm4_ccm_decrypt_reqs(tlv); submission_count--; while ((mb_queue_sm4_ccm_decrypt_get_size(tlv->sm4_ccm_decrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)) { process_mb_sm4_ccm_decrypt_reqs(tlv); submission_count--; } } # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_ccm_decrypt_req_rates); # endif #endif continue; } } DEBUG("Checking whether we have enough requests to process\n"); #ifdef ENABLE_QAT_SW_ECX if (mb_queue_x25519_keygen_get_size(tlv->x25519_keygen_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 X25519 keygen requests */ DEBUG("8 X25519 keygen requests in flight, process them\n"); process_x25519_keygen_reqs(tlv); submission_count--; } while ((mb_queue_x25519_keygen_get_size(tlv->x25519_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_x25519_keygen_req_rates); # endif } if (mb_queue_x25519_derive_get_size(tlv->x25519_derive_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 X25519 derive requests */ DEBUG("8 X25519 derive requests in flight, process them\n"); process_x25519_derive_reqs(tlv); submission_count--; } while ((mb_queue_x25519_derive_get_size(tlv->x25519_derive_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_x25519_derive_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_ECDSA if (mb_queue_ecdsap256_sign_get_size(tlv->ecdsap256_sign_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p256 Sign requests */ DEBUG("8 ECDSA p256 Sign requests in flight, process them\n"); process_ecdsa_sign_reqs(tlv, EC_P256); submission_count--; } while ((mb_queue_ecdsap256_sign_get_size(tlv->ecdsap256_sign_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_sign_req_rates); # endif } if (mb_queue_ecdsap256_sign_setup_get_size(tlv->ecdsap256_sign_setup_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p256 sign setup requests */ DEBUG("8 ECDSA p256 sign setup requests in flight, process them\n"); process_ecdsa_sign_setup_reqs(tlv, EC_P256); submission_count--; } while ((mb_queue_ecdsap256_sign_setup_get_size(tlv->ecdsap256_sign_setup_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_sign_setup_req_rates); # endif } if (mb_queue_ecdsap256_sign_sig_get_size(tlv->ecdsap256_sign_sig_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p256 sign sig requests */ DEBUG("8 ECDSA p256 sign sig requests in flight, process them\n"); process_ecdsa_sign_sig_reqs(tlv, EC_P256); submission_count--; } while ((mb_queue_ecdsap256_sign_sig_get_size(tlv->ecdsap256_sign_sig_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_sign_sig_req_rates); # endif } if (mb_queue_ecdsap256_verify_get_size(tlv->ecdsap256_verify_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p256 Sign requests */ DEBUG("8 ECDSA p256 Sign requests in flight, process them\n"); process_ecdsa_verify_reqs(tlv, EC_P256); submission_count--; } while ((mb_queue_ecdsap256_verify_get_size(tlv->ecdsap256_verify_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap256_verify_req_rates); # endif } if (mb_queue_ecdsap384_sign_get_size(tlv->ecdsap384_sign_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p384 Sign requests */ DEBUG("8 ECDSA p384 Sign requests in flight, process them\n"); process_ecdsa_sign_reqs(tlv, EC_P384); submission_count--; } while ((mb_queue_ecdsap384_sign_get_size(tlv->ecdsap384_sign_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_sign_req_rates); # endif } if (mb_queue_ecdsap384_sign_setup_get_size(tlv->ecdsap384_sign_setup_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p384 sign setup requests */ DEBUG("8 ECDSA p384 sign setup requests in flight, process them\n"); process_ecdsa_sign_setup_reqs(tlv, EC_P384); submission_count--; } while ((mb_queue_ecdsap384_sign_setup_get_size(tlv->ecdsap384_sign_setup_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_sign_setup_req_rates); # endif } if (mb_queue_ecdsap384_sign_sig_get_size(tlv->ecdsap384_sign_sig_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p384 sign sig requests */ DEBUG("8 ECDSA p384 sign sig requests in flight, process them\n"); process_ecdsa_sign_sig_reqs(tlv, EC_P384); submission_count--; } while ((mb_queue_ecdsap384_sign_sig_get_size(tlv->ecdsap384_sign_sig_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_sign_sig_req_rates); # endif } if (mb_queue_ecdsap384_verify_get_size(tlv->ecdsap384_verify_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDSA p384 Sign requests */ DEBUG("8 ECDSA p384 Sign requests in flight, process them\n"); process_ecdsa_verify_reqs(tlv, EC_P384); submission_count--; } while ((mb_queue_ecdsap384_verify_get_size(tlv->ecdsap384_verify_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsap384_verify_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_SM2 if (mb_queue_ecdsa_sm2_sign_get_size(tlv->ecdsa_sm2_sign_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 SM2_ECDSA Verify requests */ DEBUG("8 SM2_ECDSA Sign requests in flight, process them\n"); process_ecdsa_sm2_sign_reqs(tlv); submission_count--; } while ((mb_queue_ecdsa_sm2_sign_get_size(tlv->ecdsa_sm2_sign_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsa_sm2_sign_req_rates); # endif } if (mb_queue_ecdsa_sm2_verify_get_size(tlv->ecdsa_sm2_verify_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 SM2_ECDSA Verify requests */ DEBUG("8 SM2_ECDSA Verify requests in flight, process them\n"); process_ecdsa_sm2_verify_reqs(tlv); submission_count--; } while ((mb_queue_ecdsa_sm2_verify_get_size(tlv->ecdsa_sm2_verify_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdsa_sm2_verify_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_ECDH if (mb_queue_ecdhp256_keygen_get_size(tlv->ecdhp256_keygen_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDH p256 keygen requests */ DEBUG("8 ECDH p256 keygen requests in flight, process them\n"); process_ecdh_keygen_reqs(tlv, EC_P256); submission_count--; } while ((mb_queue_ecdhp256_keygen_get_size(tlv->ecdhp256_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp256_keygen_req_rates); # endif } if (mb_queue_ecdhp256_compute_get_size(tlv->ecdhp256_compute_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDH p256 compute requests */ DEBUG("8 ECDH p256 compute requests in flight, process them\n"); process_ecdh_compute_reqs(tlv, EC_P256); submission_count--; } while ((mb_queue_ecdhp256_compute_get_size(tlv->ecdhp256_compute_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp256_compute_req_rates); # endif } if (mb_queue_ecdhp384_keygen_get_size(tlv->ecdhp384_keygen_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDH p384 keygen requests */ DEBUG("8 ECDH p384 keygen requests in flight, process them\n"); process_ecdh_keygen_reqs(tlv, EC_P384); submission_count--; } while ((mb_queue_ecdhp384_keygen_get_size(tlv->ecdhp384_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp384_keygen_req_rates); # endif } if (mb_queue_ecdhp384_compute_get_size(tlv->ecdhp384_compute_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDH p384 compute requests */ DEBUG("8 ECDH p384 compute requests in flight, process them\n"); process_ecdh_compute_reqs(tlv, EC_P384); submission_count--; } while ((mb_queue_ecdhp384_compute_get_size(tlv->ecdhp384_compute_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_ecdhp384_compute_req_rates); #endif } if (mb_queue_sm2ecdh_keygen_get_size(tlv->sm2ecdh_keygen_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDH sm2 keygen requests */ DEBUG("8 ECDH sm2 keygen requests in flight, process them\n"); process_ecdh_keygen_reqs(tlv, EC_SM2); submission_count--; } while ((mb_queue_sm2ecdh_keygen_get_size(tlv->sm2ecdh_keygen_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm2ecdh_keygen_req_rates); # endif } if (mb_queue_sm2ecdh_compute_get_size(tlv->sm2ecdh_compute_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 ECDH sm2 compute requests */ DEBUG("8 ECDH sm2 compute requests in flight, process them\n"); process_ecdh_compute_reqs(tlv, EC_SM2); submission_count--; } while ((mb_queue_sm2ecdh_compute_get_size(tlv->sm2ecdh_compute_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm2ecdh_compute_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_RSA if (mb_queue_rsa2k_priv_get_size(tlv->rsa2k_priv_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 private key requests */ DEBUG("8 RSA2K private key requests in flight, process them\n"); process_RSA_priv_reqs(tlv, RSA_2K_LENGTH); submission_count--; } while ((mb_queue_rsa2k_priv_get_size(tlv->rsa2k_priv_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa2k_priv_req_rates); # endif } if (mb_queue_rsa2k_pub_get_size(tlv->rsa2k_pub_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 public key requests */ DEBUG("8 RSA2K public key requests in flight, process them\n"); process_RSA_pub_reqs(tlv, RSA_2K_LENGTH); submission_count--; } while ((mb_queue_rsa2k_pub_get_size(tlv->rsa2k_pub_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa2k_pub_req_rates); # endif } if (mb_queue_rsa3k_priv_get_size(tlv->rsa3k_priv_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 private key requests */ DEBUG("8 RSA3k private key requests in flight, process them\n"); process_RSA_priv_reqs(tlv, RSA_3K_LENGTH); submission_count--; } while ((mb_queue_rsa3k_priv_get_size(tlv->rsa3k_priv_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa3k_priv_req_rates); # endif } if (mb_queue_rsa3k_pub_get_size(tlv->rsa3k_pub_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 public key requests */ DEBUG("8 RSA3k public key requests in flight, process them\n"); process_RSA_pub_reqs(tlv, RSA_3K_LENGTH); submission_count--; } while ((mb_queue_rsa3k_pub_get_size(tlv->rsa3k_pub_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa3k_pub_req_rates); # endif } if (mb_queue_rsa4k_priv_get_size(tlv->rsa4k_priv_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 private key requests */ DEBUG("8 RSA4k private key requests in flight, process them\n"); process_RSA_priv_reqs(tlv, RSA_4K_LENGTH); submission_count--; } while ((mb_queue_rsa4k_priv_get_size(tlv->rsa4k_priv_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa4k_priv_req_rates); # endif } if (mb_queue_rsa4k_pub_get_size(tlv->rsa4k_pub_queue) >= MULTIBUFF_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { /* Deal with 8 public key requests */ DEBUG("8 RSA4k public key requests in flight, process them\n"); process_RSA_pub_reqs(tlv, RSA_4K_LENGTH); submission_count--; } while ((mb_queue_rsa4k_pub_get_size(tlv->rsa4k_pub_queue) >= MULTIBUFF_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_rsa4k_pub_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_SM3 if (mb_queue_sm3_init_get_size(tlv->sm3_init_queue) >= MULTIBUFF_SM3_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("16 SM3 Init requests in flight, process them\n"); process_sm3_init_reqs(tlv); submission_count--; } while ((mb_queue_sm3_init_get_size(tlv->sm3_init_queue) >= MULTIBUFF_SM3_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm3_init_req_rates); # endif } if (mb_queue_sm3_update_get_size(tlv->sm3_update_queue) >= MULTIBUFF_SM3_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("16 SM3 Update requests in flight, process them\n"); process_sm3_update_reqs(tlv); submission_count--; } while ((mb_queue_sm3_update_get_size(tlv->sm3_update_queue) >= MULTIBUFF_SM3_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm3_update_req_rates); # endif } if (mb_queue_sm3_final_get_size(tlv->sm3_final_queue) >= MULTIBUFF_SM3_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("16 SM3 Final requests in flight, process them\n"); process_sm3_final_reqs(tlv); submission_count--; } while ((mb_queue_sm3_final_get_size(tlv->sm3_final_queue) >= MULTIBUFF_SM3_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm3_final_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_SM4_CBC if (mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_queue) >= MULTIBUFF_SM4_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("%d SM4_CBC cipher enc requests in flight, process them\n", MULTIBUFF_SM4_MAX_BATCH); process_mb_sm4_cbc_cipher_enc_reqs(tlv); submission_count--; } while ((mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_cbc_cipher_req_rates); # endif } if (mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_dec_queue) >= MULTIBUFF_SM4_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("%d SM4_CBC cipher dec requests in flight, process them\n", MULTIBUFF_SM4_MAX_BATCH); process_mb_sm4_cbc_cipher_dec_reqs(tlv); submission_count--; } while ((mb_queue_sm4_cbc_cipher_get_size(tlv->sm4_cbc_cipher_dec_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_cbc_cipher_dec_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_SM4_GCM if (mb_queue_sm4_gcm_encrypt_get_size(tlv->sm4_gcm_encrypt_queue) >= MULTIBUFF_SM4_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("%d SM4_GCM encrypt requests in flight, process them\n", MULTIBUFF_SM4_MAX_BATCH); process_mb_sm4_gcm_encrypt_reqs(tlv); submission_count--; } while ((mb_queue_sm4_gcm_encrypt_get_size(tlv->sm4_gcm_encrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_gcm_encrypt_req_rates); # endif } if (mb_queue_sm4_gcm_decrypt_get_size(tlv->sm4_gcm_decrypt_queue) >= MULTIBUFF_SM4_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("%d SM4_GCM decrypt requests in flight, process them\n", MULTIBUFF_SM4_MAX_BATCH); process_mb_sm4_gcm_decrypt_reqs(tlv); submission_count--; } while ((mb_queue_sm4_gcm_decrypt_get_size(tlv->sm4_gcm_decrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_gcm_decrypt_req_rates); # endif } #endif #ifdef ENABLE_QAT_SW_SM4_CCM if (mb_queue_sm4_ccm_encrypt_get_size(tlv->sm4_ccm_encrypt_queue) >= MULTIBUFF_SM4_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("%d SM4_GCM encrypt requests in flight, process them\n", MULTIBUFF_SM4_MAX_BATCH); process_mb_sm4_ccm_encrypt_reqs(tlv); submission_count--; } while ((mb_queue_sm4_ccm_encrypt_get_size(tlv->sm4_ccm_encrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_ccm_encrypt_req_rates); # endif } if (mb_queue_sm4_ccm_decrypt_get_size(tlv->sm4_ccm_decrypt_queue) >= MULTIBUFF_SM4_MAX_BATCH) { submission_count = MULTIBUFF_MAX_SUBMISSIONS; do { DEBUG("%d SM4_GCM decrypt requests in flight, process them\n", MULTIBUFF_SM4_MAX_BATCH); process_mb_sm4_ccm_decrypt_reqs(tlv); submission_count--; } while ((mb_queue_sm4_ccm_decrypt_get_size(tlv->sm4_ccm_decrypt_queue) >= MULTIBUFF_SM4_MIN_BATCH) && (submission_count > 0)); # ifdef QAT_SW_HEURISTIC_TIMEOUT multibuff_update_req_timeout(&mb_sm4_ccm_decrypt_req_rates); # endif } #endif DEBUG("Finished loop in the Polling Thread\n"); } DEBUG("timer_poll_func finishing - pid = %d\n", getpid()); cleared_to_start = 0; return NULL; } int qat_sw_poll() { struct timespec current_time = { 0 }; #if defined(ENABLE_QAT_SW_RSA) || defined(ENABLE_QAT_SW_ECX) \ || defined(ENABLE_QAT_SW_ECDSA) || defined(ENABLE_QAT_SW_ECDH) \ || defined(ENABLE_QAT_SW_SM3) || defined(ENABLE_QAT_SW_SM4_CBC) \ || defined(ENABLE_QAT_SW_SM4_GCM) || defined(ENABLE_QAT_SW_SM4_CCM) int snapshot_num_reqs = 0; #endif if (enable_external_polling == 0) { WARN("External Polling is not enabled\n"); return 0; } if (mb_tlv == NULL) return 1; /* Do nothing as there are no QAT_SW Requests */ clock_gettime(clock_id, ¤t_time); #ifdef ENABLE_QAT_SW_ECX /* Deal with X25519 Keygen requests */ snapshot_num_reqs = mb_queue_x25519_keygen_get_size(mb_tlv->x25519_keygen_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_x25519_keygen_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &x25519_keygen_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, x25519_keygen_previous_time, current_time) == 1) { process_x25519_keygen_reqs(mb_tlv); clock_gettime(clock_id, &x25519_keygen_previous_time); } } /* Deal with X25519 Derive requests */ snapshot_num_reqs = mb_queue_x25519_derive_get_size(mb_tlv->x25519_derive_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_x25519_derive_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &x25519_derive_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, x25519_derive_previous_time, current_time) == 1) { process_x25519_derive_reqs(mb_tlv); clock_gettime(clock_id, &x25519_derive_previous_time); } } #endif #ifdef ENABLE_QAT_SW_ECDSA /* Deal with ECDSA p256 sign requests */ snapshot_num_reqs = mb_queue_ecdsap256_sign_get_size(mb_tlv->ecdsap256_sign_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sign_reqs(mb_tlv, EC_P256); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap256_sign_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap256_sign_previous_time, current_time) == 1) { process_ecdsa_sign_reqs(mb_tlv, EC_P256); clock_gettime(clock_id, &ecdsap256_sign_previous_time); } } /* Deal with ECDSA p256 sign setup requests */ snapshot_num_reqs = mb_queue_ecdsap256_sign_setup_get_size(mb_tlv->ecdsap256_sign_setup_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sign_setup_reqs(mb_tlv, EC_P256); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap256_sign_setup_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap256_sign_setup_previous_time, current_time) == 1) { process_ecdsa_sign_setup_reqs(mb_tlv, EC_P256); clock_gettime(clock_id, &ecdsap256_sign_setup_previous_time); } } /* Deal with ECDSA p256 sign sig requests */ snapshot_num_reqs = mb_queue_ecdsap256_sign_sig_get_size(mb_tlv->ecdsap256_sign_sig_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sign_sig_reqs(mb_tlv, EC_P256); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap256_sign_sig_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap256_sign_sig_previous_time, current_time) == 1) { process_ecdsa_sign_sig_reqs(mb_tlv, EC_P256); clock_gettime(clock_id, &ecdsap256_sign_sig_previous_time); } } /* Deal with ECDSA p384 sign requests */ snapshot_num_reqs = mb_queue_ecdsap384_sign_get_size(mb_tlv->ecdsap384_sign_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sign_reqs(mb_tlv, EC_P384); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap384_sign_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap384_sign_previous_time, current_time) == 1) { process_ecdsa_sign_reqs(mb_tlv, EC_P384); clock_gettime(clock_id, &ecdsap384_sign_previous_time); } } /* Deal with ECDSA p384 sign setup requests */ snapshot_num_reqs = mb_queue_ecdsap384_sign_setup_get_size(mb_tlv->ecdsap384_sign_setup_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sign_setup_reqs(mb_tlv, EC_P384); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap384_sign_setup_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap384_sign_setup_previous_time, current_time) == 1) { process_ecdsa_sign_setup_reqs(mb_tlv, EC_P384); clock_gettime(clock_id, &ecdsap384_sign_setup_previous_time); } } /* Deal with ECDSA p384 sign sig requests */ snapshot_num_reqs = mb_queue_ecdsap384_sign_sig_get_size(mb_tlv->ecdsap384_sign_sig_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sign_sig_reqs(mb_tlv, EC_P384); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap384_sign_sig_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap384_sign_sig_previous_time, current_time) == 1) { process_ecdsa_sign_sig_reqs(mb_tlv, EC_P384); clock_gettime(clock_id, &ecdsap384_sign_sig_previous_time); } } /* Deal with ECDSA p256 verify requests */ snapshot_num_reqs = mb_queue_ecdsap256_verify_get_size(mb_tlv->ecdsap256_verify_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_verify_reqs(mb_tlv, EC_P256); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap256_verify_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap256_verify_previous_time, current_time) == 1) { process_ecdsa_verify_reqs(mb_tlv, EC_P256); clock_gettime(clock_id, &ecdsap256_verify_previous_time); } } /* Deal with ECDSA p384 verify requests */ snapshot_num_reqs = mb_queue_ecdsap384_verify_get_size(mb_tlv->ecdsap384_verify_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_verify_reqs(mb_tlv, EC_P384); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsap384_verify_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsap384_verify_previous_time, current_time) == 1) { process_ecdsa_verify_reqs(mb_tlv, EC_P384); clock_gettime(clock_id, &ecdsap384_verify_previous_time); } } #endif #ifdef ENABLE_QAT_SW_SM2 /* Deal with SM2_ECDSA sign requests */ snapshot_num_reqs = mb_queue_ecdsa_sm2_sign_get_size(mb_tlv->ecdsa_sm2_sign_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sm2_sign_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsa_sm2_sign_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsa_sm2_sign_previous_time, current_time) == 1) { process_ecdsa_sm2_sign_reqs(mb_tlv); clock_gettime(clock_id, &ecdsa_sm2_sign_previous_time); } } /* Deal with SM2_ECDSA verify requests */ snapshot_num_reqs = mb_queue_ecdsa_sm2_verify_get_size(mb_tlv->ecdsa_sm2_verify_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdsa_sm2_verify_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdsa_sm2_verify_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdsa_sm2_verify_previous_time, current_time) == 1) { process_ecdsa_sm2_verify_reqs(mb_tlv); clock_gettime(clock_id, &ecdsa_sm2_verify_previous_time); } } #endif #ifdef ENABLE_QAT_SW_ECDH /* Deal with ECDH p256 Keygen requests */ snapshot_num_reqs = mb_queue_ecdhp256_keygen_get_size(mb_tlv->ecdhp256_keygen_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdh_keygen_reqs(mb_tlv, EC_P256); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdhp256_keygen_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdhp256_keygen_previous_time, current_time) == 1) { process_ecdh_keygen_reqs(mb_tlv, EC_P256); clock_gettime(clock_id, &ecdhp256_keygen_previous_time); } } /* Deal with ECDH p256 compute requests */ snapshot_num_reqs = mb_queue_ecdhp256_compute_get_size(mb_tlv->ecdhp256_compute_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdh_compute_reqs(mb_tlv, EC_P256); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdhp256_compute_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdhp256_compute_previous_time, current_time) == 1) { process_ecdh_compute_reqs(mb_tlv, EC_P256); clock_gettime(clock_id, &ecdhp256_compute_previous_time); } } /* Deal with ECDH p384 Keygen requests */ snapshot_num_reqs = mb_queue_ecdhp384_keygen_get_size(mb_tlv->ecdhp384_keygen_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdh_keygen_reqs(mb_tlv, EC_P384); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdhp384_keygen_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdhp384_keygen_previous_time, current_time) == 1) { process_ecdh_keygen_reqs(mb_tlv, EC_P384); clock_gettime(clock_id, &ecdhp384_keygen_previous_time); } } /* Deal with ECDH p384 compute requests */ snapshot_num_reqs = mb_queue_ecdhp384_compute_get_size(mb_tlv->ecdhp384_compute_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdh_compute_reqs(mb_tlv, EC_P384); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &ecdhp384_compute_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, ecdhp384_compute_previous_time, current_time) == 1) { process_ecdh_compute_reqs(mb_tlv, EC_P384); clock_gettime(clock_id, &ecdhp384_compute_previous_time); } } /* Deal with ECDH sm2 Keygen requests */ snapshot_num_reqs = mb_queue_sm2ecdh_keygen_get_size(mb_tlv->sm2ecdh_keygen_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdh_keygen_reqs(mb_tlv, EC_SM2); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &sm2ecdh_keygen_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm2ecdh_keygen_previous_time, current_time) == 1) { process_ecdh_keygen_reqs(mb_tlv, EC_SM2); clock_gettime(clock_id, &sm2ecdh_keygen_previous_time); } } /* Deal with ECDH sm2 compute requests */ snapshot_num_reqs = mb_queue_sm2ecdh_compute_get_size(mb_tlv->sm2ecdh_compute_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_ecdh_compute_reqs(mb_tlv, EC_SM2); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &sm2ecdh_compute_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm2ecdh_compute_previous_time, current_time) == 1) { process_ecdh_compute_reqs(mb_tlv, EC_SM2); clock_gettime(clock_id, &sm2ecdh_compute_previous_time); } } #endif #ifdef ENABLE_QAT_SW_RSA /* Deal with rsa private key requests */ snapshot_num_reqs = mb_queue_rsa2k_priv_get_size(mb_tlv->rsa2k_priv_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_RSA_priv_reqs(mb_tlv, RSA_2K_LENGTH); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &rsa2k_priv_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, rsa2k_priv_previous_time, current_time) == 1) { process_RSA_priv_reqs(mb_tlv, RSA_2K_LENGTH); clock_gettime(clock_id, &rsa2k_priv_previous_time); } } /* Deal with rsa public key requests */ snapshot_num_reqs = mb_queue_rsa2k_pub_get_size(mb_tlv->rsa2k_pub_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_RSA_pub_reqs(mb_tlv, RSA_2K_LENGTH); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &rsa2k_pub_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, rsa2k_pub_previous_time, current_time) == 1) { process_RSA_pub_reqs(mb_tlv, RSA_2K_LENGTH); clock_gettime(clock_id, &rsa2k_pub_previous_time); } } /* Deal with rsa3k private key requests */ snapshot_num_reqs = mb_queue_rsa3k_priv_get_size(mb_tlv->rsa3k_priv_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_RSA_priv_reqs(mb_tlv, RSA_3K_LENGTH); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &rsa3k_priv_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, rsa3k_priv_previous_time, current_time) == 1) { process_RSA_priv_reqs(mb_tlv, RSA_3K_LENGTH); clock_gettime(clock_id, &rsa3k_priv_previous_time); } } /* Deal with rsa3k public key requests */ snapshot_num_reqs = mb_queue_rsa3k_pub_get_size(mb_tlv->rsa3k_pub_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_RSA_pub_reqs(mb_tlv, RSA_3K_LENGTH); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &rsa3k_pub_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, rsa3k_pub_previous_time, current_time) == 1) { process_RSA_pub_reqs(mb_tlv, RSA_3K_LENGTH); clock_gettime(clock_id, &rsa3k_pub_previous_time); } } /* Deal with rsa4k private key requests */ snapshot_num_reqs = mb_queue_rsa4k_priv_get_size(mb_tlv->rsa4k_priv_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_RSA_priv_reqs(mb_tlv, RSA_4K_LENGTH); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &rsa4k_priv_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, rsa4k_priv_previous_time, current_time) == 1) { process_RSA_priv_reqs(mb_tlv, RSA_4K_LENGTH); clock_gettime(clock_id, &rsa4k_priv_previous_time); } } /* Deal with rsa4k public key requests */ snapshot_num_reqs = mb_queue_rsa4k_pub_get_size(mb_tlv->rsa4k_pub_queue); if (snapshot_num_reqs >= MULTIBUFF_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_MIN_BATCH) { process_RSA_pub_reqs(mb_tlv, RSA_4K_LENGTH); snapshot_num_reqs -= MULTIBUFF_MIN_BATCH; } clock_gettime(clock_id, &rsa4k_pub_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, rsa4k_pub_previous_time, current_time) == 1) { process_RSA_pub_reqs(mb_tlv, RSA_4K_LENGTH); clock_gettime(clock_id, &rsa4k_pub_previous_time); } } #endif #ifdef ENABLE_QAT_SW_SM3 /* Deal with SM3 Init requests */ snapshot_num_reqs = mb_queue_sm3_init_get_size(mb_tlv->sm3_init_queue); if (snapshot_num_reqs >= MULTIBUFF_SM3_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM3_MIN_BATCH) { process_sm3_init_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM3_MIN_BATCH; } clock_gettime(clock_id, &sm3_init_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM3_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm3_init_previous_time, current_time) == 1) { process_sm3_init_reqs(mb_tlv); clock_gettime(clock_id, &sm3_init_previous_time); } } /* Deal with SM3 Update requests */ snapshot_num_reqs = mb_queue_sm3_update_get_size(mb_tlv->sm3_update_queue); if (snapshot_num_reqs >= MULTIBUFF_SM3_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM3_MIN_BATCH) { process_sm3_update_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM3_MIN_BATCH; } clock_gettime(clock_id, &sm3_update_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM3_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm3_update_previous_time, current_time) == 1) { process_sm3_update_reqs(mb_tlv); clock_gettime(clock_id, &sm3_update_previous_time); } } /* Deal with SM3 Final requests */ snapshot_num_reqs = mb_queue_sm3_final_get_size(mb_tlv->sm3_final_queue); if (snapshot_num_reqs >= MULTIBUFF_SM3_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM3_MIN_BATCH) { process_sm3_final_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM3_MIN_BATCH; } clock_gettime(clock_id, &sm3_final_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM3_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm3_final_previous_time, current_time) == 1) { process_sm3_final_reqs(mb_tlv); clock_gettime(clock_id, &sm3_final_previous_time); } } #endif #ifdef ENABLE_QAT_SW_SM4_CBC /* Deal with SM4_CBC Cipher requests */ snapshot_num_reqs = mb_queue_sm4_cbc_cipher_get_size(mb_tlv->sm4_cbc_cipher_queue); if (snapshot_num_reqs >= MULTIBUFF_SM4_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM4_MIN_BATCH) { process_mb_sm4_cbc_cipher_enc_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM4_MIN_BATCH; } clock_gettime(clock_id, &sm4_cbc_cipher_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM4_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm4_cbc_cipher_previous_time, current_time) == 1) { process_mb_sm4_cbc_cipher_enc_reqs(mb_tlv); clock_gettime(clock_id, &sm4_cbc_cipher_previous_time); } } /* Deal with SM4_CBC Cipher decryption requests */ snapshot_num_reqs = mb_queue_sm4_cbc_cipher_get_size(mb_tlv->sm4_cbc_cipher_dec_queue); if (snapshot_num_reqs >= MULTIBUFF_SM4_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM4_MIN_BATCH) { process_mb_sm4_cbc_cipher_dec_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM4_MIN_BATCH; } clock_gettime(clock_id, &sm4_cbc_cipher_dec_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM4_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm4_cbc_cipher_dec_previous_time, current_time) == 1) { process_mb_sm4_cbc_cipher_dec_reqs(mb_tlv); clock_gettime(clock_id, &sm4_cbc_cipher_dec_previous_time); } } #endif #ifdef ENABLE_QAT_SW_SM4_GCM /* Deal with SM4_GCM Cipher requests */ snapshot_num_reqs = mb_queue_sm4_gcm_encrypt_get_size(mb_tlv->sm4_gcm_encrypt_queue); if (snapshot_num_reqs >= MULTIBUFF_SM4_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM4_MIN_BATCH) { process_mb_sm4_gcm_encrypt_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM4_MIN_BATCH; } clock_gettime(clock_id, &sm4_gcm_encrypt_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM4_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm4_gcm_encrypt_previous_time, current_time) == 1) { process_mb_sm4_gcm_encrypt_reqs(mb_tlv); clock_gettime(clock_id, &sm4_gcm_encrypt_previous_time); } } /* Deal with SM4_GCM Decrypt requests */ snapshot_num_reqs = mb_queue_sm4_gcm_decrypt_get_size(mb_tlv->sm4_gcm_decrypt_queue); if (snapshot_num_reqs >= MULTIBUFF_SM4_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM4_MIN_BATCH) { process_mb_sm4_gcm_decrypt_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM4_MIN_BATCH; } clock_gettime(clock_id, &sm4_gcm_decrypt_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM4_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm4_gcm_decrypt_previous_time, current_time) == 1) { process_mb_sm4_gcm_decrypt_reqs(mb_tlv); clock_gettime(clock_id, &sm4_gcm_decrypt_previous_time); } } #endif #ifdef ENABLE_QAT_SW_SM4_CCM /* Deal with SM4_CCM Encrypt requests */ snapshot_num_reqs = mb_queue_sm4_ccm_encrypt_get_size(mb_tlv->sm4_ccm_encrypt_queue); if (snapshot_num_reqs >= MULTIBUFF_SM4_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM4_MIN_BATCH) { process_mb_sm4_ccm_encrypt_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM4_MIN_BATCH; } clock_gettime(clock_id, &sm4_ccm_encrypt_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM4_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm4_ccm_encrypt_previous_time, current_time) == 1) { process_mb_sm4_ccm_encrypt_reqs(mb_tlv); clock_gettime(clock_id, &sm4_ccm_encrypt_previous_time); } } /* Deal with SM4_CCM Decrypt requests */ snapshot_num_reqs = mb_queue_sm4_ccm_decrypt_get_size(mb_tlv->sm4_ccm_decrypt_queue); if (snapshot_num_reqs >= MULTIBUFF_SM4_MAX_BATCH) { while (snapshot_num_reqs >= MULTIBUFF_SM4_MIN_BATCH) { process_mb_sm4_ccm_decrypt_reqs(mb_tlv); snapshot_num_reqs -= MULTIBUFF_SM4_MIN_BATCH; } clock_gettime(clock_id, &sm4_ccm_decrypt_previous_time); } else { if (snapshot_num_reqs > 0 && snapshot_num_reqs < MULTIBUFF_SM4_MAX_BATCH && multibuff_poll_check_for_timeout(mb_poll_timeout_time, sm4_ccm_decrypt_previous_time, current_time) == 1) { process_mb_sm4_ccm_decrypt_reqs(mb_tlv); clock_gettime(clock_id, &sm4_ccm_decrypt_previous_time); } } #endif return 1; } qatengine-1.9.0/qat_sw_polling.h000066400000000000000000000052461500416242000166700ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_polling.h * * This file provides an interface for multibuff polling in QAT engine * *****************************************************************************/ #ifndef QAT_SW_POLLING_H # define QAT_SW_POLLING_H #include "e_qat.h" /****************************************************************************** * function: * void *timer_poll_func(void *ih) * * @param ih [IN] - NULL * * description: * Poll the multibuff request (nanosleep version) * NB: Delay in this function is set by default at runtime by an engine * specific message. If not set then the default is QAT_POLL_PERIOD_IN_NS. * ******************************************************************************/ void *multibuff_timer_poll_func(void *ih); int qat_sw_poll(); #endif /* QAT_SW_POLLING_H */ qatengine-1.9.0/qat_sw_queue.c000066400000000000000000003026111500416242000163370ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_queue.c * * This file provides multibuff implementations of a queue * *****************************************************************************/ #include #include #include /* Local Includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_sw_queue.h" #include "qat_sw_request.h" /* OpenSSL Includes */ #include mb_queue_rsa2k_priv * mb_queue_rsa2k_priv_create() { mb_queue_rsa2k_priv *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_rsa2k_priv)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_rsa2k_priv_disable(mb_queue_rsa2k_priv *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_rsa2k_priv_cleanup(mb_queue_rsa2k_priv *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_rsa2k_priv_enqueue(mb_queue_rsa2k_priv *queue, rsa_priv_op_data *item) { if (queue == NULL || item == NULL) { DEBUG("Queue NULL\n"); return 1; } if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } rsa_priv_op_data * mb_queue_rsa2k_priv_dequeue(mb_queue_rsa2k_priv *queue) { rsa_priv_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_rsa2k_priv_get_size(mb_queue_rsa2k_priv *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_rsa2k_pub * mb_queue_rsa2k_pub_create() { mb_queue_rsa2k_pub *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_rsa2k_pub)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_rsa2k_pub_disable(mb_queue_rsa2k_pub *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_rsa2k_pub_cleanup(mb_queue_rsa2k_pub *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_rsa2k_pub_enqueue(mb_queue_rsa2k_pub *queue, rsa_pub_op_data *item) { if (queue == NULL || item == NULL) { DEBUG("Queue NULL\n"); return 1; } if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } rsa_pub_op_data * mb_queue_rsa2k_pub_dequeue(mb_queue_rsa2k_pub *queue) { rsa_pub_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_rsa2k_pub_get_size(mb_queue_rsa2k_pub *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_rsa3k_priv * mb_queue_rsa3k_priv_create() { mb_queue_rsa3k_priv *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_rsa3k_priv)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_rsa3k_priv_disable(mb_queue_rsa3k_priv *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_rsa3k_priv_cleanup(mb_queue_rsa3k_priv *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_rsa3k_priv_enqueue(mb_queue_rsa3k_priv *queue, rsa_priv_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } rsa_priv_op_data * mb_queue_rsa3k_priv_dequeue(mb_queue_rsa3k_priv *queue) { rsa_priv_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_rsa3k_priv_get_size(mb_queue_rsa3k_priv *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_rsa3k_pub * mb_queue_rsa3k_pub_create() { mb_queue_rsa3k_pub *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_rsa3k_pub)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_rsa3k_pub_disable(mb_queue_rsa3k_pub *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_rsa3k_pub_cleanup(mb_queue_rsa3k_pub *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_rsa3k_pub_enqueue(mb_queue_rsa3k_pub *queue, rsa_pub_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } rsa_pub_op_data * mb_queue_rsa3k_pub_dequeue(mb_queue_rsa3k_pub *queue) { rsa_pub_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_rsa3k_pub_get_size(mb_queue_rsa3k_pub *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_rsa4k_priv * mb_queue_rsa4k_priv_create() { mb_queue_rsa4k_priv *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_rsa4k_priv)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_rsa4k_priv_disable(mb_queue_rsa4k_priv *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_rsa4k_priv_cleanup(mb_queue_rsa4k_priv *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_rsa4k_priv_enqueue(mb_queue_rsa4k_priv *queue, rsa_priv_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } rsa_priv_op_data * mb_queue_rsa4k_priv_dequeue(mb_queue_rsa4k_priv *queue) { rsa_priv_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_rsa4k_priv_get_size(mb_queue_rsa4k_priv *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_rsa4k_pub * mb_queue_rsa4k_pub_create() { mb_queue_rsa4k_pub *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_rsa4k_pub)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_rsa4k_pub_disable(mb_queue_rsa4k_pub *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_rsa4k_pub_cleanup(mb_queue_rsa4k_pub *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_rsa4k_pub_enqueue(mb_queue_rsa4k_pub *queue, rsa_pub_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } rsa_pub_op_data * mb_queue_rsa4k_pub_dequeue(mb_queue_rsa4k_pub *queue) { rsa_pub_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_rsa4k_pub_get_size(mb_queue_rsa4k_pub *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_x25519_keygen * mb_queue_x25519_keygen_create() { mb_queue_x25519_keygen *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_x25519_keygen)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_x25519_keygen_disable(mb_queue_x25519_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_x25519_keygen_cleanup(mb_queue_x25519_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_x25519_keygen_enqueue(mb_queue_x25519_keygen *queue, x25519_keygen_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } x25519_keygen_op_data * mb_queue_x25519_keygen_dequeue(mb_queue_x25519_keygen *queue) { x25519_keygen_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_x25519_keygen_get_size(mb_queue_x25519_keygen *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_x25519_derive * mb_queue_x25519_derive_create() { mb_queue_x25519_derive *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_x25519_derive)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_x25519_derive_disable(mb_queue_x25519_derive *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_x25519_derive_cleanup(mb_queue_x25519_derive *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_x25519_derive_enqueue(mb_queue_x25519_derive *queue, x25519_derive_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } x25519_derive_op_data * mb_queue_x25519_derive_dequeue(mb_queue_x25519_derive *queue) { x25519_derive_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_x25519_derive_get_size(mb_queue_x25519_derive *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap256_sign * mb_queue_ecdsap256_sign_create() { mb_queue_ecdsap256_sign *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap256_sign)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap256_sign_disable(mb_queue_ecdsap256_sign *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap256_sign_cleanup(mb_queue_ecdsap256_sign *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap256_sign_enqueue(mb_queue_ecdsap256_sign *queue, ecdsa_sign_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sign_op_data *mb_queue_ecdsap256_sign_dequeue(mb_queue_ecdsap256_sign *queue) { ecdsa_sign_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap256_sign_get_size(mb_queue_ecdsap256_sign *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap256_sign_setup * mb_queue_ecdsap256_sign_setup_create() { mb_queue_ecdsap256_sign_setup *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap256_sign_setup)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap256_sign_setup_disable(mb_queue_ecdsap256_sign_setup *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap256_sign_setup_cleanup(mb_queue_ecdsap256_sign_setup *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap256_sign_setup_enqueue(mb_queue_ecdsap256_sign_setup *queue, ecdsa_sign_setup_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sign_setup_op_data *mb_queue_ecdsap256_sign_setup_dequeue(mb_queue_ecdsap256_sign_setup *queue) { ecdsa_sign_setup_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap256_sign_setup_get_size(mb_queue_ecdsap256_sign_setup *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap256_sign_sig * mb_queue_ecdsap256_sign_sig_create() { mb_queue_ecdsap256_sign_sig *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap256_sign_sig)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap256_sign_sig_disable(mb_queue_ecdsap256_sign_sig *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap256_sign_sig_cleanup(mb_queue_ecdsap256_sign_sig *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap256_sign_sig_enqueue(mb_queue_ecdsap256_sign_sig *queue, ecdsa_sign_sig_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sign_sig_op_data *mb_queue_ecdsap256_sign_sig_dequeue(mb_queue_ecdsap256_sign_sig *queue) { ecdsa_sign_sig_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap256_sign_sig_get_size(mb_queue_ecdsap256_sign_sig *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap256_verify * mb_queue_ecdsap256_verify_create() { mb_queue_ecdsap256_verify *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap256_verify)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap256_verify_disable(mb_queue_ecdsap256_verify *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap256_verify_cleanup(mb_queue_ecdsap256_verify *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap256_verify_enqueue(mb_queue_ecdsap256_verify *queue, ecdsa_verify_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_verify_op_data *mb_queue_ecdsap256_verify_dequeue(mb_queue_ecdsap256_verify *queue) { ecdsa_verify_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap256_verify_get_size(mb_queue_ecdsap256_verify *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdhp256_keygen * mb_queue_ecdhp256_keygen_create() { mb_queue_ecdhp256_keygen *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdhp256_keygen)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdhp256_keygen_disable(mb_queue_ecdhp256_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdhp256_keygen_cleanup(mb_queue_ecdhp256_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdhp256_keygen_enqueue(mb_queue_ecdhp256_keygen *queue, ecdh_keygen_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdh_keygen_op_data *mb_queue_ecdhp256_keygen_dequeue(mb_queue_ecdhp256_keygen *queue) { ecdh_keygen_op_data *item = NULL; if (queue == NULL) { return NULL; } if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdhp256_keygen_get_size(mb_queue_ecdhp256_keygen *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdhp256_compute * mb_queue_ecdhp256_compute_create() { mb_queue_ecdhp256_compute *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdhp256_compute)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdhp256_compute_disable(mb_queue_ecdhp256_compute *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdhp256_compute_cleanup(mb_queue_ecdhp256_compute *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdhp256_compute_enqueue(mb_queue_ecdhp256_compute *queue, ecdh_compute_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdh_compute_op_data *mb_queue_ecdhp256_compute_dequeue(mb_queue_ecdhp256_compute *queue) { ecdh_compute_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdhp256_compute_get_size(mb_queue_ecdhp256_compute *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdhp384_keygen * mb_queue_ecdhp384_keygen_create() { mb_queue_ecdhp384_keygen *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdhp384_keygen)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdhp384_keygen_disable(mb_queue_ecdhp384_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdhp384_keygen_cleanup(mb_queue_ecdhp384_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdhp384_keygen_enqueue(mb_queue_ecdhp384_keygen *queue, ecdh_keygen_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdh_keygen_op_data *mb_queue_ecdhp384_keygen_dequeue(mb_queue_ecdhp384_keygen *queue) { ecdh_keygen_op_data *item = NULL; if (queue == NULL) { return NULL; } if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdhp384_keygen_get_size(mb_queue_ecdhp384_keygen *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdhp384_compute * mb_queue_ecdhp384_compute_create() { mb_queue_ecdhp384_compute *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdhp384_compute)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdhp384_compute_disable(mb_queue_ecdhp384_compute *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdhp384_compute_cleanup(mb_queue_ecdhp384_compute *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdhp384_compute_enqueue(mb_queue_ecdhp384_compute *queue, ecdh_compute_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdh_compute_op_data * mb_queue_ecdhp384_compute_dequeue(mb_queue_ecdhp384_compute *queue) { ecdh_compute_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdhp384_compute_get_size(mb_queue_ecdhp384_compute *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap384_sign * mb_queue_ecdsap384_sign_create() { mb_queue_ecdsap384_sign *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap384_sign)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap384_sign_disable(mb_queue_ecdsap384_sign *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap384_sign_cleanup(mb_queue_ecdsap384_sign *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap384_sign_enqueue(mb_queue_ecdsap384_sign *queue, ecdsa_sign_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sign_op_data * mb_queue_ecdsap384_sign_dequeue(mb_queue_ecdsap384_sign *queue) { ecdsa_sign_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap384_sign_get_size(mb_queue_ecdsap384_sign *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap384_sign_setup * mb_queue_ecdsap384_sign_setup_create() { mb_queue_ecdsap384_sign_setup *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap384_sign_setup)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap384_sign_setup_disable(mb_queue_ecdsap384_sign_setup *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap384_sign_setup_cleanup(mb_queue_ecdsap384_sign_setup *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap384_sign_setup_enqueue(mb_queue_ecdsap384_sign_setup *queue, ecdsa_sign_setup_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sign_setup_op_data *mb_queue_ecdsap384_sign_setup_dequeue(mb_queue_ecdsap384_sign_setup *queue) { ecdsa_sign_setup_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap384_sign_setup_get_size(mb_queue_ecdsap384_sign_setup *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap384_sign_sig * mb_queue_ecdsap384_sign_sig_create() { mb_queue_ecdsap384_sign_sig *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap384_sign_sig)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap384_sign_sig_disable(mb_queue_ecdsap384_sign_sig *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap384_sign_sig_cleanup(mb_queue_ecdsap384_sign_sig *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap384_sign_sig_enqueue(mb_queue_ecdsap384_sign_sig *queue, ecdsa_sign_sig_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sign_sig_op_data *mb_queue_ecdsap384_sign_sig_dequeue(mb_queue_ecdsap384_sign_sig *queue) { ecdsa_sign_sig_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap384_sign_sig_get_size(mb_queue_ecdsap384_sign_sig *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsap384_verify * mb_queue_ecdsap384_verify_create() { mb_queue_ecdsap384_verify *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsap384_verify)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsap384_verify_disable(mb_queue_ecdsap384_verify *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsap384_verify_cleanup(mb_queue_ecdsap384_verify *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsap384_verify_enqueue(mb_queue_ecdsap384_verify *queue, ecdsa_verify_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_verify_op_data *mb_queue_ecdsap384_verify_dequeue(mb_queue_ecdsap384_verify *queue) { ecdsa_verify_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsap384_verify_get_size(mb_queue_ecdsap384_verify *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm2ecdh_keygen * mb_queue_sm2ecdh_keygen_create() { mb_queue_sm2ecdh_keygen *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm2ecdh_keygen)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm2ecdh_keygen_disable(mb_queue_sm2ecdh_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm2ecdh_keygen_cleanup(mb_queue_sm2ecdh_keygen *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm2ecdh_keygen_enqueue(mb_queue_sm2ecdh_keygen *queue, ecdh_keygen_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdh_keygen_op_data *mb_queue_sm2ecdh_keygen_dequeue(mb_queue_sm2ecdh_keygen *queue) { ecdh_keygen_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm2ecdh_keygen_get_size(mb_queue_sm2ecdh_keygen *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm2ecdh_compute * mb_queue_sm2ecdh_compute_create() { mb_queue_sm2ecdh_compute *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm2ecdh_compute)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm2ecdh_compute_disable(mb_queue_sm2ecdh_compute *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm2ecdh_compute_cleanup(mb_queue_sm2ecdh_compute *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm2ecdh_compute_enqueue(mb_queue_sm2ecdh_compute *queue, ecdh_compute_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdh_compute_op_data *mb_queue_sm2ecdh_compute_dequeue(mb_queue_sm2ecdh_compute *queue) { ecdh_compute_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm2ecdh_compute_get_size(mb_queue_sm2ecdh_compute *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm3_init * mb_queue_sm3_init_create() { mb_queue_sm3_init *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm3_init)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm3_init_disable(mb_queue_sm3_init *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm3_init_cleanup(mb_queue_sm3_init *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm3_init_enqueue(mb_queue_sm3_init *queue, sm3_init_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm3_init_op_data *mb_queue_sm3_init_dequeue(mb_queue_sm3_init *queue) { sm3_init_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm3_init_get_size(mb_queue_sm3_init *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm3_update * mb_queue_sm3_update_create() { mb_queue_sm3_update *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm3_update)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm3_update_disable(mb_queue_sm3_update *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm3_update_cleanup(mb_queue_sm3_update *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm3_update_enqueue(mb_queue_sm3_update *queue, sm3_update_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm3_update_op_data *mb_queue_sm3_update_dequeue(mb_queue_sm3_update *queue) { sm3_update_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm3_update_get_size(mb_queue_sm3_update *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm3_final * mb_queue_sm3_final_create() { mb_queue_sm3_final *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm3_final)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm3_final_disable(mb_queue_sm3_final *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm3_final_cleanup(mb_queue_sm3_final *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm3_final_enqueue(mb_queue_sm3_final *queue, sm3_final_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm3_final_op_data *mb_queue_sm3_final_dequeue(mb_queue_sm3_final *queue) { sm3_final_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm3_final_get_size(mb_queue_sm3_final *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsa_sm2_sign * mb_queue_ecdsa_sm2_sign_create() { mb_queue_ecdsa_sm2_sign *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsa_sm2_sign)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsa_sm2_sign_disable(mb_queue_ecdsa_sm2_sign *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsa_sm2_sign_cleanup(mb_queue_ecdsa_sm2_sign *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsa_sm2_sign_enqueue(mb_queue_ecdsa_sm2_sign *queue, ecdsa_sm2_sign_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sm2_sign_op_data *mb_queue_ecdsa_sm2_sign_dequeue(mb_queue_ecdsa_sm2_sign *queue) { ecdsa_sm2_sign_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsa_sm2_sign_get_size(mb_queue_ecdsa_sm2_sign *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_ecdsa_sm2_verify * mb_queue_ecdsa_sm2_verify_create() { mb_queue_ecdsa_sm2_verify *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_ecdsa_sm2_verify)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_ecdsa_sm2_verify_disable(mb_queue_ecdsa_sm2_verify *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_ecdsa_sm2_verify_cleanup(mb_queue_ecdsa_sm2_verify *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_ecdsa_sm2_verify_enqueue(mb_queue_ecdsa_sm2_verify *queue, ecdsa_sm2_verify_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } ecdsa_sm2_verify_op_data *mb_queue_ecdsa_sm2_verify_dequeue(mb_queue_ecdsa_sm2_verify *queue) { ecdsa_sm2_verify_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_ecdsa_sm2_verify_get_size(mb_queue_ecdsa_sm2_verify *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm4_cbc_cipher * mb_queue_sm4_cbc_cipher_create() { mb_queue_sm4_cbc_cipher *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm4_cbc_cipher)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm4_cbc_cipher_disable(mb_queue_sm4_cbc_cipher *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm4_cbc_cipher_dec_disable(mb_queue_sm4_cbc_cipher *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm4_cbc_cipher_cleanup(mb_queue_sm4_cbc_cipher *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm4_cbc_cipher_dec_cleanup(mb_queue_sm4_cbc_cipher *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm4_cbc_cipher_enqueue(mb_queue_sm4_cbc_cipher *queue, sm4_cbc_cipher_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm4_cbc_cipher_op_data *mb_queue_sm4_cbc_cipher_dequeue(mb_queue_sm4_cbc_cipher *queue) { sm4_cbc_cipher_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } sm4_cbc_cipher_op_data *mb_queue_sm4_cbc_cipher_dec_dequeue(mb_queue_sm4_cbc_cipher *queue) { sm4_cbc_cipher_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm4_cbc_cipher_get_size(mb_queue_sm4_cbc_cipher *queue) { if (queue == NULL) return 0; return queue->num_items; } #ifdef ENABLE_QAT_SW_SM4_GCM mb_queue_sm4_gcm_encrypt * mb_queue_sm4_gcm_encrypt_create() { mb_queue_sm4_gcm_encrypt *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm4_gcm_encrypt)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm4_gcm_encrypt_disable(mb_queue_sm4_gcm_encrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm4_gcm_encrypt_cleanup(mb_queue_sm4_gcm_encrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm4_gcm_encrypt_enqueue(mb_queue_sm4_gcm_encrypt *queue, sm4_gcm_encrypt_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm4_gcm_encrypt_op_data *mb_queue_sm4_gcm_encrypt_dequeue(mb_queue_sm4_gcm_encrypt *queue) { sm4_gcm_encrypt_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm4_gcm_encrypt_get_size(mb_queue_sm4_gcm_encrypt *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm4_gcm_decrypt * mb_queue_sm4_gcm_decrypt_create() { mb_queue_sm4_gcm_decrypt *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm4_gcm_decrypt)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm4_gcm_decrypt_disable(mb_queue_sm4_gcm_decrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm4_gcm_decrypt_cleanup(mb_queue_sm4_gcm_decrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm4_gcm_decrypt_enqueue(mb_queue_sm4_gcm_decrypt *queue, sm4_gcm_decrypt_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm4_gcm_decrypt_op_data *mb_queue_sm4_gcm_decrypt_dequeue(mb_queue_sm4_gcm_decrypt *queue) { sm4_gcm_decrypt_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm4_gcm_decrypt_get_size(mb_queue_sm4_gcm_decrypt *queue) { if (queue == NULL) return 0; return queue->num_items; } #endif #ifdef ENABLE_QAT_SW_SM4_CCM mb_queue_sm4_ccm_encrypt * mb_queue_sm4_ccm_encrypt_create() { mb_queue_sm4_ccm_encrypt *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm4_ccm_encrypt)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm4_ccm_encrypt_disable(mb_queue_sm4_ccm_encrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm4_ccm_encrypt_cleanup(mb_queue_sm4_ccm_encrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm4_ccm_encrypt_enqueue(mb_queue_sm4_ccm_encrypt *queue, sm4_ccm_encrypt_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm4_ccm_encrypt_op_data *mb_queue_sm4_ccm_encrypt_dequeue(mb_queue_sm4_ccm_encrypt *queue) { sm4_ccm_encrypt_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm4_ccm_encrypt_get_size(mb_queue_sm4_ccm_encrypt *queue) { if (queue == NULL) return 0; return queue->num_items; } mb_queue_sm4_ccm_decrypt * mb_queue_sm4_ccm_decrypt_create() { mb_queue_sm4_ccm_decrypt *queue = NULL; queue = OPENSSL_zalloc(sizeof(mb_queue_sm4_ccm_decrypt)); if (queue == NULL) return NULL; DEBUG("Queue Created %p\n", queue); if (!enable_external_polling) { pthread_mutex_init(&queue->mb_queue_mutex, NULL); pthread_mutex_lock(&queue->mb_queue_mutex); } queue->head = NULL; queue->tail = NULL; queue->disabled = 0; queue->num_items = 0; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return queue; } int mb_queue_sm4_ccm_decrypt_disable(mb_queue_sm4_ccm_decrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); queue->disabled = 1; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } int mb_queue_sm4_ccm_decrypt_cleanup(mb_queue_sm4_ccm_decrypt *queue) { if (queue == NULL) return 1; if (!enable_external_polling) { pthread_mutex_destroy(&queue->mb_queue_mutex); OPENSSL_free(queue); } DEBUG("Queue Freed%p\n", queue); return 0; } int mb_queue_sm4_ccm_decrypt_enqueue(mb_queue_sm4_ccm_decrypt *queue, sm4_ccm_decrypt_op_data *item) { if (queue == NULL || item == NULL) return 1; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->disabled == 1) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 1; } if (queue->num_items == 0) { queue->tail = item; queue->head = item; } else { queue->tail->next = item; queue->tail = item; } queue->tail->next = NULL; queue->num_items++; if (enable_heuristic_polling) { QAT_ATOMIC_INC(num_asym_mb_items_in_queue); } if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return 0; } sm4_ccm_decrypt_op_data *mb_queue_sm4_ccm_decrypt_dequeue(mb_queue_sm4_ccm_decrypt *queue) { sm4_ccm_decrypt_op_data *item = NULL; if (queue == NULL) return NULL; if (!enable_external_polling) pthread_mutex_lock(&queue->mb_queue_mutex); if (queue->head == NULL) { if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return NULL; } item = queue->head; queue->head = item->next; queue->num_items--; if (enable_heuristic_polling) { QAT_ATOMIC_DEC(num_asym_mb_items_in_queue); } if (queue->num_items == 0) queue->tail = NULL; if (!enable_external_polling) pthread_mutex_unlock(&queue->mb_queue_mutex); return item; } int mb_queue_sm4_ccm_decrypt_get_size(mb_queue_sm4_ccm_decrypt *queue) { if (queue == NULL) return 0; return queue->num_items; } #endif qatengine-1.9.0/qat_sw_queue.h000066400000000000000000000611311500416242000163430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_queue.h * * This file provides the data structure for storing up multibuff requests * so multiple request can be processed in one operation. * *****************************************************************************/ #ifndef QAT_SW_QUEUE_H # define QAT_SW_QUEUE_H # include # include "qat_sw_request.h" typedef struct _mb_queue_rsa2k_priv { pthread_mutex_t mb_queue_mutex; rsa_priv_op_data *head; rsa_priv_op_data *tail; int num_items; int disabled; } mb_queue_rsa2k_priv; typedef struct _mb_queue_rsa2k_pub { pthread_mutex_t mb_queue_mutex; rsa_pub_op_data *head; rsa_pub_op_data *tail; int num_items; int disabled; } mb_queue_rsa2k_pub; typedef struct _mb_queue_rsa3k_priv { pthread_mutex_t mb_queue_mutex; rsa_priv_op_data *head; rsa_priv_op_data *tail; int num_items; int disabled; } mb_queue_rsa3k_priv; typedef struct _mb_queue_rsa3k_pub { pthread_mutex_t mb_queue_mutex; rsa_pub_op_data *head; rsa_pub_op_data *tail; int num_items; int disabled; } mb_queue_rsa3k_pub; typedef struct _mb_queue_rsa4k_priv { pthread_mutex_t mb_queue_mutex; rsa_priv_op_data *head; rsa_priv_op_data *tail; int num_items; int disabled; } mb_queue_rsa4k_priv; typedef struct _mb_queue_rsa4k_pub { pthread_mutex_t mb_queue_mutex; rsa_pub_op_data *head; rsa_pub_op_data *tail; int num_items; int disabled; } mb_queue_rsa4k_pub; typedef struct _mb_queue_x25519_keygen { pthread_mutex_t mb_queue_mutex; x25519_keygen_op_data *head; x25519_keygen_op_data *tail; int num_items; int disabled; } mb_queue_x25519_keygen; typedef struct _mb_queue_x25519_derive { pthread_mutex_t mb_queue_mutex; x25519_derive_op_data *head; x25519_derive_op_data *tail; int num_items; int disabled; } mb_queue_x25519_derive; typedef struct _mb_queue_ecdsap256_sign { pthread_mutex_t mb_queue_mutex; ecdsa_sign_op_data *head; ecdsa_sign_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap256_sign; typedef struct _mb_queue_ecdsap256_sign_setup { pthread_mutex_t mb_queue_mutex; ecdsa_sign_setup_op_data *head; ecdsa_sign_setup_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap256_sign_setup; typedef struct _mb_queue_ecdsap256_sign_sig { pthread_mutex_t mb_queue_mutex; ecdsa_sign_sig_op_data *head; ecdsa_sign_sig_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap256_sign_sig; typedef struct _mb_queue_ecdsap256_verify { pthread_mutex_t mb_queue_mutex; ecdsa_verify_op_data *head; ecdsa_verify_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap256_verify; typedef struct _mb_queue_ecdsap384_sign { pthread_mutex_t mb_queue_mutex; ecdsa_sign_op_data *head; ecdsa_sign_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap384_sign; typedef struct _mb_queue_ecdsap384_sign_setup { pthread_mutex_t mb_queue_mutex; ecdsa_sign_setup_op_data *head; ecdsa_sign_setup_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap384_sign_setup; typedef struct _mb_queue_ecdsap384_sign_sig { pthread_mutex_t mb_queue_mutex; ecdsa_sign_sig_op_data *head; ecdsa_sign_sig_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap384_sign_sig; typedef struct _mb_queue_ecdsap384_verify { pthread_mutex_t mb_queue_mutex; ecdsa_verify_op_data *head; ecdsa_verify_op_data *tail; int num_items; int disabled; } mb_queue_ecdsap384_verify; typedef struct _mb_queue_ecdhp256_keygen { pthread_mutex_t mb_queue_mutex; ecdh_keygen_op_data *head; ecdh_keygen_op_data *tail; int num_items; int disabled; } mb_queue_ecdhp256_keygen; typedef struct _mb_queue_ecdhp256_compute { pthread_mutex_t mb_queue_mutex; ecdh_compute_op_data *head; ecdh_compute_op_data *tail; int num_items; int disabled; } mb_queue_ecdhp256_compute; typedef struct _mb_queue_ecdhp384_keygen { pthread_mutex_t mb_queue_mutex; ecdh_keygen_op_data *head; ecdh_keygen_op_data *tail; int num_items; int disabled; } mb_queue_ecdhp384_keygen; typedef struct _mb_queue_ecdhp384_compute { pthread_mutex_t mb_queue_mutex; ecdh_compute_op_data *head; ecdh_compute_op_data *tail; int num_items; int disabled; } mb_queue_ecdhp384_compute; typedef struct _mb_queue_sm2ecdh_keygen { pthread_mutex_t mb_queue_mutex; ecdh_keygen_op_data *head; ecdh_keygen_op_data *tail; int num_items; int disabled; } mb_queue_sm2ecdh_keygen; typedef struct _mb_queue_sm2ecdh_compute { pthread_mutex_t mb_queue_mutex; ecdh_compute_op_data *head; ecdh_compute_op_data *tail; int num_items; int disabled; } mb_queue_sm2ecdh_compute; typedef struct _mb_queue_ecdsa_sm2_sign { pthread_mutex_t mb_queue_mutex; ecdsa_sm2_sign_op_data *head; ecdsa_sm2_sign_op_data *tail; int num_items; int disabled; } mb_queue_ecdsa_sm2_sign; typedef struct _mb_queue_ecdsa_sm2_verify { pthread_mutex_t mb_queue_mutex; ecdsa_sm2_verify_op_data *head; ecdsa_sm2_verify_op_data *tail; int num_items; int disabled; } mb_queue_ecdsa_sm2_verify; typedef struct _mb_queue_sm3_init { pthread_mutex_t mb_queue_mutex; sm3_init_op_data *head; sm3_init_op_data *tail; int num_items; int disabled; } mb_queue_sm3_init; typedef struct _mb_queue_sm3_update { pthread_mutex_t mb_queue_mutex; sm3_update_op_data *head; sm3_update_op_data *tail; int num_items; int disabled; } mb_queue_sm3_update; typedef struct _mb_queue_sm3_final { pthread_mutex_t mb_queue_mutex; sm3_final_op_data *head; sm3_final_op_data *tail; int num_items; int disabled; } mb_queue_sm3_final; typedef struct _mb_queue_sm4_cbc_cipher { pthread_mutex_t mb_queue_mutex; sm4_cbc_cipher_op_data *head; sm4_cbc_cipher_op_data *tail; int num_items; int disabled; } mb_queue_sm4_cbc_cipher; # ifdef ENABLE_QAT_SW_SM4_GCM typedef struct _mb_queue_sm4_gcm_encrypt { pthread_mutex_t mb_queue_mutex; sm4_gcm_encrypt_op_data *head; sm4_gcm_encrypt_op_data *tail; int num_items; int disabled; } mb_queue_sm4_gcm_encrypt; typedef struct _mb_queue_sm4_gcm_decrypt { pthread_mutex_t mb_queue_mutex; sm4_gcm_decrypt_op_data *head; sm4_gcm_decrypt_op_data *tail; int num_items; int disabled; } mb_queue_sm4_gcm_decrypt; # endif # ifdef ENABLE_QAT_SW_SM4_CCM typedef struct _mb_queue_sm4_ccm_encrypt { pthread_mutex_t mb_queue_mutex; sm4_ccm_encrypt_op_data *head; sm4_ccm_encrypt_op_data *tail; int num_items; int disabled; } mb_queue_sm4_ccm_encrypt; typedef struct _mb_queue_sm4_ccm_decrypt { pthread_mutex_t mb_queue_mutex; sm4_ccm_decrypt_op_data *head; sm4_ccm_decrypt_op_data *tail; int num_items; int disabled; } mb_queue_sm4_ccm_decrypt; # endif mb_queue_rsa2k_priv * mb_queue_rsa2k_priv_create(); int mb_queue_rsa2k_priv_disable(mb_queue_rsa2k_priv * queue); int mb_queue_rsa2k_priv_cleanup(mb_queue_rsa2k_priv * queue); int mb_queue_rsa2k_priv_enqueue(mb_queue_rsa2k_priv *queue, rsa_priv_op_data *item); rsa_priv_op_data * mb_queue_rsa2k_priv_dequeue(mb_queue_rsa2k_priv *queue); int mb_queue_rsa2k_priv_get_size(mb_queue_rsa2k_priv *queue); mb_queue_rsa2k_pub * mb_queue_rsa2k_pub_create(); int mb_queue_rsa2k_pub_disable(mb_queue_rsa2k_pub * queue); int mb_queue_rsa2k_pub_cleanup(mb_queue_rsa2k_pub * queue); int mb_queue_rsa2k_pub_enqueue(mb_queue_rsa2k_pub *queue, rsa_pub_op_data *item); rsa_pub_op_data * mb_queue_rsa2k_pub_dequeue(mb_queue_rsa2k_pub *queue); int mb_queue_rsa2k_pub_get_size(mb_queue_rsa2k_pub *queue); mb_queue_rsa3k_priv * mb_queue_rsa3k_priv_create(); int mb_queue_rsa3k_priv_disable(mb_queue_rsa3k_priv * queue); int mb_queue_rsa3k_priv_cleanup(mb_queue_rsa3k_priv * queue); int mb_queue_rsa3k_priv_enqueue(mb_queue_rsa3k_priv *queue, rsa_priv_op_data *item); rsa_priv_op_data * mb_queue_rsa3k_priv_dequeue(mb_queue_rsa3k_priv *queue); int mb_queue_rsa3k_priv_get_size(mb_queue_rsa3k_priv *queue); mb_queue_rsa3k_pub * mb_queue_rsa3k_pub_create(); int mb_queue_rsa3k_pub_disable(mb_queue_rsa3k_pub * queue); int mb_queue_rsa3k_pub_cleanup(mb_queue_rsa3k_pub * queue); int mb_queue_rsa3k_pub_enqueue(mb_queue_rsa3k_pub *queue, rsa_pub_op_data *item); rsa_pub_op_data * mb_queue_rsa3k_pub_dequeue(mb_queue_rsa3k_pub *queue); int mb_queue_rsa3k_pub_get_size(mb_queue_rsa3k_pub *queue); mb_queue_rsa4k_priv * mb_queue_rsa4k_priv_create(); int mb_queue_rsa4k_priv_disable(mb_queue_rsa4k_priv * queue); int mb_queue_rsa4k_priv_cleanup(mb_queue_rsa4k_priv * queue); int mb_queue_rsa4k_priv_enqueue(mb_queue_rsa4k_priv *queue, rsa_priv_op_data *item); rsa_priv_op_data * mb_queue_rsa4k_priv_dequeue(mb_queue_rsa4k_priv *queue); int mb_queue_rsa4k_priv_get_size(mb_queue_rsa4k_priv *queue); mb_queue_rsa4k_pub * mb_queue_rsa4k_pub_create(); int mb_queue_rsa4k_pub_disable(mb_queue_rsa4k_pub * queue); int mb_queue_rsa4k_pub_cleanup(mb_queue_rsa4k_pub * queue); int mb_queue_rsa4k_pub_enqueue(mb_queue_rsa4k_pub *queue, rsa_pub_op_data *item); rsa_pub_op_data * mb_queue_rsa4k_pub_dequeue(mb_queue_rsa4k_pub *queue); int mb_queue_rsa4k_pub_get_size(mb_queue_rsa4k_pub *queue); mb_queue_x25519_keygen * mb_queue_x25519_keygen_create(); int mb_queue_x25519_keygen_disable(mb_queue_x25519_keygen * queue); int mb_queue_x25519_keygen_cleanup(mb_queue_x25519_keygen * queue); int mb_queue_x25519_keygen_enqueue(mb_queue_x25519_keygen *queue, x25519_keygen_op_data *item); x25519_keygen_op_data *mb_queue_x25519_keygen_dequeue(mb_queue_x25519_keygen *queue); int mb_queue_x25519_keygen_get_size(mb_queue_x25519_keygen *queue); mb_queue_x25519_derive * mb_queue_x25519_derive_create(); int mb_queue_x25519_derive_disable(mb_queue_x25519_derive * queue); int mb_queue_x25519_derive_cleanup(mb_queue_x25519_derive * queue); int mb_queue_x25519_derive_enqueue(mb_queue_x25519_derive *queue, x25519_derive_op_data *item); x25519_derive_op_data *mb_queue_x25519_derive_dequeue(mb_queue_x25519_derive *queue); int mb_queue_x25519_derive_get_size(mb_queue_x25519_derive *queue); mb_queue_ecdsap256_sign * mb_queue_ecdsap256_sign_create(); int mb_queue_ecdsap256_sign_disable(mb_queue_ecdsap256_sign * queue); int mb_queue_ecdsap256_sign_cleanup(mb_queue_ecdsap256_sign * queue); int mb_queue_ecdsap256_sign_enqueue(mb_queue_ecdsap256_sign *queue, ecdsa_sign_op_data *item); ecdsa_sign_op_data *mb_queue_ecdsap256_sign_dequeue(mb_queue_ecdsap256_sign *queue); int mb_queue_ecdsap256_sign_get_size(mb_queue_ecdsap256_sign *queue); mb_queue_ecdsap256_sign_setup * mb_queue_ecdsap256_sign_setup_create(); int mb_queue_ecdsap256_sign_setup_disable(mb_queue_ecdsap256_sign_setup * queue); int mb_queue_ecdsap256_sign_setup_cleanup(mb_queue_ecdsap256_sign_setup * queue); int mb_queue_ecdsap256_sign_setup_enqueue(mb_queue_ecdsap256_sign_setup *queue, ecdsa_sign_setup_op_data *item); ecdsa_sign_setup_op_data *mb_queue_ecdsap256_sign_setup_dequeue(mb_queue_ecdsap256_sign_setup *queue); int mb_queue_ecdsap256_sign_setup_get_size(mb_queue_ecdsap256_sign_setup *queue); mb_queue_ecdsap256_sign_sig * mb_queue_ecdsap256_sign_sig_create(); int mb_queue_ecdsap256_sign_sig_disable(mb_queue_ecdsap256_sign_sig * queue); int mb_queue_ecdsap256_sign_sig_cleanup(mb_queue_ecdsap256_sign_sig * queue); int mb_queue_ecdsap256_sign_sig_enqueue(mb_queue_ecdsap256_sign_sig *queue, ecdsa_sign_sig_op_data *item); ecdsa_sign_sig_op_data *mb_queue_ecdsap256_sign_sig_dequeue(mb_queue_ecdsap256_sign_sig *queue); int mb_queue_ecdsap256_sign_sig_get_size(mb_queue_ecdsap256_sign_sig *queue); mb_queue_ecdsap256_verify * mb_queue_ecdsap256_verify_create(); int mb_queue_ecdsap256_verify_disable(mb_queue_ecdsap256_verify * queue); int mb_queue_ecdsap256_verify_cleanup(mb_queue_ecdsap256_verify * queue); int mb_queue_ecdsap256_verify_enqueue(mb_queue_ecdsap256_verify *queue, ecdsa_verify_op_data *item); ecdsa_verify_op_data *mb_queue_ecdsap256_verify_dequeue(mb_queue_ecdsap256_verify *queue); int mb_queue_ecdsap256_verify_get_size(mb_queue_ecdsap256_verify *queue); mb_queue_ecdsap384_sign * mb_queue_ecdsap384_sign_create(); int mb_queue_ecdsap384_sign_disable(mb_queue_ecdsap384_sign * queue); int mb_queue_ecdsap384_sign_cleanup(mb_queue_ecdsap384_sign * queue); int mb_queue_ecdsap384_sign_enqueue(mb_queue_ecdsap384_sign *queue, ecdsa_sign_op_data *item); ecdsa_sign_op_data *mb_queue_ecdsap384_sign_dequeue(mb_queue_ecdsap384_sign *queue); int mb_queue_ecdsap384_sign_get_size(mb_queue_ecdsap384_sign *queue); mb_queue_ecdsap384_sign_setup * mb_queue_ecdsap384_sign_setup_create(); int mb_queue_ecdsap384_sign_setup_disable(mb_queue_ecdsap384_sign_setup * queue); int mb_queue_ecdsap384_sign_setup_cleanup(mb_queue_ecdsap384_sign_setup * queue); int mb_queue_ecdsap384_sign_setup_enqueue(mb_queue_ecdsap384_sign_setup *queue, ecdsa_sign_setup_op_data *item); ecdsa_sign_setup_op_data *mb_queue_ecdsap384_sign_setup_dequeue(mb_queue_ecdsap384_sign_setup *queue); int mb_queue_ecdsap384_sign_setup_get_size(mb_queue_ecdsap384_sign_setup *queue); mb_queue_ecdsap384_sign_sig * mb_queue_ecdsap384_sign_sig_create(); int mb_queue_ecdsap384_sign_sig_disable(mb_queue_ecdsap384_sign_sig * queue); int mb_queue_ecdsap384_sign_sig_cleanup(mb_queue_ecdsap384_sign_sig * queue); int mb_queue_ecdsap384_sign_sig_enqueue(mb_queue_ecdsap384_sign_sig *queue, ecdsa_sign_sig_op_data *item); ecdsa_sign_sig_op_data *mb_queue_ecdsap384_sign_sig_dequeue(mb_queue_ecdsap384_sign_sig *queue); int mb_queue_ecdsap384_sign_sig_get_size(mb_queue_ecdsap384_sign_sig *queue); mb_queue_ecdsap384_verify * mb_queue_ecdsap384_verify_create(); int mb_queue_ecdsap384_verify_disable(mb_queue_ecdsap384_verify * queue); int mb_queue_ecdsap384_verify_cleanup(mb_queue_ecdsap384_verify * queue); int mb_queue_ecdsap384_verify_enqueue(mb_queue_ecdsap384_verify *queue, ecdsa_verify_op_data *item); ecdsa_verify_op_data *mb_queue_ecdsap384_verify_dequeue(mb_queue_ecdsap384_verify *queue); int mb_queue_ecdsap384_verify_get_size(mb_queue_ecdsap384_verify *queue); mb_queue_ecdhp256_keygen * mb_queue_ecdhp256_keygen_create(); int mb_queue_ecdhp256_keygen_disable(mb_queue_ecdhp256_keygen * queue); int mb_queue_ecdhp256_keygen_cleanup(mb_queue_ecdhp256_keygen * queue); int mb_queue_ecdhp256_keygen_enqueue(mb_queue_ecdhp256_keygen *queue, ecdh_keygen_op_data *item); ecdh_keygen_op_data *mb_queue_ecdhp256_keygen_dequeue(mb_queue_ecdhp256_keygen *queue); int mb_queue_ecdhp256_keygen_get_size(mb_queue_ecdhp256_keygen *queue); mb_queue_ecdhp256_compute * mb_queue_ecdhp256_compute_create(); int mb_queue_ecdhp256_compute_disable(mb_queue_ecdhp256_compute * queue); int mb_queue_ecdhp256_compute_cleanup(mb_queue_ecdhp256_compute * queue); int mb_queue_ecdhp256_compute_enqueue(mb_queue_ecdhp256_compute *queue, ecdh_compute_op_data *item); ecdh_compute_op_data *mb_queue_ecdhp256_compute_dequeue(mb_queue_ecdhp256_compute *queue); int mb_queue_ecdhp256_compute_get_size(mb_queue_ecdhp256_compute *queue); mb_queue_ecdhp384_keygen * mb_queue_ecdhp384_keygen_create(); int mb_queue_ecdhp384_keygen_disable(mb_queue_ecdhp384_keygen * queue); int mb_queue_ecdhp384_keygen_cleanup(mb_queue_ecdhp384_keygen * queue); int mb_queue_ecdhp384_keygen_enqueue(mb_queue_ecdhp384_keygen *queue, ecdh_keygen_op_data *item); ecdh_keygen_op_data *mb_queue_ecdhp384_keygen_dequeue(mb_queue_ecdhp384_keygen *queue); int mb_queue_ecdhp384_keygen_get_size(mb_queue_ecdhp384_keygen *queue); mb_queue_ecdhp384_compute * mb_queue_ecdhp384_compute_create(); int mb_queue_ecdhp384_compute_disable(mb_queue_ecdhp384_compute * queue); int mb_queue_ecdhp384_compute_cleanup(mb_queue_ecdhp384_compute * queue); int mb_queue_ecdhp384_compute_enqueue(mb_queue_ecdhp384_compute *queue, ecdh_compute_op_data *item); ecdh_compute_op_data *mb_queue_ecdhp384_compute_dequeue(mb_queue_ecdhp384_compute *queue); int mb_queue_ecdhp384_compute_get_size(mb_queue_ecdhp384_compute *queue); /* SM3 Init */ mb_queue_sm3_init * mb_queue_sm3_init_create(); int mb_queue_sm3_init_disable(mb_queue_sm3_init * queue); int mb_queue_sm3_init_cleanup(mb_queue_sm3_init * queue); int mb_queue_sm3_init_enqueue(mb_queue_sm3_init *queue, sm3_init_op_data *item); sm3_init_op_data *mb_queue_sm3_init_dequeue(mb_queue_sm3_init *queue); int mb_queue_sm3_init_get_size(mb_queue_sm3_init *queue); /* SM3 update */ mb_queue_sm3_update * mb_queue_sm3_update_create(); int mb_queue_sm3_update_disable(mb_queue_sm3_update * queue); int mb_queue_sm3_update_cleanup(mb_queue_sm3_update * queue); int mb_queue_sm3_update_enqueue(mb_queue_sm3_update *queue, sm3_update_op_data *item); sm3_update_op_data *mb_queue_sm3_update_dequeue(mb_queue_sm3_update *queue); int mb_queue_sm3_update_get_size(mb_queue_sm3_update *queue); /* SM3 Final */ mb_queue_sm3_final * mb_queue_sm3_final_create(); int mb_queue_sm3_final_disable(mb_queue_sm3_final * queue); int mb_queue_sm3_final_cleanup(mb_queue_sm3_final * queue); int mb_queue_sm3_final_enqueue(mb_queue_sm3_final *queue, sm3_final_op_data *item); sm3_final_op_data *mb_queue_sm3_final_dequeue(mb_queue_sm3_final *queue); int mb_queue_sm3_final_get_size(mb_queue_sm3_final *queue); mb_queue_sm2ecdh_keygen * mb_queue_sm2ecdh_keygen_create(); int mb_queue_sm2ecdh_keygen_disable(mb_queue_sm2ecdh_keygen * queue); int mb_queue_sm2ecdh_keygen_cleanup(mb_queue_sm2ecdh_keygen * queue); int mb_queue_sm2ecdh_keygen_enqueue(mb_queue_sm2ecdh_keygen *queue, ecdh_keygen_op_data *item); ecdh_keygen_op_data *mb_queue_sm2ecdh_keygen_dequeue(mb_queue_sm2ecdh_keygen *queue); int mb_queue_sm2ecdh_keygen_get_size(mb_queue_sm2ecdh_keygen *queue); mb_queue_sm2ecdh_compute * mb_queue_sm2ecdh_compute_create(); int mb_queue_sm2ecdh_compute_disable(mb_queue_sm2ecdh_compute * queue); int mb_queue_sm2ecdh_compute_cleanup(mb_queue_sm2ecdh_compute * queue); int mb_queue_sm2ecdh_compute_enqueue(mb_queue_sm2ecdh_compute *queue, ecdh_compute_op_data *item); ecdh_compute_op_data *mb_queue_sm2ecdh_compute_dequeue(mb_queue_sm2ecdh_compute *queue); int mb_queue_sm2ecdh_compute_get_size(mb_queue_sm2ecdh_compute *queue); mb_queue_ecdsa_sm2_sign * mb_queue_ecdsa_sm2_sign_create(); int mb_queue_ecdsa_sm2_sign_disable(mb_queue_ecdsa_sm2_sign * queue); int mb_queue_ecdsa_sm2_sign_cleanup(mb_queue_ecdsa_sm2_sign * queue); int mb_queue_ecdsa_sm2_sign_enqueue(mb_queue_ecdsa_sm2_sign *queue, ecdsa_sm2_sign_op_data *item); ecdsa_sm2_sign_op_data *mb_queue_ecdsa_sm2_sign_dequeue(mb_queue_ecdsa_sm2_sign *queue); int mb_queue_ecdsa_sm2_sign_get_size(mb_queue_ecdsa_sm2_sign *queue); mb_queue_ecdsa_sm2_verify * mb_queue_ecdsa_sm2_verify_create(); int mb_queue_ecdsa_sm2_verify_disable(mb_queue_ecdsa_sm2_verify * queue); int mb_queue_ecdsa_sm2_verify_cleanup(mb_queue_ecdsa_sm2_verify * queue); int mb_queue_ecdsa_sm2_verify_enqueue(mb_queue_ecdsa_sm2_verify *queue, ecdsa_sm2_verify_op_data *item); ecdsa_sm2_verify_op_data *mb_queue_ecdsa_sm2_verify_dequeue(mb_queue_ecdsa_sm2_verify *queue); int mb_queue_ecdsa_sm2_verify_get_size(mb_queue_ecdsa_sm2_verify *queue); /* SM4_CBC cipher */ mb_queue_sm4_cbc_cipher * mb_queue_sm4_cbc_cipher_create(); int mb_queue_sm4_cbc_cipher_disable(mb_queue_sm4_cbc_cipher * queue); int mb_queue_sm4_cbc_cipher_cleanup(mb_queue_sm4_cbc_cipher * queue); int mb_queue_sm4_cbc_cipher_enqueue(mb_queue_sm4_cbc_cipher *queue, sm4_cbc_cipher_op_data *item); sm4_cbc_cipher_op_data *mb_queue_sm4_cbc_cipher_dequeue(mb_queue_sm4_cbc_cipher *queue); int mb_queue_sm4_cbc_cipher_get_size(mb_queue_sm4_cbc_cipher *queue); int mb_queue_sm4_cbc_cipher_dec_disable(mb_queue_sm4_cbc_cipher * queue); int mb_queue_sm4_cbc_cipher_dec_cleanup(mb_queue_sm4_cbc_cipher * queue); sm4_cbc_cipher_op_data *mb_queue_sm4_cbc_cipher_dec_dequeue(mb_queue_sm4_cbc_cipher *queue); /* SM4_GCM encrypt */ # ifdef ENABLE_QAT_SW_SM4_GCM mb_queue_sm4_gcm_encrypt * mb_queue_sm4_gcm_encrypt_create(); int mb_queue_sm4_gcm_encrypt_disable(mb_queue_sm4_gcm_encrypt * queue); int mb_queue_sm4_gcm_encrypt_cleanup(mb_queue_sm4_gcm_encrypt * queue); int mb_queue_sm4_gcm_encrypt_enqueue(mb_queue_sm4_gcm_encrypt *queue, sm4_gcm_encrypt_op_data *item); sm4_gcm_encrypt_op_data *mb_queue_sm4_gcm_encrypt_dequeue(mb_queue_sm4_gcm_encrypt *queue); int mb_queue_sm4_gcm_encrypt_get_size(mb_queue_sm4_gcm_encrypt *queue); /* SM4_GCM decrypt */ mb_queue_sm4_gcm_decrypt * mb_queue_sm4_gcm_decrypt_create(); int mb_queue_sm4_gcm_decrypt_disable(mb_queue_sm4_gcm_decrypt * queue); int mb_queue_sm4_gcm_decrypt_cleanup(mb_queue_sm4_gcm_decrypt * queue); int mb_queue_sm4_gcm_decrypt_enqueue(mb_queue_sm4_gcm_decrypt *queue, sm4_gcm_decrypt_op_data *item); sm4_gcm_decrypt_op_data *mb_queue_sm4_gcm_decrypt_dequeue(mb_queue_sm4_gcm_decrypt *queue); int mb_queue_sm4_gcm_decrypt_get_size(mb_queue_sm4_gcm_decrypt *queue); # endif /* ENABLE_QAT_SW_SM4_GCM */ /* SM4_CCM */ # ifdef ENABLE_QAT_SW_SM4_CCM mb_queue_sm4_ccm_encrypt * mb_queue_sm4_ccm_encrypt_create(); int mb_queue_sm4_ccm_encrypt_disable(mb_queue_sm4_ccm_encrypt * queue); int mb_queue_sm4_ccm_encrypt_cleanup(mb_queue_sm4_ccm_encrypt * queue); int mb_queue_sm4_ccm_encrypt_enqueue(mb_queue_sm4_ccm_encrypt *queue, sm4_ccm_encrypt_op_data *item); sm4_ccm_encrypt_op_data *mb_queue_sm4_ccm_encrypt_dequeue(mb_queue_sm4_ccm_encrypt *queue); int mb_queue_sm4_ccm_encrypt_get_size(mb_queue_sm4_ccm_encrypt *queue); mb_queue_sm4_ccm_decrypt * mb_queue_sm4_ccm_decrypt_create(); int mb_queue_sm4_ccm_decrypt_disable(mb_queue_sm4_ccm_decrypt * queue); int mb_queue_sm4_ccm_decrypt_cleanup(mb_queue_sm4_ccm_decrypt * queue); int mb_queue_sm4_ccm_decrypt_enqueue(mb_queue_sm4_ccm_decrypt *queue, sm4_ccm_decrypt_op_data *item); sm4_ccm_decrypt_op_data *mb_queue_sm4_ccm_decrypt_dequeue(mb_queue_sm4_ccm_decrypt *queue); int mb_queue_sm4_ccm_decrypt_get_size(mb_queue_sm4_ccm_decrypt *queue); # endif /* ENABLE_QAT_SW_SM4_CCM */ #endif /* QAT_SW_QUEUE_H */ qatengine-1.9.0/qat_sw_request.h000066400000000000000000000234431500416242000167130ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_request.h * * This file provides the data structure for buffering multibuff requests * *****************************************************************************/ #ifndef QAT_SW_REQUEST_H # define QAT_SW_REQUEST_H # include # include # include # include # ifndef QAT_BORINGSSL # include # endif /* QAT_BORINGSSL */ # include # include "qat_common.h" /* Crypto_mb includes */ #include "crypto_mb/sm3.h" #include "crypto_mb/sm4.h" # ifdef ENABLE_QAT_SW_SM4_GCM # include "crypto_mb/sm4_gcm.h" # endif # ifdef ENABLE_QAT_SW_SM4_CCM # include "crypto_mb/sm4_ccm.h" # endif # define IV_LEN 16 # pragma pack(push, 1) typedef struct _sm3_context{ int msg_buff_idx; unsigned long long msg_len; unsigned char msg_buffer[SM3_MSG_BLOCK_SIZE]; unsigned int msg_hash[SM3_SIZE_IN_WORDS]; EVP_MD *sw_md; EVP_MD_CTX *sw_md_ctx; } QAT_SM3_CTX_mb; # pragma pack(pop) typedef struct _rsa_priv_op_data { struct _rsa_priv_op_data *next; struct _rsa_priv_op_data *prev; int type; int flen; const unsigned char * from; unsigned char padded_buf[512]; unsigned char *to; unsigned char lenstra_to[512]; const BIGNUM *d; const BIGNUM *e; const BIGNUM *n; const BIGNUM *p; const BIGNUM *q; const BIGNUM *dmp1; const BIGNUM *dmq1; const BIGNUM *iqmp; RSA *rsa; int padding; ASYNC_JOB *job; int *sts; int disable_lenstra_check; } rsa_priv_op_data; typedef struct _rsa_pub_op_data { struct _rsa_pub_op_data *next; struct _rsa_pub_op_data *prev; int type; int flen; const unsigned char *from; unsigned char padded_buf[512]; unsigned char *to; const BIGNUM *e; const BIGNUM *n; RSA *rsa; int padding; ASYNC_JOB *job; int *sts; } rsa_pub_op_data; typedef struct _x25519_keygen_op_data { struct _x25519_keygen_op_data *next; struct _x25519_keygen_op_data *prev; EVP_PKEY *pkey; const unsigned char *privkey; unsigned char *pubkey; QAT_SW_ECX_KEY *key; ASYNC_JOB *job; int *sts; } x25519_keygen_op_data; typedef struct _x25519_derive_op_data { struct _x25519_derive_op_data *next; struct _x25519_derive_op_data *prev; unsigned char *key; const unsigned char *privkey; const unsigned char *pubkey; ASYNC_JOB *job; int *sts; } x25519_derive_op_data; typedef struct _ecdsa_sm2_sign_op_data { struct _ecdsa_sm2_sign_op_data *next; struct _ecdsa_sm2_sign_op_data *prev; unsigned char *sign_r; unsigned char *sign_s; const unsigned char *digest; const BIGNUM *eph_key; const BIGNUM *priv_key; const BIGNUM *x; const BIGNUM *y; const BIGNUM *z; unsigned char *id; int id_len; int dig_len; int id_set; ASYNC_JOB *job; int *sts; } ecdsa_sm2_sign_op_data; typedef struct _ecdsa_sm2_verify_op_data { struct _ecdsa_sm2_verify_op_data *next; struct _ecdsa_sm2_verify_op_data *prev; unsigned char *sign_r; unsigned char *sign_s; const unsigned char *digest; int dig_len; BIGNUM *x; BIGNUM *y; BIGNUM *z; const BIGNUM *priv_key; EC_GROUP *gen_group; unsigned char *id; int id_len; int id_set; ECDSA_SIG *s; ASYNC_JOB *job; int *sts; } ecdsa_sm2_verify_op_data; typedef struct _ecdsa_sign_op_data { struct _ecdsa_sign_op_data *next; struct _ecdsa_sign_op_data *prev; unsigned char *sign_r; unsigned char *sign_s; const unsigned char *digest; const BIGNUM *eph_key; const BIGNUM *priv_key; ASYNC_JOB *job; int *sts; } ecdsa_sign_op_data; typedef struct _ecdsa_sign_setup_op_data { struct _ecdsa_sign_setup_op_data *next; struct _ecdsa_sign_setup_op_data *prev; BIGNUM *k_inv; BIGNUM *sig_rp; const BIGNUM *eph_key; ASYNC_JOB *job; int *sts; } ecdsa_sign_setup_op_data; typedef struct _ecdsa_sign_sig_op_data { struct _ecdsa_sign_sig_op_data *next; struct _ecdsa_sign_sig_op_data *prev; unsigned char *sign_r; unsigned char *sign_s; const unsigned char *digest; const BIGNUM *sig_rp; const BIGNUM *k_inv; const BIGNUM *priv_key; ASYNC_JOB *job; int *sts; } ecdsa_sign_sig_op_data; typedef struct _ecdsa_verify_op_data { struct _ecdsa_verify_op_data *next; struct _ecdsa_verify_op_data *prev; BIGNUM *x; BIGNUM *y; BIGNUM *z; const unsigned char *digest; const ECDSA_SIG *s; ASYNC_JOB *job; int *sts; } ecdsa_verify_op_data; typedef struct _ecdh_keygen_op_data { struct _ecdh_keygen_op_data *next; struct _ecdh_keygen_op_data *prev; BIGNUM *x; BIGNUM *y; BIGNUM *z; const BIGNUM *priv_key; ASYNC_JOB *job; int *sts; } ecdh_keygen_op_data; typedef struct _ecdh_compute_op_data { struct _ecdh_compute_op_data *next; struct _ecdh_compute_op_data *prev; unsigned char *shared_key; const BIGNUM *priv_key; const BIGNUM *x; const BIGNUM *y; const BIGNUM *z; ASYNC_JOB *job; int *sts; } ecdh_compute_op_data; typedef struct _sm3_init_op_data { struct _sm3_init_op_data *next; struct _sm3_init_op_data *prev; QAT_SM3_CTX_mb *state; ASYNC_JOB *job; int *sts; } sm3_init_op_data; typedef struct _sm3_update_op_data { struct _sm3_update_op_data *next; struct _sm3_update_op_data *prev; QAT_SM3_CTX_mb *state; const unsigned char *sm3_data; int sm3_len; ASYNC_JOB *job; int *sts; } sm3_update_op_data; typedef struct _sm3_final_op_data { struct _sm3_final_op_data *next; struct _sm3_final_op_data *prev; QAT_SM3_CTX_mb *state; unsigned char *sm3_hash; ASYNC_JOB *job; int *sts; } sm3_final_op_data; typedef struct _sm4_cbc_cipher_op_data { struct _sm4_cbc_cipher_op_data *next; struct _sm4_cbc_cipher_op_data *prev; ASYNC_JOB *job; int *sts; int8u *in_out; const int8u *in_txt; int in_txt_len; int8u in_iv[IV_LEN]; sm4_key in_key; int in_enc; } sm4_cbc_cipher_op_data; # ifdef ENABLE_QAT_SW_SM4_GCM typedef struct _sm4_gcm_encrypt_op_data { struct _sm4_gcm_encrypt_op_data *next; struct _sm4_gcm_encrypt_op_data *prev; SM4_GCM_CTX_mb16 *state; ASYNC_JOB *job; int init_flag; const sm4_key *sm4_key; const int8u *sm4_iv; int sm4_ivlen; const int8u *sm4_in; int sm4_len; int8u *sm4_out; const int8u *sm4_aad; int sm4_aadlen; int8u *sm4_tag; int sm4_taglen; int *sts; } sm4_gcm_encrypt_op_data; typedef struct _sm4_gcm_decrypt_op_data { struct _sm4_gcm_decrypt_op_data *next; struct _sm4_gcm_decrypt_op_data *prev; SM4_GCM_CTX_mb16 *state; ASYNC_JOB *job; int init_flag; const sm4_key *sm4_key; const int8u *sm4_iv; int sm4_ivlen; const int8u *sm4_in; int sm4_len; int8u *sm4_out; const int8u *sm4_aad; int sm4_aadlen; int8u *sm4_tag; int sm4_taglen; int *sts; } sm4_gcm_decrypt_op_data; # endif # ifdef ENABLE_QAT_SW_SM4_CCM typedef struct _sm4_ccm_encrypt_op_data { struct _sm4_ccm_encrypt_op_data *next; struct _sm4_ccm_encrypt_op_data *prev; SM4_CCM_CTX_mb16 *state; ASYNC_JOB *job; int init_flag; const sm4_key *sm4_key; const int8u *sm4_iv; int sm4_ivlen; const int8u *sm4_in; int sm4_len; int8u *sm4_out; const int8u *sm4_aad; int sm4_aadlen; int8u *sm4_tag; int sm4_taglen; int sm4_msglen; int *sts; } sm4_ccm_encrypt_op_data; typedef struct _sm4_ccm_decrypt_op_data { struct _sm4_ccm_decrypt_op_data *next; struct _sm4_ccm_decrypt_op_data *prev; SM4_CCM_CTX_mb16 *state; ASYNC_JOB *job; int init_flag; const sm4_key *sm4_key; const int8u *sm4_iv; int sm4_ivlen; const int8u *sm4_in; int sm4_len; int8u *sm4_out; const int8u *sm4_aad; int sm4_aadlen; int8u *sm4_tag; int sm4_taglen; int sm4_msglen; int *sts; } sm4_ccm_decrypt_op_data; # endif /* ENABLE_QAT_SW_SM4_CCM */ #endif /* QAT_SW_REQUEST_H */ qatengine-1.9.0/qat_sw_rsa.c000066400000000000000000001603311500416242000160010ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_rsa.c * * This file contains the engine implementation for RSA Multi-buffer operations * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include #include "crypto_mb/rsa.h" #include "e_qat.h" #include "qat_sw_rsa.h" #include "qat_events.h" #include "qat_fork.h" #include "qat_utils.h" #include "qat_evp.h" #include "qat_constant_time.h" #ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" #endif # define RSA_MULTIBUFF_PRIV_ENC 1 # define RSA_MULTIBUFF_PRIV_DEC 2 # define RSA_MULTIBUFF_PUB_ENC 3 # define RSA_MULTIBUFF_PUB_DEC 4 /* * The RSA range check is performed so that if the op sizes are not in the * range supported by the multibuffer engine then fall back to the standard * software implementation. */ static inline int multibuff_rsa_range_check(int len) { if (len == RSA_2K_LENGTH || len == RSA_3K_LENGTH || len == RSA_4K_LENGTH) { return 1; } else { return 0; } } #ifndef QAT_BORINGSSL int multibuff_rsa_init(RSA *rsa) { return RSA_meth_get_init(RSA_PKCS1_OpenSSL())(rsa); } int multibuff_rsa_finish(RSA *rsa) { return RSA_meth_get_finish(RSA_PKCS1_OpenSSL())(rsa); } #endif /* QAT_BORINGSSL */ static int multibuff_rsa_check_padding_priv_dec(unsigned char *from, int from_len, unsigned char *to, int padding) { int output_len = -1; switch (padding) { case RSA_PKCS1_PADDING: output_len = RSA_padding_check_PKCS1_type_2(to, from_len, from, from_len, from_len); break; case RSA_PKCS1_OAEP_PADDING: output_len = RSA_padding_check_PKCS1_OAEP(to, from_len, from, from_len, from_len, NULL, 0); break; #ifndef QAT_OPENSSL_3 case RSA_SSLV23_PADDING: output_len = RSA_padding_check_SSLv23(to, from_len, from, from_len, from_len); break; #endif case RSA_NO_PADDING: output_len = RSA_padding_check_none(to, from_len, from, from_len, from_len); break; default: break; } return output_len; } static int multibuff_rsa_check_padding_pub_dec(unsigned char *from, int from_len, unsigned char *to, int padding) { int output_len = -1; switch (padding) { case RSA_PKCS1_PADDING: output_len = RSA_padding_check_PKCS1_type_1(to, from_len, from, from_len, from_len); break; case RSA_X931_PADDING: output_len = RSA_padding_check_X931(to, from_len, from, from_len, from_len); break; case RSA_NO_PADDING: output_len = RSA_padding_check_none(to, from_len, from, from_len, from_len); break; default: break; } return output_len; } static int multibuff_rsa_add_padding_priv_enc(const unsigned char *from, int from_len, unsigned char *to, int to_len, int padding) { int padding_result = -1; switch (padding) { case RSA_PKCS1_PADDING: padding_result = RSA_padding_add_PKCS1_type_1(to, to_len, from, from_len); break; case RSA_X931_PADDING: padding_result = RSA_padding_add_X931(to, to_len, from, from_len); break; case RSA_NO_PADDING: padding_result = RSA_padding_add_none(to, to_len, from, from_len); break; default: WARN("Unknown padding type: %d\n", padding); QATerr(QAT_F_MULTIBUFF_RSA_ADD_PADDING_PRIV_ENC, QAT_R_UNKNOWN_PADDING_TYPE); break; } return padding_result; } static int multibuff_rsa_add_padding_pub_enc(const unsigned char *from, int from_len, unsigned char *to, int to_len, int padding) { int padding_result = -1; switch (padding) { case RSA_PKCS1_PADDING: padding_result = RSA_padding_add_PKCS1_type_2(to, to_len, from, from_len); break; case RSA_PKCS1_OAEP_PADDING: padding_result = RSA_padding_add_PKCS1_OAEP(to, to_len, from, from_len, NULL, 0); break; #ifndef QAT_OPENSSL_3 case RSA_SSLV23_PADDING: padding_result = RSA_padding_add_SSLv23(to, to_len, from, from_len); break; #endif case RSA_NO_PADDING: padding_result = RSA_padding_add_none(to, to_len, from, from_len); break; default: WARN("Unknown padding type: %d\n", padding); QATerr(QAT_F_MULTIBUFF_RSA_ADD_PADDING_PUB_ENC, QAT_R_UNKNOWN_PADDING_TYPE); break; } return padding_result; } void process_RSA_priv_reqs(mb_thread_data *tlv, int rsa_bits) { rsa_priv_op_data *rsa_priv_req_array[MULTIBUFF_BATCH] = {0}; const unsigned char *rsa_priv_from[MULTIBUFF_BATCH] = {0}; unsigned char *rsa_priv_to[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_lenstra_e[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_lenstra_n[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_priv_p[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_priv_q[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_priv_dmp1[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_priv_dmq1[MULTIBUFF_BATCH] = {0}; const BIGNUM *rsa_priv_iqmp[MULTIBUFF_BATCH] = {0}; unsigned int rsa_sts = 0; int req_num = 0; int local_request_no = 0; START_RDTSC(&rsa_cycles_priv_execute); switch(rsa_bits) { case RSA_2K_LENGTH: DEBUG("Dequeue RSA2K priv reqs.\n"); while ((rsa_priv_req_array[req_num] = mb_queue_rsa2k_priv_dequeue(tlv->rsa2k_priv_queue)) != NULL) { rsa_priv_from[req_num] = rsa_priv_req_array[req_num]->from; if (rsa_priv_req_array[req_num]->type == RSA_MULTIBUFF_PRIV_DEC) { rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->padded_buf; } else { rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->to; } rsa_priv_p[req_num] = rsa_priv_req_array[req_num]->p; rsa_priv_q[req_num] = rsa_priv_req_array[req_num]->q; rsa_priv_dmp1[req_num] = rsa_priv_req_array[req_num]->dmp1; rsa_priv_dmq1[req_num] = rsa_priv_req_array[req_num]->dmq1; rsa_priv_iqmp[req_num] = rsa_priv_req_array[req_num]->iqmp; ++req_num; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case RSA_3K_LENGTH: DEBUG("Dequeue RSA3K priv reqs.\n"); while ((rsa_priv_req_array[req_num] = mb_queue_rsa3k_priv_dequeue(tlv->rsa3k_priv_queue)) != NULL) { rsa_priv_from[req_num] = rsa_priv_req_array[req_num]->from; if (rsa_priv_req_array[req_num]->type == RSA_MULTIBUFF_PRIV_DEC) { rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->padded_buf; } else { rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->to; } rsa_priv_p[req_num] = rsa_priv_req_array[req_num]->p; rsa_priv_q[req_num] = rsa_priv_req_array[req_num]->q; rsa_priv_dmp1[req_num] = rsa_priv_req_array[req_num]->dmp1; rsa_priv_dmq1[req_num] = rsa_priv_req_array[req_num]->dmq1; rsa_priv_iqmp[req_num] = rsa_priv_req_array[req_num]->iqmp; ++req_num; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case RSA_4K_LENGTH: DEBUG("Dequeue RSA4K priv reqs.\n"); while ((rsa_priv_req_array[req_num] = mb_queue_rsa4k_priv_dequeue(tlv->rsa4k_priv_queue)) != NULL) { rsa_priv_from[req_num] = rsa_priv_req_array[req_num]->from; if (rsa_priv_req_array[req_num]->type == RSA_MULTIBUFF_PRIV_DEC) { rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->padded_buf; } else { rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->to; } rsa_priv_p[req_num] = rsa_priv_req_array[req_num]->p; rsa_priv_q[req_num] = rsa_priv_req_array[req_num]->q; rsa_priv_dmp1[req_num] = rsa_priv_req_array[req_num]->dmp1; rsa_priv_dmq1[req_num] = rsa_priv_req_array[req_num]->dmq1; rsa_priv_iqmp[req_num] = rsa_priv_req_array[req_num]->iqmp; ++req_num; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; DEBUG("Submitting %d priv requests\n", local_request_no); num_rsa_sw_priv_reqs += local_request_no; rsa_sts = mbx_rsa_private_crt_ssl_mb8(rsa_priv_from, rsa_priv_to, rsa_priv_p, rsa_priv_q, rsa_priv_dmp1, rsa_priv_dmq1, rsa_priv_iqmp, rsa_bits); for (req_num = 0; req_num < local_request_no; req_num++) { if (rsa_priv_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(rsa_sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer rsa priv crt req[%d] success\n", req_num); *rsa_priv_req_array[req_num]->sts = 1; } else { WARN("Multibuffer rsa priv crt req[%d] failure\n", req_num); *rsa_priv_req_array[req_num]->sts = -1; } if (rsa_priv_req_array[req_num]->disable_lenstra_check) { rsa_priv_from[req_num] = NULL; rsa_priv_to[req_num] = NULL; rsa_lenstra_e[req_num] = NULL; rsa_lenstra_n[req_num] = NULL; } else { rsa_priv_from[req_num] = (unsigned const char*) rsa_priv_to[req_num]; rsa_priv_to[req_num] = rsa_priv_req_array[req_num]->lenstra_to; rsa_lenstra_e[req_num] = rsa_priv_req_array[req_num]->e; rsa_lenstra_n[req_num] = rsa_priv_req_array[req_num]->n; } } } rsa_sts = mbx_rsa_public_ssl_mb8(rsa_priv_from, rsa_priv_to, rsa_lenstra_e, rsa_lenstra_n, rsa_bits); for (req_num = 0; req_num < local_request_no; req_num++) { if (rsa_priv_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(rsa_sts, req_num) == MBX_STATUS_OK) { if (*rsa_priv_req_array[req_num]->sts < 0) { WARN("Multibuffer rsa priv req[%d] failure\n", req_num); *rsa_priv_req_array[req_num]->sts = -1; } else { DEBUG("Multibuffer rsa priv req[%d] success\n", req_num); *rsa_priv_req_array[req_num]->sts = 1; } if (!rsa_priv_req_array[req_num]->disable_lenstra_check) { if (CRYPTO_memcmp(rsa_priv_req_array[req_num]->from, rsa_priv_to[req_num], rsa_priv_req_array[req_num]->flen) == 0) { if (*rsa_priv_req_array[req_num]->sts < 0) { WARN("Lenstra check[%d] failure\n", req_num); *rsa_priv_req_array[req_num]->sts = -1; } else { *rsa_priv_req_array[req_num]->sts = 1; } } else { WARN("Lenstra memcmp[%d] failure\n", req_num); *rsa_priv_req_array[req_num]->sts = -1; } } } else { WARN("mbx_rsa_public_ssl_mb8[%d] failure\n", req_num); *rsa_priv_req_array[req_num]->sts = -1; } /* Remove Padding here if needed */ if (*rsa_priv_req_array[req_num]->sts == 1 && rsa_priv_req_array[req_num]->type == RSA_MULTIBUFF_PRIV_DEC) { *rsa_priv_req_array[req_num]->sts = multibuff_rsa_check_padding_priv_dec( rsa_priv_req_array[req_num]->padded_buf, rsa_priv_req_array[req_num]->flen, rsa_priv_req_array[req_num]->to, rsa_priv_req_array[req_num]->padding); } if (rsa_priv_req_array[req_num]->job) { #ifdef QAT_BORINGSSL bssl_mb_async_job_finish_wait(rsa_priv_req_array[req_num]->job, ASYNC_JOB_COMPLETE, ASYNC_STATUS_OK); #endif /* QAT_BORINGSSL */ qat_wake_job(rsa_priv_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(rsa_priv_req_array[req_num], sizeof(rsa_priv_op_data)); mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req_array[req_num]); } } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (rsa_bits) { case RSA_2K_LENGTH: mb_rsa2k_priv_req_rates.req_this_period += local_request_no; break; case RSA_3K_LENGTH: mb_rsa3k_priv_req_rates.req_this_period += local_request_no; break; case RSA_4K_LENGTH: mb_rsa4k_priv_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&rsa_cycles_priv_execute, 1, "[RSA:priv_execute]"); DEBUG("Processed Final Request\n"); } void process_RSA_pub_reqs(mb_thread_data *tlv, int rsa_bits) { rsa_pub_op_data *rsa_pub_req_array[MULTIBUFF_BATCH] = {0}; const unsigned char * rsa_pub_from[MULTIBUFF_BATCH] = {0}; unsigned char * rsa_pub_to[MULTIBUFF_BATCH] = {0}; const BIGNUM * rsa_pub_e[MULTIBUFF_BATCH] = {0}; const BIGNUM * rsa_pub_n[MULTIBUFF_BATCH] = {0}; unsigned int rsa_sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&rsa_cycles_pub_execute); switch(rsa_bits) { case RSA_2K_LENGTH: DEBUG("Dequeue RSA2K pub reqs.\n"); while ((rsa_pub_req_array[req_num] = mb_queue_rsa2k_pub_dequeue(tlv->rsa2k_pub_queue)) != NULL) { rsa_pub_from[req_num] = rsa_pub_req_array[req_num]->from; if (rsa_pub_req_array[req_num]->type == RSA_MULTIBUFF_PUB_DEC) { rsa_pub_to[req_num] = rsa_pub_req_array[req_num]->padded_buf; } else { rsa_pub_to[req_num] = rsa_pub_req_array[req_num]->to; } rsa_pub_e[req_num] = rsa_pub_req_array[req_num]->e; rsa_pub_n[req_num] = rsa_pub_req_array[req_num]->n; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case RSA_3K_LENGTH: DEBUG("Dequeue RSA3K pub reqs.\n"); while ((rsa_pub_req_array[req_num] = mb_queue_rsa3k_pub_dequeue(tlv->rsa3k_pub_queue)) != NULL) { rsa_pub_from[req_num] = rsa_pub_req_array[req_num]->from; if (rsa_pub_req_array[req_num]->type == RSA_MULTIBUFF_PUB_DEC) { rsa_pub_to[req_num] = rsa_pub_req_array[req_num]->padded_buf; } else { rsa_pub_to[req_num] = rsa_pub_req_array[req_num]->to; } rsa_pub_e[req_num] = rsa_pub_req_array[req_num]->e; rsa_pub_n[req_num] = rsa_pub_req_array[req_num]->n; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; case RSA_4K_LENGTH: DEBUG("Dequeue RSA4K pub reqs.\n"); while ((rsa_pub_req_array[req_num] = mb_queue_rsa4k_pub_dequeue(tlv->rsa4k_pub_queue)) != NULL) { rsa_pub_from[req_num] = rsa_pub_req_array[req_num]->from; if (rsa_pub_req_array[req_num]->type == RSA_MULTIBUFF_PUB_DEC) { rsa_pub_to[req_num] = rsa_pub_req_array[req_num]->padded_buf; } else { rsa_pub_to[req_num] = rsa_pub_req_array[req_num]->to; } rsa_pub_e[req_num] = rsa_pub_req_array[req_num]->e; rsa_pub_n[req_num] = rsa_pub_req_array[req_num]->n; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } break; } local_request_no = req_num; DEBUG("Submitting %d pub requests\n", local_request_no); num_rsa_sw_pub_reqs += local_request_no; rsa_sts = mbx_rsa_public_ssl_mb8(rsa_pub_from, rsa_pub_to, rsa_pub_e, rsa_pub_n, rsa_bits); for (req_num = 0; req_num < local_request_no; req_num++) { if (rsa_pub_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(rsa_sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer RSA pub req[%d] success\n", req_num); *rsa_pub_req_array[req_num]->sts = 1; } else { DEBUG("Multibuffer RSA pub req[%d] failure\n", req_num); *rsa_pub_req_array[req_num]->sts = -1; } /* Remove Padding here if needed */ if (*rsa_pub_req_array[req_num]->sts == 1 && rsa_pub_req_array[req_num]->type == RSA_MULTIBUFF_PUB_DEC) { *rsa_pub_req_array[req_num]->sts = multibuff_rsa_check_padding_pub_dec( rsa_pub_req_array[req_num]->padded_buf, rsa_pub_req_array[req_num]->flen, rsa_pub_req_array[req_num]->to, rsa_pub_req_array[req_num]->padding); } if (rsa_pub_req_array[req_num]->job) { qat_wake_job(rsa_pub_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(rsa_pub_req_array[req_num], sizeof(rsa_pub_op_data)); mb_flist_rsa_pub_push(tlv->rsa_pub_freelist, rsa_pub_req_array[req_num]); } } # ifdef QAT_SW_HEURISTIC_TIMEOUT switch (rsa_bits) { case RSA_2K_LENGTH: mb_rsa2k_pub_req_rates.req_this_period += local_request_no; break; case RSA_3K_LENGTH: mb_rsa3k_pub_req_rates.req_this_period += local_request_no; break; case RSA_4K_LENGTH: mb_rsa4k_pub_req_rates.req_this_period += local_request_no; break; } # endif STOP_RDTSC(&rsa_cycles_pub_execute, 1, "[RSA:pub_execute]"); DEBUG("Processed Final Request\n"); } int multibuff_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int sts = -1; ASYNC_JOB *job; int rsa_len = 0, rsa_bits = 0; rsa_priv_op_data *rsa_priv_req = NULL; int padding_result = 0; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; const BIGNUM *p = NULL; const BIGNUM *q = NULL; const BIGNUM *dmp1 = NULL; const BIGNUM *dmq1 = NULL; const BIGNUM *iqmp = NULL; int job_ret = 0; mb_thread_data *tlv = NULL; static __thread int req_num = 0; unsigned char temp_buf[RSA_4K_LENGTH]; unsigned char *select_ptr = NULL; int rsa_priv_enc_sts = 0; #ifdef QAT_BORINGSSL ASYNC_WAIT_CTX *waitctx = NULL; mb_bssl_rsa_async_ctx *bssl_rsa_async_ctx = NULL; #endif /* QAT_BORINGSSL */ #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif /* Check input parameters */ if (unlikely(NULL == rsa || NULL == from || NULL == to || flen <= 0)) { WARN("RSA key, input or output is NULL or invalid length, \ flen = %d\n", flen); QATerr(QAT_F_MULTIBUFF_RSA_PRIV_ENC, QAT_R_RSA_FROM_TO_NULL); if (to != NULL && rsa != NULL) { rsa_len = RSA_size(rsa); OPENSSL_cleanse(to, rsa_len); } return sts; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; rsa_len = RSA_size(rsa); /* Check the length passed in is not longer than the rsa key length. If it is then use the sw method synchronously. */ if (flen > rsa_len) { DEBUG("The length is longer than the RSA key length, using sw method\n"); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif rsa_bits = RSA_bits((const RSA*)rsa); /* Check if the request key size is supported */ if (!multibuff_rsa_range_check(rsa_bits)) { DEBUG("Requested key size not supported, use sw method %d\n", rsa_bits); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } while ((rsa_priv_req = mb_flist_rsa_priv_pop(tlv->rsa_priv_freelist)) == NULL) { #ifdef QAT_BORINGSSL goto use_sw_method; #else /* OpenSSL */ # ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); # else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } # endif #endif /* QAT_BORINGSSL */ } DEBUG("QAT SW RSA Started %p\n", rsa_priv_req); START_RDTSC(&rsa_cycles_priv_enc_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ RSA_get0_key((const RSA*)rsa, &n, &e, &d); RSA_get0_factors((const RSA*)rsa, &p, &q); RSA_get0_crt_params((const RSA*)rsa, &dmp1, &dmq1, &iqmp); /* Further checks on the inputs, these are fatal if failed */ if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); QATerr(QAT_F_MULTIBUFF_RSA_PRIV_ENC, QAT_R_P_Q_DMP_DMQ_IQMP_NULL); OPENSSL_cleanse(to, rsa_len); STOP_RDTSC(&rsa_cycles_priv_enc_setup, 1, "[RSA:priv_enc_setup]"); WARN("Either p %p, q %p, dmp1 %p, dmq1 %p, iqmp %p are NULL\n", p, q, dmp1, dmq1, iqmp); return sts; } /* Check whether we have public key info to allow a lenstra check. */ if (e == NULL || e_check == NULL || BN_ucmp(e, e_check) != 0) { DEBUG("Disabling Lenstra Check\n"); rsa_priv_req->disable_lenstra_check = 1; } else { rsa_priv_req->disable_lenstra_check = 0; } /* padding processing */ padding_result = multibuff_rsa_add_padding_priv_enc(from, flen, rsa_priv_req->padded_buf, rsa_len, padding); if (padding_result <= 0) { OPENSSL_cleanse(rsa_priv_req->padded_buf, rsa_len); mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); /* Error is raised within the padding function. */ OPENSSL_cleanse(to, rsa_len); STOP_RDTSC(&rsa_cycles_priv_enc_setup, 1, "[RSA:priv_enc_setup]"); WARN("Failed to add padding\n"); return sts; } rsa_priv_req->type = RSA_MULTIBUFF_PRIV_ENC; rsa_priv_req->flen = rsa_len; rsa_priv_req->from = rsa_priv_req->padded_buf; rsa_priv_req->rsa = rsa; rsa_priv_req->padding = padding; rsa_priv_req->job = job; rsa_priv_req->e = e; rsa_priv_req->n = n; rsa_priv_req->p = p; rsa_priv_req->q = q; rsa_priv_req->dmp1 = dmp1; rsa_priv_req->dmq1 = dmq1; rsa_priv_req->iqmp = iqmp; #ifdef QAT_BORINGSSL waitctx = ASYNC_get_wait_ctx(job); if (!waitctx) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); WARN("waitctx is NULL\n"); goto use_sw_method; } bssl_rsa_async_ctx = (mb_bssl_rsa_async_ctx *)OPENSSL_zalloc( sizeof(mb_bssl_rsa_async_ctx)); if (!bssl_rsa_async_ctx) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); WARN("Allocating for bssl_rsa_async_ctx failed.\n"); goto use_sw_method; } bssl_rsa_async_ctx->status = 0; bssl_rsa_async_ctx->length = rsa_len; bssl_rsa_async_ctx->async_ctx.callback_func = mb_bssl_rsa_priv_enc_callback_fn; bssl_rsa_async_ctx->async_ctx.ctx = bssl_rsa_async_ctx; waitctx->data = &(bssl_rsa_async_ctx->async_ctx); rsa_priv_req->sts = (int *)(&bssl_rsa_async_ctx->status); bssl_rsa_async_ctx->data = OPENSSL_zalloc(rsa_len); if (!bssl_rsa_async_ctx->data) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); WARN("Allocating for bssl_rsa_async_ctx->data failed.\n"); OPENSSL_free(bssl_rsa_async_ctx); goto use_sw_method; } rsa_priv_req->to = bssl_rsa_async_ctx->data; #else /* QAT_BORINGSSL */ rsa_priv_req->to = to; rsa_priv_req->sts = &sts; #endif /* QAT_BORINGSSL */ switch(rsa_bits) { case RSA_2K_LENGTH: mb_queue_rsa2k_priv_enqueue(tlv->rsa2k_priv_queue, rsa_priv_req); break; case RSA_3K_LENGTH: mb_queue_rsa3k_priv_enqueue(tlv->rsa3k_priv_queue, rsa_priv_req); break; case RSA_4K_LENGTH: mb_queue_rsa4k_priv_enqueue(tlv->rsa4k_priv_queue, rsa_priv_req); break; } STOP_RDTSC(&rsa_cycles_priv_enc_setup, 1, "[RSA:priv_enc_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_RSA_priv_reqs(tlv, rsa_bits); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } #ifdef QAT_BORINGSSL if (job) { job->tlv_destructor(NULL); return 1; } #endif /* QAT_BORINGSSL */ DEBUG("Pausing: %p status = %d\n", rsa_priv_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", rsa_priv_req, sts); #ifdef ENABLE_QAT_FIPS } #endif rsa_priv_enc_sts = qat_constant_time_select_int((sts <= 0), sts, rsa_len); select_ptr = qat_constant_time_select_ptr((rsa_priv_enc_sts == rsa_len), (void *)temp_buf, (void *)to); OPENSSL_cleanse(select_ptr, rsa_len); return rsa_priv_enc_sts; use_sw_method: sts = RSA_meth_get_priv_enc(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); # ifdef QAT_BORINGSSL if ((job = ASYNC_get_current_job())) { job->tlv_destructor(NULL); waitctx = ASYNC_get_wait_ctx(job); if (waitctx && sts > 0) { waitctx->data = (void *)(long long)sts; bssl_mb_async_job_finish_wait(job, ASYNC_JOB_OPER_COMPLETE, ASYNC_STATUS_OK); } else { bssl_mb_async_job_finish_wait(job, ASYNC_JOB_STOPPED, ASYNC_STATUS_OK); } } # endif /* QAT_BORINGSSL */ DEBUG("SW Finished\n"); return sts; } int multibuff_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int sts = -1; ASYNC_JOB *job; int rsa_len = 0, rsa_bits = 0; rsa_priv_op_data *rsa_priv_req = NULL; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; const BIGNUM *p = NULL; const BIGNUM *q = NULL; const BIGNUM *dmp1 = NULL; const BIGNUM *dmq1 = NULL; const BIGNUM *iqmp = NULL; int job_ret = 0; mb_thread_data *tlv = NULL; static __thread int req_num = 0; unsigned char temp_buf[RSA_4K_LENGTH]; unsigned char *select_ptr = NULL; #ifdef QAT_BORINGSSL ASYNC_WAIT_CTX *waitctx = NULL; mb_bssl_rsa_async_ctx *bssl_rsa_async_ctx = NULL; #endif /* QAT_BORINGSSL */ #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif /* Check input parameters */ if (unlikely(rsa == NULL || from == NULL || to == NULL || (flen != (rsa_len = RSA_size(rsa))))) { WARN("RSA key %p, input %p or output %p are NULL or invalid length, \ flen = %d, rsa_len = %d\n", rsa, from, to, flen, rsa_len); QATerr(QAT_F_MULTIBUFF_RSA_PRIV_DEC, QAT_R_RSA_FROM_TO_NULL); if (to != NULL && rsa != NULL) { rsa_len = RSA_size(rsa); OPENSSL_cleanse(to, rsa_len); } return sts; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check the length passed in is not longer than the rsa key length. If it is then use the sw method synchronously. */ if (flen > rsa_len) { DEBUG("The length is longer than the RSA key length, using sw method\n"); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif rsa_bits = RSA_bits((const RSA*)rsa); /* Check if the request key size is supported */ if (!multibuff_rsa_range_check(rsa_bits)) { DEBUG("Requested key size not supported, use sw method %d\n", rsa_bits); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return sts; #else goto use_sw_method; #endif } while ((rsa_priv_req = mb_flist_rsa_priv_pop(tlv->rsa_priv_freelist)) == NULL) { #ifdef QAT_BORINGSSL goto use_sw_method; #else /* QAT_BORINGSSL */ # ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); # else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } # endif #endif /* QAT_BORINGSSL */ } DEBUG("QAT SW RSA Started %p\n", rsa_priv_req); START_RDTSC(&rsa_cycles_priv_dec_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ RSA_get0_key((const RSA*)rsa, &n, &e, &d); RSA_get0_factors((const RSA*)rsa, &p, &q); RSA_get0_crt_params((const RSA*)rsa, &dmp1, &dmq1, &iqmp); /* Further checks on the inputs, these are fatal if failed */ if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); QATerr(QAT_F_MULTIBUFF_RSA_PRIV_DEC, QAT_R_P_Q_DMP_DMQ_IQMP_NULL); OPENSSL_cleanse(to, rsa_len); STOP_RDTSC(&rsa_cycles_priv_dec_setup, 1, "[RSA:priv_dec_setup]"); WARN("Either p %p, q %p, dmp1 %p, dmq1 %p, iqmp %p are NULL\n", p, q, dmp1, dmq1, iqmp); return sts; } /* Check whether we have public key info to allow a lenstra check. */ if (e == NULL || e_check == NULL || BN_ucmp(e, e_check) != 0) { DEBUG("Disabling Lenstra Check\n"); rsa_priv_req->disable_lenstra_check = 1; } else { rsa_priv_req->disable_lenstra_check = 0; } rsa_priv_req->type = RSA_MULTIBUFF_PRIV_DEC; rsa_priv_req->flen = rsa_len; rsa_priv_req->from = from; rsa_priv_req->rsa = rsa; rsa_priv_req->padding = padding; rsa_priv_req->job = job; rsa_priv_req->e = e; rsa_priv_req->n = n; rsa_priv_req->p = p; rsa_priv_req->q = q; rsa_priv_req->dmp1 = dmp1; rsa_priv_req->dmq1 = dmq1; rsa_priv_req->iqmp = iqmp; #ifdef QAT_BORINGSSL waitctx = ASYNC_get_wait_ctx(job); if (!waitctx) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); WARN("waitctx is NULL\n"); goto use_sw_method; } bssl_rsa_async_ctx = (mb_bssl_rsa_async_ctx *)OPENSSL_zalloc( sizeof(mb_bssl_rsa_async_ctx)); if (!bssl_rsa_async_ctx) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); WARN("Allocating for bssl_rsa_async_ctx failed.\n"); goto use_sw_method; } bssl_rsa_async_ctx->status = 0; bssl_rsa_async_ctx->length = rsa_len; bssl_rsa_async_ctx->async_ctx.callback_func = mb_bssl_rsa_priv_enc_callback_fn; bssl_rsa_async_ctx->async_ctx.ctx = bssl_rsa_async_ctx; waitctx->data = &(bssl_rsa_async_ctx->async_ctx); rsa_priv_req->sts = (int *)(&bssl_rsa_async_ctx->status); bssl_rsa_async_ctx->data = OPENSSL_zalloc(rsa_len); if (!bssl_rsa_async_ctx->data) { mb_flist_rsa_priv_push(tlv->rsa_priv_freelist, rsa_priv_req); WARN("Allocating for bssl_rsa_async_ctx->data failed.\n"); OPENSSL_free(bssl_rsa_async_ctx); goto use_sw_method; } rsa_priv_req->to = bssl_rsa_async_ctx->data; #else /* QAT_BORINGSSL */ rsa_priv_req->to = to; rsa_priv_req->sts = &sts; #endif /* QAT_BORINGSSL */ switch(rsa_bits) { case RSA_2K_LENGTH: mb_queue_rsa2k_priv_enqueue(tlv->rsa2k_priv_queue, rsa_priv_req); break; case RSA_3K_LENGTH: mb_queue_rsa3k_priv_enqueue(tlv->rsa3k_priv_queue, rsa_priv_req); break; case RSA_4K_LENGTH: mb_queue_rsa4k_priv_enqueue(tlv->rsa4k_priv_queue, rsa_priv_req); break; } STOP_RDTSC(&rsa_cycles_priv_dec_setup, 1, "[RSA:priv_dec_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_RSA_priv_reqs(tlv, rsa_bits); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } #ifdef QAT_BORINGSSL if (job) { job->tlv_destructor(NULL); return 1; } #endif /* QAT_BORINGSSL */ DEBUG("Pausing: %p status = %d\n", rsa_priv_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", rsa_priv_req, sts); #ifdef ENABLE_QAT_FIPS } #endif select_ptr = qat_constant_time_select_ptr((sts < 1), (void *)to, (void *)temp_buf); OPENSSL_cleanse(select_ptr, rsa_len); return sts; use_sw_method: sts = RSA_meth_get_priv_dec(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); # ifdef QAT_BORINGSSL if ((job = ASYNC_get_current_job())) { job->tlv_destructor(NULL); waitctx = ASYNC_get_wait_ctx(job); if (waitctx && sts > 0) { waitctx->data = (void *)((long long)sts); bssl_mb_async_job_finish_wait(job, ASYNC_JOB_OPER_COMPLETE, ASYNC_STATUS_OK); } else { bssl_mb_async_job_finish_wait(job, ASYNC_JOB_STOPPED, ASYNC_STATUS_OK); } } # endif /* QAT_BORINGSSL */ DEBUG("SW Finished\n"); return sts; } int multibuff_rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int sts = -1; ASYNC_JOB *job; int rsa_len = 0, rsa_bits = 0; rsa_pub_op_data *rsa_pub_req = NULL; int padding_result = 0; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; int job_ret = 0; mb_thread_data *tlv = NULL; static __thread int req_num = 0; unsigned char temp_buf[RSA_4K_LENGTH]; unsigned char *select_ptr = NULL; int rsa_pub_enc_sts = 0; #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif /* Check Parameters */ if (rsa == NULL || from == NULL || to == NULL || flen < 0) { WARN("RSA key %p, input %p or output %p are NULL or invalid length, \ flen = %d, rsa_len = %d\n", rsa, from, to, flen, rsa_len); QATerr(QAT_F_MULTIBUFF_RSA_PUB_ENC, QAT_R_RSA_FROM_TO_NULL); if (to != NULL && rsa != NULL) { rsa_len = RSA_size(rsa); OPENSSL_cleanse(to, rsa_len); } return sts; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; rsa_len = RSA_size(rsa); /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif rsa_bits = RSA_bits((const RSA*)rsa); /* Check if the request key size is supported */ if (!multibuff_rsa_range_check(rsa_bits)) { DEBUG("Requested key size not supported, use sw method %d\n", rsa_bits); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return sts; #else goto use_sw_method; #endif } while ((rsa_pub_req = mb_flist_rsa_pub_pop(tlv->rsa_pub_freelist)) == NULL) { #ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); #else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } #endif } DEBUG("QAT SW RSA Started %p\n", rsa_pub_req); START_RDTSC(&rsa_cycles_pub_enc_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ RSA_get0_key((const RSA*)rsa, &n, &e, &d); if (e == NULL || e_check == NULL || BN_ucmp(e, e_check) != 0) { mb_flist_rsa_pub_push(tlv->rsa_pub_freelist, rsa_pub_req); STOP_RDTSC(&rsa_cycles_pub_enc_setup, 1, "[RSA:pub_enc_setup]"); DEBUG("Request is using a public exp not equal to 65537\n"); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } /* padding processing */ padding_result = multibuff_rsa_add_padding_pub_enc(from, flen, rsa_pub_req->padded_buf, rsa_len, padding); if (padding_result <= 0) { OPENSSL_cleanse(rsa_pub_req->padded_buf, rsa_len); mb_flist_rsa_pub_push(tlv->rsa_pub_freelist, rsa_pub_req); /* Error is raised within the padding function. */ OPENSSL_cleanse(to, rsa_len); STOP_RDTSC(&rsa_cycles_pub_enc_setup, 1, "[RSA:pub_enc_setup]"); WARN("Failed to add padding\n"); return sts; } rsa_pub_req->type = RSA_MULTIBUFF_PUB_ENC; rsa_pub_req->flen = flen; rsa_pub_req->from = rsa_pub_req->padded_buf; rsa_pub_req->to = to; rsa_pub_req->rsa = rsa; rsa_pub_req->job = job; rsa_pub_req->padding = padding; rsa_pub_req->e = e; rsa_pub_req->n = n; rsa_pub_req->sts = &sts; switch(rsa_bits) { case RSA_2K_LENGTH: mb_queue_rsa2k_pub_enqueue(tlv->rsa2k_pub_queue, rsa_pub_req); break; case RSA_3K_LENGTH: mb_queue_rsa3k_pub_enqueue(tlv->rsa3k_pub_queue, rsa_pub_req); break; case RSA_4K_LENGTH: mb_queue_rsa4k_pub_enqueue(tlv->rsa4k_pub_queue, rsa_pub_req); break; } STOP_RDTSC(&rsa_cycles_pub_enc_setup, 1, "[RSA:pub_enc_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_RSA_pub_reqs(tlv, rsa_bits); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", rsa_pub_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", rsa_pub_req, sts); #ifdef ENABLE_QAT_FIPS } #endif rsa_pub_enc_sts = qat_constant_time_select_int((sts <= 0), sts, rsa_len); select_ptr = qat_constant_time_select_ptr((rsa_pub_enc_sts == rsa_len), (void *)temp_buf, (void *)to); OPENSSL_cleanse(select_ptr, rsa_len); return rsa_pub_enc_sts; use_sw_method: sts = RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); DEBUG("SW Finished\n"); return sts; } int multibuff_rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int sts = -1; ASYNC_JOB *job; int rsa_len = 0, rsa_bits = 0; rsa_pub_op_data *rsa_pub_req = NULL; const BIGNUM *n = NULL; const BIGNUM *e = NULL; const BIGNUM *d = NULL; int job_ret = 0; mb_thread_data *tlv = NULL; static __thread int req_num = 0; unsigned char temp_buf[RSA_4K_LENGTH]; unsigned char *select_ptr = NULL; #ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); #endif /* Check Parameters */ if (rsa == NULL || from == NULL || to == NULL || (flen != (rsa_len = RSA_size(rsa)))) { WARN("RSA key %p, input %p or output %p are NULL or invalid length, \ flen = %d, rsa_len = %d\n", rsa, from, to, flen, rsa_len); QATerr(QAT_F_MULTIBUFF_RSA_PUB_DEC, QAT_R_RSA_FROM_TO_NULL); if (to != NULL && rsa != NULL) { rsa_len = RSA_size(rsa); OPENSSL_cleanse(to, rsa_len); } return sts; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { #ifndef ENABLE_QAT_FIPS DEBUG("Running synchronously using sw method\n"); goto use_sw_method; #endif } /* Setup asynchronous notifications */ #ifdef ENABLE_QAT_FIPS if (job != NULL && !qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications.\n"); return sts; } #else if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } #endif rsa_bits = RSA_bits((const RSA*)rsa); /* Check if the request key size is supported */ if (!multibuff_rsa_range_check(rsa_bits)) { DEBUG("Requested key size not supported, use sw method %d\n", rsa_bits); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); #ifdef ENABLE_QAT_FIPS return sts; #else goto use_sw_method; #endif } while ((rsa_pub_req = mb_flist_rsa_pub_pop(tlv->rsa_pub_freelist)) == NULL) { #ifndef ENABLE_QAT_FIPS qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); #else if (job != NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } #endif } DEBUG("QAT SW RSA Started %p\n", rsa_pub_req); START_RDTSC(&rsa_cycles_pub_dec_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ RSA_get0_key((const RSA*)rsa, &n, &e, &d); if (e == NULL || e_check == NULL || BN_ucmp(e, e_check) != 0) { mb_flist_rsa_pub_push(tlv->rsa_pub_freelist, rsa_pub_req); STOP_RDTSC(&rsa_cycles_pub_dec_setup, 1, "[RSA:pub_dec_setup]"); DEBUG("Request is using a public exp not equal to 65537\n"); #ifndef ENABLE_QAT_FIPS goto use_sw_method; #else return sts; #endif } rsa_pub_req->type = RSA_MULTIBUFF_PUB_DEC; rsa_pub_req->flen = flen; rsa_pub_req->from = from; rsa_pub_req->to = to; rsa_pub_req->rsa = rsa; rsa_pub_req->padding = padding; rsa_pub_req->job = job; rsa_pub_req->e = e; rsa_pub_req->n = n; rsa_pub_req->sts = &sts; switch(rsa_bits) { case RSA_2K_LENGTH: mb_queue_rsa2k_pub_enqueue(tlv->rsa2k_pub_queue, rsa_pub_req); break; case RSA_3K_LENGTH: mb_queue_rsa3k_pub_enqueue(tlv->rsa3k_pub_queue, rsa_pub_req); break; case RSA_4K_LENGTH: mb_queue_rsa4k_pub_enqueue(tlv->rsa4k_pub_queue, rsa_pub_req); break; } STOP_RDTSC(&rsa_cycles_pub_dec_setup, 1, "[RSA:pub_dec_setup]"); #ifdef ENABLE_QAT_FIPS if (job == NULL) process_RSA_pub_reqs(tlv, rsa_bits); #endif if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", rsa_pub_req, sts); #ifdef ENABLE_QAT_FIPS if (job != NULL) { #endif do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", rsa_pub_req, sts); #ifdef ENABLE_QAT_FIPS } #endif select_ptr = qat_constant_time_select_ptr((sts < 1), (void *)to, (void *)temp_buf); OPENSSL_cleanse(select_ptr, rsa_len); return sts; use_sw_method: sts = RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())(flen, from, to, rsa, padding); DEBUG("SW Finished\n"); return sts; } #ifdef QAT_BORINGSSL int mb_bssl_rsa_priv_sign(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { int len = 0; const unsigned rsa_size = RSA_size(rsa); int __attribute__((unused)) _ret; if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); _ret = ASYNC_current_job_last_check_and_get(); return 0; } len = multibuff_rsa_priv_enc(in_len, in, out, rsa, padding); if(0 >= len) { _ret = ASYNC_current_job_last_check_and_get(); WARN("Failure in mb_bssl_rsa_priv_sign.\n"); OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); return 0; } if (1 == len) { /* async mode */ _ret = ASYNC_current_job_last_check_and_get(); len = 0; } *out_len = len; return 1; } int mb_bssl_rsa_priv_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { int len = 0; const unsigned rsa_size = RSA_size(rsa); int __attribute__((unused)) _ret; if (max_out < rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); _ret = ASYNC_current_job_last_check_and_get(); return 0; } if (in_len != rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); return 0; } len = multibuff_rsa_priv_dec(in_len, in, out, rsa, padding); if(0 >= len) { _ret = ASYNC_current_job_last_check_and_get(); return 0; } if (1 == len) { /* async mode */ _ret = ASYNC_current_job_last_check_and_get(); len = 0; } *out_len = len; return 1; } void mb_bssl_rsa_priv_enc_callback_fn(void *async_ctx, unsigned char *out_buffer, unsigned long *size, unsigned long max_size) { if (!async_ctx) { return; } mb_bssl_rsa_async_ctx *rsa_async_ctx = (mb_bssl_rsa_async_ctx *)async_ctx; *size = rsa_async_ctx->length; unsigned char *data = rsa_async_ctx->data; if (rsa_async_ctx->status) { bssl_memcpy(out_buffer, data, *size); } OPENSSL_free(rsa_async_ctx->data); OPENSSL_free(rsa_async_ctx); } #endif /* QAT_BORINGSSL */ qatengine-1.9.0/qat_sw_rsa.h000066400000000000000000000101301500416242000157750ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_rsa.h * * This file provides an RSA interface for Multi-buffer implementation of an * OpenSSL engine * *****************************************************************************/ #ifndef QAT_SW_RSA_H # define QAT_SW_RSA_H # include /* RSA key sizes */ # define RSA_2K_LENGTH 2048 # define RSA_3K_LENGTH 3072 # define RSA_4K_LENGTH 4096 #ifdef ENABLE_QAT_SW_RSA /* ENABLE_QAT_SW_RSA */ #ifdef QAT_BORINGSSL typedef struct { int status; unsigned int length; unsigned char *data; mb_async_ctx async_ctx; } mb_bssl_rsa_async_ctx; #endif /* QAT_BORINGSSL */ void process_RSA_priv_reqs(mb_thread_data *tlv, int rsa_bits); void process_RSA_pub_reqs(mb_thread_data *tlv, int rsa_bits); int multibuff_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int multibuff_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int multibuff_rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); int multibuff_rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); #ifdef QAT_BORINGSSL int mb_bssl_rsa_priv_sign(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); int mb_bssl_rsa_priv_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); void mb_bssl_rsa_priv_enc_callback_fn(void *async_ctx, unsigned char *out_buffer, unsigned long *size, unsigned long max_size); void mb_rsa_sign_sync_call_back_fn(void *async_ctx, unsigned char *out_buffer, unsigned long *size, unsigned long max_size); #else /* OpenSSL */ int multibuff_rsa_init(RSA *rsa); int multibuff_rsa_finish(RSA *rsa); #endif /* QAT_BORINGSSL */ #endif /* ENABLE_QAT_SW_RSA */ #endif /* QAT_SW_RSA_H */ qatengine-1.9.0/qat_sw_sha2.c000066400000000000000000000260261500416242000160530ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sha2.c * * This file provides an implementation of SHA2 operations * *****************************************************************************/ #if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) /* Local Includes */ # include "e_qat.h" # include "qat_evp.h" # include "qat_utils.h" # include "qat_sw_gcm.h" # ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_ciphers.h" # endif # ifdef ENABLE_QAT_FIPS # include "qat_prov_cmvp.h" # endif # include "qat_sw_sha2.h" # ifdef ENABLE_QAT_FIPS extern int qat_fips_key_zeroize; # endif IMB_MGR *sha_ipsec_mgr = NULL; int qat_imb_sha2(int nid, IMB_MGR * ipsec_mgr, unsigned char hash_type, const void *data, size_t len, unsigned char *out); /****************************************************************************** * function: * sha_init_ipsec_mb_mgr(void) * * @retval 0 function failed * @retval 1 function succeeded * * description: * Allocate and Initialize the Intel IPsec Multi-Buffer Library Manager * to help dispatch AVX512 APIS * ******************************************************************************/ int sha_init_ipsec_mb_mgr() { if (sha_ipsec_mgr == NULL) { sha_ipsec_mgr = alloc_mb_mgr(0); if (sha_ipsec_mgr == NULL) { WARN("Error allocating Intel IPsec MB_MGR!\n"); return 0; } else { /* Initialize the manager to dispatch AVX512 IPsec APIs */ init_mb_mgr_avx512(sha_ipsec_mgr); return 1; } } if (qat_reload_algo) return 1; return 0; } /****************************************************************************** * function: * sha_free_ipsec_mb_mgr(void) * * description: * Free Intel IPsec Multi-Buffer Library Manager resources * ******************************************************************************/ void sha_free_ipsec_mb_mgr() { if (sha_ipsec_mgr) { free_mb_mgr(sha_ipsec_mgr); sha_ipsec_mgr = NULL; } } /****************************************************************************** * function: * qat_sha2_ctx_get_nid(QAT_SHA2_CTX *ctx) * * description: * Function takes QAT_SHA2_CTX as input argument and return NID * ******************************************************************************/ int qat_sha2_ctx_get_nid(QAT_SHA2_CTX *ctx) { return ctx->md_type; } /****************************************************************************** * function: * mb_qat_SHA2_init(QAT_SHA2_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function initialises the hash algorithm parameters for EVP context. * ******************************************************************************/ int mb_qat_SHA2_init(QAT_SHA2_CTX *ctx) { if (NULL == ctx) { WARN("ctx is NULL\n"); return 0; } if (ctx->md_type == NID_sha224) { ctx->h[0] = 0xc1059ed8UL; ctx->h[1] = 0x367cd507UL; ctx->h[2] = 0x3070dd17UL; ctx->h[3] = 0xf70e5939UL; ctx->h[4] = 0xffc00b31UL; ctx->h[5] = 0x68581511UL; ctx->h[6] = 0x64f98fa7UL; ctx->h[7] = 0xbefa4fa4UL; ctx->md_len = SHA224_DIGEST_LENGTH; return 1; } if (ctx->md_type == NID_sha256) { ctx->h[0] = 0x6a09e667UL; ctx->h[1] = 0xbb67ae85UL; ctx->h[2] = 0x3c6ef372UL; ctx->h[3] = 0xa54ff53aUL; ctx->h[4] = 0x510e527fUL; ctx->h[5] = 0x9b05688cUL; ctx->h[6] = 0x1f83d9abUL; ctx->h[7] = 0x5be0cd19UL; ctx->md_len = SHA256_DIGEST_LENGTH; return 1; } if (ctx->md_type == NID_sha384) { ctx->h[0] = U64(0xcbbb9d5dc1059ed8); ctx->h[1] = U64(0x629a292a367cd507); ctx->h[2] = U64(0x9159015a3070dd17); ctx->h[3] = U64(0x152fecd8f70e5939); ctx->h[4] = U64(0x67332667ffc00b31); ctx->h[5] = U64(0x8eb44a8768581511); ctx->h[6] = U64(0xdb0c2e0d64f98fa7); ctx->h[7] = U64(0x47b5481dbefa4fa4); ctx->Nl = 0; ctx->Nh = 0; ctx->num = 0; ctx->md_len = SHA384_DIGEST_LENGTH; return 1; } if (ctx->md_type == NID_sha512) { ctx->h[0] = U64(0x6a09e667f3bcc908); ctx->h[1] = U64(0xbb67ae8584caa73b); ctx->h[2] = U64(0x3c6ef372fe94f82b); ctx->h[3] = U64(0xa54ff53a5f1d36f1); ctx->h[4] = U64(0x510e527fade682d1); ctx->h[5] = U64(0x9b05688c2b3e6c1f); ctx->h[6] = U64(0x1f83d9abfb41bd6b); ctx->h[7] = U64(0x5be0cd19137e2179); ctx->Nl = 0; ctx->Nh = 0; ctx->num = 0; ctx->md_len = SHA512_DIGEST_LENGTH; return 1; } return 0; } /****************************************************************************** * function: * mb_qat_SHA2_update(QAT_SHA2_CTX *ctx, const void *data, size_t len) * * @param ctx [IN] - pointer to existing context * @param data [IN] - input buffer * @param len [IN] - length of input buffer * * @retval -1 function failed * @retval len function succeeded * * description: * This function performs the cryptographic transform according to the * parameters setup during initialisation. * * ******************************************************************************/ int mb_qat_SHA2_update(QAT_SHA2_CTX *ctx, const void *actual_data, size_t len) { unsigned char *data = (unsigned char *)actual_data; unsigned char *p = NULL; size_t n; int nid = 0; unsigned long long data_size = 0; # ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); # endif if (ctx->md_type == NID_sha256 || ctx->md_type == NID_sha224) { p = ctx->u.small_data; } if (ctx->md_type == NID_sha384 || ctx->md_type == NID_sha512) { p = ctx->u.large_data; } data_size = QAT_SHA_MAX_SIZE; nid = qat_sha2_ctx_get_nid(ctx); n = ctx->num; DEBUG("ctx = %p, NID = %d, in = %p, len = %zu\n", ctx, nid, actual_data, len); if (n != 0) { /* Offload threshold met */ if (len >= data_size || len + n >= data_size) { /* Use part of new packet filling the packet buffer */ data_size += data_size; memcpy(p + n, data, len); ctx->num += (unsigned int)len; return 1; } else { /* Append the new packets to buffer */ memcpy(p + n, data, len); ctx->num += (unsigned int)len; return 1; } } n = len / data_size; if (n > 0) { n *= data_size; qat_imb_sha2(nid, sha_ipsec_mgr, ctx->md_type, data, n, ctx->digest_data1); data += n; len -= n; } /* Save the bytes into buffer if there're some bytes left * after the previous update. */ if (len != 0) { if (ctx->md_type == NID_sha256 || ctx->md_type == NID_sha224) { p = ctx->u.small_data; } if (ctx->md_type == NID_sha384 || ctx->md_type == NID_sha512) { p = ctx->u.large_data; } ctx->num = (unsigned int)len; memcpy(p, data, len); } return 1; } /****************************************************************************** * function: * mb_qat_SHA2_final(QAT_SHA2_CTX *ctx, unsigned char *md) * * @param ctx [IN] - pointer to existing context * @param md [OUT] - output buffer for digest result * * @retval -1 function failed * @retval 1 function succeeded * * description: * This function performs the copy operation of digest into md buffer. * ******************************************************************************/ int mb_qat_SHA2_final(QAT_SHA2_CTX *ctx, unsigned char *md) { int nid = 0; unsigned char *p = NULL; nid = qat_sha2_ctx_get_nid(ctx); # ifdef ENABLE_QAT_FIPS qat_fips_get_approved_status(); # endif if (ctx->md_type == NID_sha256 || ctx->md_type == NID_sha224) { p = ctx->u.small_data; } if (ctx->md_type == NID_sha384 || ctx->md_type == NID_sha512) { p = ctx->u.large_data; } DEBUG("ctx = %p, NID = %d, in = %p, len = %d\n", ctx, nid, p, ctx->num); qat_imb_sha2(nid, sha_ipsec_mgr, ctx->md_type, p, ctx->num, ctx->digest_data1); memcpy(md, ctx->digest_data1, ctx->md_size); return 1; } /****************************************************************************** * function: * mb_qat_sha2_cleanup(QAT_SHA2_CTX *ctx) * * @param ctx [IN] - pointer to existing context * * @retval 1 function succeeded * @retval 0 function failed * * description: * This function will cleanup all allocated resources required to perform the * cryptographic transform. * ******************************************************************************/ int mb_qat_sha2_cleanup(QAT_SHA2_CTX *ctx) { # ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 0; # endif QAT_SHA2_CTX *sha_ctx = (QAT_SHA2_CTX *) ctx; memset(sha_ctx, 0, sizeof(QAT_SHA2_CTX)); OPENSSL_clear_free(ctx, sizeof(*ctx)); # ifdef ENABLE_QAT_FIPS qat_fips_key_zeroize = 1; qat_fips_get_key_zeroize_status(); # endif return 1; } #endif /*ENABLE_QAT_FIPS && ENABLE_QAT_SW_SHA2 */ qatengine-1.9.0/qat_sw_sha2.h000066400000000000000000000114341500416242000160550ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_prov_sha2.h * * This file provides an interface to Qat provider SHA2 operations * *****************************************************************************/ #ifndef QAT_SW_SHA2_H # define QAT_SW_SHA2_H /* Standard Includes */ # include # include /* OpenSSL Includes */ # include # include # include # include # include # include /* Intel IPsec library include */ # if defined(ENABLE_QAT_FIPS) && defined(ENABLE_QAT_SW_SHA2) # include # endif /* Internal flags that can be queried */ # define PROV_DIGEST_FLAG_XOF 0x0001 # define PROV_DIGEST_FLAG_ALGID_ABSENT 0x0002 # define SHA2_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT # define QAT_SHA224_DIGEST_LENGTH 28 # define QAT_SHA256_DIGEST_LENGTH 32 # define QAT_SHA384_DIGEST_LENGTH 48 # define QAT_SHA512_DIGEST_LENGTH 64 # if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) typedef __int64 i64; typedef unsigned __int64 u64; # define U64(C) C##UI64 # elif defined(__arch64__) typedef long i64; typedef unsigned long u64; # define U64(C) C##UL # else typedef long long i64; typedef unsigned long long u64; # define U64(C) C##ULL # endif /*- * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * ! SHA_LONG has to be at least 32 bits wide. ! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ # define QAT_SHA_LONG unsigned long long int # define QAT_SHA_LBLOCK 16 # define QAT_SHA_MAX_SIZE 99999999 /* SHA-256 treats input data as a contiguous array of 32 bit wide * big-endian values. */ # define QAT_SHA256_CBLOCK (QAT_SHA_LBLOCK*4)//original value is *4 /* SHA-512 treats input data as a contiguous array of 64 bit wide * big-endian values. */ # define QAT_SHA512_CBLOCK (QAT_SHA_LBLOCK*8) typedef struct qat_sha2_st { QAT_SHA_LONG h[8]; QAT_SHA_LONG Nl, Nh; size_t block_size; size_t md_size; /* output length, variable in XOF */ size_t data_bufsz; /* used bytes in below buffer */ union { /*used for 224 & 256 block sizes */ unsigned char small_data[QAT_SHA_MAX_SIZE]; /*used for 384 & 512 block sizes */ unsigned char large_data[QAT_SHA_MAX_SIZE]; } u; unsigned int num; unsigned int md_len; int md_type; unsigned char *name1; unsigned char *data22; unsigned char digest_data1[EVP_MAX_MD_SIZE]; EVP_MD *sw_md; EVP_MD_CTX *sw_md_ctx; } QAT_SHA2_CTX; int mb_qat_SHA2_init(QAT_SHA2_CTX * ctx); int mb_qat_SHA2_update(QAT_SHA2_CTX * ctx, const void *actual_data, size_t len); int mb_qat_SHA2_final(QAT_SHA2_CTX * ctx, unsigned char *md); int mb_qat_sha2_cleanup(QAT_SHA2_CTX * ctx); int qat_sha2_ctx_get_nid(QAT_SHA2_CTX * ctx); int sha_init_ipsec_mb_mgr(); void sha_free_ipsec_mb_mgr(); #endif /* QAT_SW_SHA2_H */ qatengine-1.9.0/qat_sw_sm2.c000066400000000000000000001244641500416242000157240ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm2.c * * This file provides multibuffer support for SM2 ECDSA * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include "qat_sw_sm2.h" #if defined(ENABLE_QAT_SW_SM2) typedef struct { /* Key and paramgen group */ EC_GROUP *gen_group; /* message digest */ const EVP_MD *md; /* Distinguishing Identifier, ISO/IEC 15946-3 */ uint8_t *id; size_t id_len; /* id_set indicates if the 'id' field is set (1) or not (0) */ int id_set; } QAT_SM2_PKEY_CTX; #if defined(QAT_OPENSSL_3) && defined(ENABLE_QAT_SW_SM2) typedef struct evp_signature_st { int name_id; char *type_name; const char *description; OSSL_PROVIDER *prov; CRYPTO_REF_COUNT references; #if OPENSSL_VERSION_NUMBER < 0x30200000 CRYPTO_RWLOCK *lock; #endif OSSL_FUNC_signature_newctx_fn *newctx; OSSL_FUNC_signature_sign_init_fn *sign_init; OSSL_FUNC_signature_sign_fn *sign; #if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_signature_sign_message_init_fn *sign_message_init; OSSL_FUNC_signature_sign_message_update_fn *sign_message_update; OSSL_FUNC_signature_sign_message_final_fn *sign_message_final; #endif OSSL_FUNC_signature_verify_init_fn *verify_init; OSSL_FUNC_signature_verify_fn *verify; #if OPENSSL_VERSION_NUMBER >= 0x30400000 OSSL_FUNC_signature_verify_message_init_fn *verify_message_init; OSSL_FUNC_signature_verify_message_update_fn *verify_message_update; OSSL_FUNC_signature_verify_message_final_fn *verify_message_final; #endif OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; OSSL_FUNC_signature_verify_recover_fn *verify_recover; OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; OSSL_FUNC_signature_digest_sign_fn *digest_sign; OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; OSSL_FUNC_signature_digest_verify_fn *digest_verify; OSSL_FUNC_signature_freectx_fn *freectx; OSSL_FUNC_signature_dupctx_fn *dupctx; OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; } QAT_EVP_SIGNATURE /* EVP_SIGNATURE for QAT Provider sm2 */; struct bignum_st { BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit * chunks. */ int top; /* Index of last used d +1. */ /* The next are internal book keeping for bn_expand. */ int dmax; /* Size of the d array. */ int neg; /* one if the number is negative */ int flags; }; static QAT_EVP_SIGNATURE get_default_signature_sm2() { static QAT_EVP_SIGNATURE s_signature; static int initilazed = 0; if (!initilazed) { QAT_EVP_SIGNATURE *signature = (QAT_EVP_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "SM2", "provider=default"); if (signature) { s_signature = *signature; EVP_SIGNATURE_free((QAT_EVP_SIGNATURE *)signature); initilazed = 1; } else { WARN("EVP_SIGNATURE_fetch from default provider failed"); } } return s_signature; } #endif void process_ecdsa_sm2_sign_reqs(mb_thread_data *tlv) { ecdsa_sm2_sign_op_data *ecdsa_sm2_sign_req_array[MULTIBUFF_BATCH] = {0}; unsigned char *sign_r[MULTIBUFF_BATCH] = {0}; unsigned char *sign_s[MULTIBUFF_BATCH] = {0};; const unsigned char *digest[MULTIBUFF_BATCH] = {0}; const BIGNUM *eph_key[MULTIBUFF_BATCH] = {0}; const BIGNUM *priv_key[MULTIBUFF_BATCH] = {0}; const int8u* id[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_sm2_sign_x[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_sm2_sign_y[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_sm2_sign_z[MULTIBUFF_BATCH] = {0}; int id_len[MULTIBUFF_BATCH] = {0}; int digest_len[MULTIBUFF_BATCH] = {0}; unsigned int sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdsa_cycles_sign_execute); /* Build Arrays of pointers for call */ DEBUG("Dequeue ECDSA SM2 sign reqs.\n"); while ((ecdsa_sm2_sign_req_array[req_num] = mb_queue_ecdsa_sm2_sign_dequeue(tlv->ecdsa_sm2_sign_queue)) != NULL) { sign_r[req_num] = ecdsa_sm2_sign_req_array[req_num]->sign_r; sign_s[req_num] = ecdsa_sm2_sign_req_array[req_num]->sign_s; digest[req_num] = ecdsa_sm2_sign_req_array[req_num]->digest; eph_key[req_num] = ecdsa_sm2_sign_req_array[req_num]->eph_key; priv_key[req_num] = ecdsa_sm2_sign_req_array[req_num]->priv_key; id[req_num] = ecdsa_sm2_sign_req_array[req_num]->id; ecdsa_sm2_sign_x[req_num] = (const BIGNUM* const)ecdsa_sm2_sign_req_array[req_num]->x; ecdsa_sm2_sign_y[req_num] = (const BIGNUM* const)ecdsa_sm2_sign_req_array[req_num]->y; ecdsa_sm2_sign_z[req_num] = (const BIGNUM* const)ecdsa_sm2_sign_req_array[req_num]->z; id_len[req_num] = (const int)ecdsa_sm2_sign_req_array[req_num]->id_len; digest_len[req_num] = (const int)ecdsa_sm2_sign_req_array[req_num]->dig_len; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d ECDSA SM2 sign requests\n", local_request_no); sts = mbx_sm2_ecdsa_sign_ssl_mb8(sign_r, sign_s, id, id_len, digest, digest_len, eph_key, priv_key, ecdsa_sm2_sign_x, ecdsa_sm2_sign_y, ecdsa_sm2_sign_z, NULL); for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdsa_sm2_sign_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer ECDSA SM2 Sign request[%d] success\n", req_num); *ecdsa_sm2_sign_req_array[req_num]->sts = 1; } else { WARN("Multibuffer ECDSA SM2 Sign request[%d] failure - sts %d\n", req_num, MBX_GET_STS(sts, req_num)); *ecdsa_sm2_sign_req_array[req_num]->sts = 0; } } if (ecdsa_sm2_sign_req_array[req_num]->job) { qat_wake_job(ecdsa_sm2_sign_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdsa_sm2_sign_req_array[req_num], sizeof(ecdsa_sm2_sign_op_data)); mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_ecdsa_sm2_sign_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&ecdsa_cycles_sign_execute, 1, "[ECDSA:sign_execute]"); DEBUG("Processed Final Request\n"); } void process_ecdsa_sm2_verify_reqs(mb_thread_data *tlv) { ecdsa_sm2_verify_op_data *ecdsa_sm2_verify_req_array[MULTIBUFF_BATCH] = {0}; const int8u* id[MULTIBUFF_BATCH] = {0}; const int8u* digest[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_sm2_verify_x[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_sm2_verify_y[MULTIBUFF_BATCH] = {0}; const BIGNUM *ecdsa_sm2_verify_z[MULTIBUFF_BATCH] = {0}; int id_len[MULTIBUFF_BATCH] = {0}; int digest_len[MULTIBUFF_BATCH] = {0}; const ECDSA_SIG *sig[MULTIBUFF_BATCH] = {0}; unsigned int sts = 0; int local_request_no = 0; int req_num = 0; START_RDTSC(&ecdsa_cycles_verify_execute); /* Build Arrays of pointers for call */ while ((ecdsa_sm2_verify_req_array[req_num] = mb_queue_ecdsa_sm2_verify_dequeue(tlv->ecdsa_sm2_verify_queue)) != NULL) { sig[req_num] = ecdsa_sm2_verify_req_array[req_num]->s; digest[req_num] = (int8u*)ecdsa_sm2_verify_req_array[req_num]->digest; id[req_num] = (int8u*)ecdsa_sm2_verify_req_array[req_num]->id; ecdsa_sm2_verify_x[req_num] = (const BIGNUM* const)ecdsa_sm2_verify_req_array[req_num]->x; ecdsa_sm2_verify_y[req_num] = (const BIGNUM* const)ecdsa_sm2_verify_req_array[req_num]->y; ecdsa_sm2_verify_z[req_num] = (const BIGNUM* const)ecdsa_sm2_verify_req_array[req_num]->z; id_len[req_num] = (const int)ecdsa_sm2_verify_req_array[req_num]->id_len; digest_len[req_num] = (const int)ecdsa_sm2_verify_req_array[req_num]->dig_len; req_num++; if (req_num == MULTIBUFF_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d ECDSA_SM2 verify requests\n", local_request_no); sts = mbx_sm2_ecdsa_verify_ssl_mb8(sig, id, id_len, digest, digest_len, ecdsa_sm2_verify_x, ecdsa_sm2_verify_y, ecdsa_sm2_verify_z, NULL); for (req_num = 0; req_num < local_request_no; req_num++) { if (ecdsa_sm2_verify_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sts, req_num) == MBX_STATUS_OK) { DEBUG("Multibuffer ECDSA_SM2 Verify request[%d] success\n", req_num); *ecdsa_sm2_verify_req_array[req_num]->sts = 1; } else { WARN("Multibuffer ECDSA_SM2 Verify request[%d] failure - sts %d\n", req_num, MBX_GET_STS(sts, req_num)); *ecdsa_sm2_verify_req_array[req_num]->sts = 0; } } if (ecdsa_sm2_verify_req_array[req_num]->job) { qat_wake_job(ecdsa_sm2_verify_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(ecdsa_sm2_verify_req_array[req_num], sizeof(ecdsa_sm2_verify_op_data)); mb_flist_ecdsa_sm2_verify_push(tlv->ecdsa_sm2_verify_freelist, ecdsa_sm2_verify_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_ecdsa_sm2_verify_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&ecdsa_cycles_verify_execute, 1, "[ECDSA:verify_execute]"); DEBUG("Processed Final Request\n"); } /* OpenSSL Softare implementation for synchronous requests, * Since OpenSSL doesn't support single shot operation * and it has to be digest and then sign, Whereas crypto_mb only * supports single shot operation for performance reasons. * Had to use this code here from OpenSSL as OpenSSL throws error * (ONLY_ONESHOT_SUPPORTED) when doing EVP_DigestUpdate() from * digest_custom if digestsign is registered from engine */ int qat_sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const EC_KEY *key) { int rc = 0; const EC_GROUP *group = EC_KEY_get0_group(key); BN_CTX *ctx = NULL; EVP_MD_CTX *hash = NULL; BIGNUM *p = NULL; BIGNUM *a = NULL; BIGNUM *b = NULL; BIGNUM *xG = NULL; BIGNUM *yG = NULL; BIGNUM *xA = NULL; BIGNUM *yA = NULL; int p_bytes = 0; uint8_t *buf = NULL; uint16_t entl = 0; uint8_t e_byte = 0; hash = EVP_MD_CTX_new(); ctx = BN_CTX_secure_new(); BN_CTX_start(ctx); if (hash == NULL || ctx == NULL) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_MALLOC_FAILURE); WARN("Hash internal error\n"); goto done; } p = BN_CTX_get(ctx); a = BN_CTX_get(ctx); b = BN_CTX_get(ctx); xG = BN_CTX_get(ctx); yG = BN_CTX_get(ctx); xA = BN_CTX_get(ctx); yA = BN_CTX_get(ctx); if (yA == NULL) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_MALLOC_FAILURE); WARN("Hash internal error\n"); goto done; } if (!EVP_DigestInit(hash, digest)) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); WARN("Hash internal error\n"); goto done; } /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */ if (id_len >= (UINT16_MAX / 8)) { /* too large */ QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_ID_TOO_LARGE); WARN("id_len too large\n"); goto done; } entl = (uint16_t)(8 * id_len); e_byte = entl >> 8; if (!EVP_DigestUpdate(hash, &e_byte, 1)) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); WARN("EVP Digest Failure\n"); goto done; } e_byte = entl & 0xFF; if (!EVP_DigestUpdate(hash, &e_byte, 1)) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); WARN("EVP Digest Failure\n"); goto done; } if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_EVP_LIB); WARN("EVP Digest Failure\n"); goto done; } if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_EC_LIB); WARN("EC Group get curve failed\n"); goto done; } p_bytes = BN_num_bytes(p); buf = OPENSSL_zalloc(p_bytes); if (buf == NULL) { WARN("Malloc Failure\n"); goto done; } if (BN_bn2binpad(a, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || BN_bn2binpad(b, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EC_POINT_get_affine_coordinates(group, EC_GROUP_get0_generator(group), xG, yG, ctx) || BN_bn2binpad(xG, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || BN_bn2binpad(yG, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EC_POINT_get_affine_coordinates(group, EC_KEY_get0_public_key(key), xA, yA, ctx) || BN_bn2binpad(xA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || BN_bn2binpad(yA, buf, p_bytes) < 0 || !EVP_DigestUpdate(hash, buf, p_bytes) || !EVP_DigestFinal(hash, out, NULL)) { QATerr(QAT_F_QAT_SM2_COMPUTE_Z_DIGEST, QAT_R_INTERNAL_ERROR); WARN("EVP Digest Operation failure\n"); goto done; } rc = 1; done: OPENSSL_free(buf); BN_CTX_free(ctx); EVP_MD_CTX_free(hash); return rc; } # ifndef QAT_OPENSSL_PROVIDER int mb_sm2_init(EVP_PKEY_CTX *ctx) { QAT_SM2_PKEY_CTX *smctx = NULL; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return 0; } if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) { WARN("smctx alloc Failure\n"); QATerr(QAT_F_MB_SM2_INIT, QAT_R_MALLOC_FAILURE); return 0; } EVP_PKEY_CTX_set_data(ctx, smctx); return 1; } void mb_sm2_cleanup(EVP_PKEY_CTX *ctx) { QAT_SM2_PKEY_CTX *smctx = NULL; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL \n"); return; } smctx = (QAT_SM2_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx); if (smctx == NULL) { WARN("smctx is NULL\n"); return; } EC_GROUP_free(smctx->gen_group); OPENSSL_free(smctx->id); OPENSSL_free(smctx); } int mb_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *)EVP_PKEY_CTX_get_data(ctx); EC_GROUP *group; uint8_t *tmp_id; if (unlikely(smctx == NULL)) { WARN("smctx cannot be NULL\n"); QATerr(QAT_F_MB_SM2_CTRL, QAT_R_CTX_NULL); return 0; } switch (type) { case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { WARN("Invalid curve\n"); QATerr(QAT_F_MB_SM2_CTRL, QAT_R_INVALID_CURVE); return 0; } EC_GROUP_free(smctx->gen_group); smctx->gen_group = group; return 1; case EVP_PKEY_CTRL_EC_PARAM_ENC: if (smctx->gen_group == NULL) { WARN("gen group NULL\n"); QATerr(QAT_F_MB_SM2_CTRL, QAT_R_NO_PARAMETERS_SET); return 0; } EC_GROUP_set_asn1_flag(smctx->gen_group, p1); return 1; case EVP_PKEY_CTRL_MD: smctx->md = p2; return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = smctx->md; return 1; case EVP_PKEY_CTRL_SET1_ID: if (p1 > 0) { tmp_id = OPENSSL_malloc(p1); if (tmp_id == NULL) { WARN("Malloc Failure\n"); QATerr(QAT_F_MB_SM2_CTRL, QAT_R_MALLOC_FAILURE); return 0; } memcpy(tmp_id, p2, p1); OPENSSL_free(smctx->id); smctx->id = tmp_id; } else { /* set null-ID */ OPENSSL_free(smctx->id); smctx->id = NULL; } smctx->id_len = (size_t)p1; smctx->id_set = 1; return 1; case EVP_PKEY_CTRL_GET1_ID: memcpy(p2, smctx->id, smctx->id_len); return 1; case EVP_PKEY_CTRL_GET1_ID_LEN: *(size_t *)p2 = smctx->id_len; return 1; /* Default behaviour is OK */ case EVP_PKEY_CTRL_PEER_KEY: case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_CMS_SIGN: case EVP_PKEY_CTRL_DIGESTINIT: /* nothing to be inited, this is to suppress the error... */ return 1; default: return -2; } } static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, const EC_KEY *key, const uint8_t *id, const size_t id_len, const uint8_t *msg, size_t msg_len) { EVP_MD_CTX *hash = EVP_MD_CTX_new(); const int md_size = EVP_MD_size(digest); uint8_t *z = NULL; BIGNUM *e = NULL; if (md_size < 0) { WARN("md_size is less than zero\n"); goto done; } z = OPENSSL_zalloc(md_size); if (hash == NULL || z == NULL) { WARN("Hash internal error\n"); goto done; } if (!qat_sm2_compute_z_digest(z, digest, id, id_len, key)) { /* QATerr already called */ goto done; } if (!EVP_DigestInit(hash, digest) || !EVP_DigestUpdate(hash, z, md_size) || !EVP_DigestUpdate(hash, msg, msg_len) /* reuse z buffer to hold H(Z || M) */ || !EVP_DigestFinal(hash, z, NULL)) { WARN("Hash internal error\n"); goto done; } e = BN_bin2bn(z, md_size, NULL); if (e == NULL) { WARN("Hash internal error\n"); } done: OPENSSL_free(z); EVP_MD_CTX_free(hash); return e; } int mb_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { /* Do nothing as this is taken care in use_sw_method within * corresponding digestsign and digestverify function */ return 1; } # endif # ifdef QAT_OPENSSL_PROVIDER int mb_ecdsa_sm2_sign(QAT_PROV_SM2_CTX *smctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) # else int mb_ecdsa_sm2_sign(EVP_MD_CTX *mctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) # endif { int ret = 0, len = 0, job_ret = 0, sts = 0; BN_CTX *ctx = NULL; ECDSA_SIG *s; ASYNC_JOB *job; size_t buflen; static __thread int req_num = 0; const EC_GROUP *group; BIGNUM *k = NULL; const BIGNUM *priv_key, *order; const EC_POINT *pub_key = NULL; BIGNUM *ecdsa_sig_r = NULL, *ecdsa_sig_s = NULL; ecdsa_sm2_sign_op_data *ecdsa_sm2_sign_req = NULL; mb_thread_data *tlv = NULL; BIGNUM *x = NULL, *y = NULL, *z = NULL; int sig_sz; /* Only used for OpenSSL 3 legacy engine API */ #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) QAT_PROV_SM2_CTX *sw_ctx; #endif #ifndef QAT_OPENSSL_PROVIDER unsigned char *dgst = NULL; BIGNUM *e = NULL; EVP_MD *md = NULL; int dlen = 0; #endif #ifdef QAT_OPENSSL_3 QAT_EVP_SIGNATURE sw_sm2_signature; #else int (*psign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) = NULL; #endif # ifdef QAT_OPENSSL_PROVIDER const EC_KEY *eckey = smctx->ec; # else EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(mctx); EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); # endif DEBUG("Entering \n"); if (unlikely(eckey == NULL) || unlikely(siglen == NULL)) { WARN("Invalid Input params\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_INPUT_PARAM_INVALID); return ret; } sig_sz = ECDSA_size(eckey); /* To know how much memory is needed to store the sig */ if (sig == NULL) { *siglen = (size_t)sig_sz; return 1; } if (*siglen < (size_t)sig_sz) { WARN("Invalid Input param\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_INPUT_PARAM_INVALID); return ret; } group = EC_KEY_get0_group(eckey); priv_key = EC_KEY_get0_private_key(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || priv_key == NULL || pub_key == NULL) { WARN("Either group, priv_key or pub_key are NULL\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return ret; } # ifndef QAT_OPENSSL_PROVIDER QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *)EVP_PKEY_CTX_get_data(pctx); if (!smctx->id_set) { smctx->id_set = 1; smctx->id = (uint8_t*)OPENSSL_memdup(SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN); smctx->id_len = SM2_DEFAULT_USERID_LEN; } # endif if ((qat_openssl3_sm2_fallback == 1) || (!qat_sw_sm2_offload)) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((ecdsa_sm2_sign_req = mb_flist_ecdsa_sm2_sign_pop(tlv->ecdsa_sm2_sign_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW ECDSA SM2 Sign Started %p\n", ecdsa_sm2_sign_req); START_RDTSC(&ecdsa_cycles_sign_setup); /* Buffer up the requests and call the new functions when we have enough * requests buffered up */ if ((s = ECDSA_SIG_new()) == NULL) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failure to allocate ECDSA_SIG\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_ECDSA_SIG_MALLOC_FAILURE); return ret; } ecdsa_sig_r = BN_new(); ecdsa_sig_s = BN_new(); /* NULL checking of ecdsa_sig_r & ecdsa_sig_s done in ECDSA_SIG_set0() */ if (ECDSA_SIG_set0(s, ecdsa_sig_r, ecdsa_sig_s) == 0) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failure to allocate r and s values to assign to the ECDSA_SIG\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_ECDSA_SIG_SET_R_S_FAILURE); goto err; } if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); k = BN_CTX_get(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); z = BN_CTX_get(ctx); if (k == NULL || x == NULL || y == NULL || z == NULL) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failed to allocate k or x or y or z\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_X_Y_Z_MALLOC_FAILURE); goto err; } if ((order = EC_GROUP_get0_order(group)) == NULL) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failure to get order from group\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_GET_ORDER_FAILURE); goto err; } len = BN_num_bits(order); buflen = (len + 7) / 8; /* Get random k */ do { if (!BN_priv_rand_range(k, order)) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failure in BN_priv_rand_range\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_RAND_GENERATE_FAILURE); goto err; } } while (BN_is_zero(k)); if (!EC_POINT_get_Jprojective_coordinates_GFp(group, pub_key, x, y, z,ctx)) { mb_flist_ecdsa_sm2_sign_push(tlv->ecdsa_sm2_sign_freelist, ecdsa_sm2_sign_req); WARN("Failure to get the Jacobian coordinates for public Key\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_INTERNAL_ERROR); goto err; } ecdsa_sm2_sign_req->sign_r = sig; ecdsa_sm2_sign_req->sign_s = sig + buflen; ecdsa_sm2_sign_req->eph_key = k; ecdsa_sm2_sign_req->priv_key = priv_key; ecdsa_sm2_sign_req->job = job; ecdsa_sm2_sign_req->sts = &sts; ecdsa_sm2_sign_req->x = x; ecdsa_sm2_sign_req->y = y; ecdsa_sm2_sign_req->z = z; ecdsa_sm2_sign_req->id = smctx->id; ecdsa_sm2_sign_req->id_len = smctx->id_len; ecdsa_sm2_sign_req->digest = tbs; ecdsa_sm2_sign_req->dig_len = tbslen; mb_queue_ecdsa_sm2_sign_enqueue(tlv->ecdsa_sm2_sign_queue, ecdsa_sm2_sign_req); STOP_RDTSC(&ecdsa_cycles_sign_setup, 1, "[ECDSA:sign_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdsa_sm2_sign_req, sts); do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdsa_sm2_sign_req, sts); if (sts) { /* Convert the buffers to BN */ BN_bin2bn(sig, buflen, ecdsa_sig_r); BN_bin2bn(sig + buflen, buflen, ecdsa_sig_s); *siglen = i2d_ECDSA_SIG(s, &sig); DEBUG("siglen %zu, tbslen %zu\n", *siglen, tbslen); ECDSA_SIG_free(s); ret = 1; } else { WARN("Failure in ECDSA Sign\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_ECDSA_SIGN_FAILURE); goto err; } err: if (!ret) { ECDSA_SIG_free(s); if (siglen != NULL) *siglen = 0; } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ret; use_sw_method: #ifdef QAT_OPENSSL_PROVIDER /* When using OpenSSL 3 provider API */ sw_sm2_signature = get_default_signature_sm2(); if (sw_sm2_signature.digest_sign) { return sw_sm2_signature.digest_sign((void*)smctx, sig, siglen, sigsize, tbs, tbslen); } else { if (sw_sm2_signature.digest_sign_update == NULL || sw_sm2_signature.digest_sign_final == NULL) { WARN("ECDSA digest_sign_update is NULL or digest_sign_final is NULL\n"); QATerr(QAT_F_MB_ECDSA_SM2_SIGN, QAT_R_ECDSA_SIGN_NULL); return 0; } if (sw_sm2_signature.digest_sign_update((void*)smctx, tbs, tbslen) <= 0) { return 0; } return sw_sm2_signature.digest_sign_final((void*)smctx, sig, siglen, sigsize); } #else # ifdef QAT_OPENSSL_3 /* When using OpenSSL 3 legacy engine API */ sw_sm2_signature = get_default_signature_sm2(); sw_ctx = OPENSSL_malloc(sizeof(QAT_PROV_SM2_CTX)); sw_ctx->mdsize = 0; sw_ctx->ec = (EC_KEY *)eckey; md = (EVP_MD *)EVP_sm3(); e = sm2_compute_msg_hash(md, eckey, smctx->id, smctx->id_len, tbs, tbslen); dgst = OPENSSL_zalloc(SM3_DIGEST_LENGTH); dlen = BN_bn2bin(e, dgst); if (sw_sm2_signature.sign) { sts = sw_sm2_signature.sign(sw_ctx, sig, siglen, ECDSA_size(eckey), dgst, dlen); } else { WARN("Failed to obtain sm2 sign func from default provider.\n"); sts = 0; } OPENSSL_free(dgst); BN_free(e); OPENSSL_free(sw_ctx); return sts; # else /* When using OpenSSL 1.1.1 */ EVP_PKEY_meth_get_sign((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &psign); md = (EVP_MD *)EVP_sm3(); e = sm2_compute_msg_hash(md, eckey, smctx->id, smctx->id_len, tbs, tbslen); dgst = OPENSSL_zalloc(SM3_DIGEST_LENGTH); dlen = BN_bn2bin(e, dgst); sts = (*psign)(pctx, sig, siglen, dgst, dlen); OPENSSL_free(dgst); BN_free(e); DEBUG("SW Finished\n"); return sts; # endif #endif } # ifdef QAT_OPENSSL_PROVIDER int mb_ecdsa_sm2_verify(QAT_PROV_SM2_CTX *smctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) # else int mb_ecdsa_sm2_verify(EVP_MD_CTX *mctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) # endif { int ret = 0, sts =0, job_ret = 0; const EC_GROUP *group = NULL; const BIGNUM *order = NULL; const EC_POINT *pub_key = NULL; ASYNC_JOB *job; ecdsa_sm2_verify_op_data *ecdsa_sm2_verify_req = NULL; mb_thread_data *tlv = NULL; BIGNUM *x = NULL, *y = NULL, *z = NULL; static __thread int req_num = 0; ECDSA_SIG *s = NULL; BN_CTX *ctx = NULL; const unsigned char *p = sig; unsigned char *der = NULL; int derlen = -1; /* Only used for OpenSSL 3 legacy engine API */ #if defined(QAT_OPENSSL_3) && !defined(QAT_OPENSSL_PROVIDER) QAT_PROV_SM2_CTX *sw_ctx; #endif #ifndef QAT_OPENSSL_PROVIDER unsigned char *dgst = NULL; BIGNUM *e = NULL; EVP_MD *md = NULL; int dlen = 0; #endif #ifdef QAT_OPENSSL_3 QAT_EVP_SIGNATURE sw_sm2_signature; #else int (*pverify) (EVP_PKEY_CTX *pctx, const unsigned char *sig, size_t siglen, const unsigned char *dgst, size_t tbslen) = NULL; #endif # ifdef QAT_OPENSSL_PROVIDER const EC_KEY *eckey = smctx->ec; # else EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(mctx); EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); const EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); # endif if (unlikely(eckey == NULL)) { WARN("Invalid Input param\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_INPUT_PARAM_INVALID); return ret; } group = EC_KEY_get0_group(eckey); pub_key = EC_KEY_get0_public_key(eckey); if (group == NULL || pub_key == NULL) { WARN("Either group or pub_key are NULL\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_GROUP_PRIV_KEY_PUB_KEY_NULL); return ret; } # ifndef QAT_OPENSSL_PROVIDER QAT_SM2_PKEY_CTX *smctx = (QAT_SM2_PKEY_CTX *)EVP_PKEY_CTX_get_data(pctx); if (!smctx->id_set) { smctx->id_set = 1; smctx->id = (uint8_t*)OPENSSL_memdup(SM2_DEFAULT_USERID, SM2_DEFAULT_USERID_LEN); smctx->id_len = SM2_DEFAULT_USERID_LEN; } # endif if ((qat_openssl3_sm2_fallback == 1) || (!qat_sw_sm2_offload)) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((ecdsa_sm2_verify_req = mb_flist_ecdsa_sm2_verify_pop(tlv->ecdsa_sm2_verify_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW ECDSA SM2 Verify Started %p\n", ecdsa_sm2_verify_req); START_RDTSC(&ecdsa_cycles_verify_setup); /* Buffer up the requests and call the new functions when we have enough * requests buffered up */ if ((s = ECDSA_SIG_new()) == NULL) { mb_flist_ecdsa_sm2_verify_push(tlv->ecdsa_sm2_verify_freelist, ecdsa_sm2_verify_req); WARN("Failure to allocate ECDSA_SIG_SM2\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_ECDSA_SIG_MALLOC_FAILURE); return ret; } if (d2i_ECDSA_SIG(&s, &p, siglen) == NULL) { WARN("Failure to get ECDSA_SIG_SM2\n"); return ret; } /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_ECDSA_SIG(s, &der); if (derlen != siglen || memcmp(sig, der, derlen) != 0) { WARN("Failure to get ECDSA_SIG_SM2\n"); return ret; } if ((ctx = BN_CTX_new()) == NULL) { mb_flist_ecdsa_sm2_verify_push(tlv->ecdsa_sm2_verify_freelist, ecdsa_sm2_verify_req); WARN("Failure to allocate ctx\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_CTX_MALLOC_FAILURE); goto err; } BN_CTX_start(ctx); x = BN_CTX_get(ctx); y = BN_CTX_get(ctx); z = BN_CTX_get(ctx); if (x == NULL || y == NULL || z == NULL) { mb_flist_ecdsa_sm2_verify_push(tlv->ecdsa_sm2_verify_freelist, ecdsa_sm2_verify_req); WARN("Failed to allocate x or y or z\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_X_Y_Z_MALLOC_FAILURE); goto err; } if (!EC_POINT_get_Jprojective_coordinates_GFp(group, pub_key, x, y, z, ctx)) { mb_flist_ecdsa_sm2_verify_push(tlv->ecdsa_sm2_verify_freelist, ecdsa_sm2_verify_req); WARN("Failure to get the Jacobian coordinates for public Key\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_INTERNAL_ERROR); goto err; } if ((order = EC_GROUP_get0_order(group)) == NULL) { mb_flist_ecdsa_sm2_verify_push(tlv->ecdsa_sm2_verify_freelist, ecdsa_sm2_verify_req); WARN("Failure to get order from group\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_GET_ORDER_FAILURE); goto err; } ecdsa_sm2_verify_req->s = s; ecdsa_sm2_verify_req->x = x; ecdsa_sm2_verify_req->y = y; ecdsa_sm2_verify_req->z = z; ecdsa_sm2_verify_req->job = job; ecdsa_sm2_verify_req->sts = &sts; ecdsa_sm2_verify_req->id = smctx->id; ecdsa_sm2_verify_req->id_len = smctx->id_len; ecdsa_sm2_verify_req->digest = tbs; ecdsa_sm2_verify_req->dig_len = tbslen; mb_queue_ecdsa_sm2_verify_enqueue(tlv->ecdsa_sm2_verify_queue, ecdsa_sm2_verify_req); STOP_RDTSC(&ecdsa_cycles_verify_setup, 1, "[ECDSA:verify_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d\n", ecdsa_sm2_verify_req, sts); do { /* If we get a failure on qat_pause_job then we will * not flag an error here and quit because we have * an asynchronous request in flight. * We don't want to start cleaning up data * structures that are still being used. If * qat_pause_job fails we will just yield and * loop around and try again until the request * completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", ecdsa_sm2_verify_req, sts); if (sts) { ret = 1; ECDSA_SIG_free(s); OPENSSL_free(der); } else { WARN("Failure in ECDSA_SM2 Verify\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_ECDSA_VERIFY_FAILURE); goto err; } err: if (!ret) { ECDSA_SIG_free(s); OPENSSL_free(der); } if (ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } return ret; use_sw_method: #ifdef QAT_OPENSSL_PROVIDER /* When using OpenSSL 3 provider API */ sw_sm2_signature = get_default_signature_sm2(); if (sw_sm2_signature.digest_verify) { return sw_sm2_signature.digest_verify((void*)smctx, sig, siglen, tbs, tbslen); } else { if (sw_sm2_signature.digest_verify_update == NULL || sw_sm2_signature.digest_verify_final == NULL) { WARN("ECDSA digest_verify_update is NULL or digest_verify_final is NULL\n"); QATerr(QAT_F_MB_ECDSA_SM2_VERIFY, QAT_R_ECDSA_VERIFY_NULL); return -1; } if (sw_sm2_signature.digest_verify_update((void*)smctx, tbs, tbslen) <= 0) { return -1; } return sw_sm2_signature.digest_verify_final((void*)smctx, sig, siglen); } #else # ifdef QAT_OPENSSL_3 /* When using OpenSSL 3 legacy engine API */ sw_sm2_signature = get_default_signature_sm2(); sw_ctx = OPENSSL_malloc(sizeof(QAT_PROV_SM2_CTX)); sw_ctx->mdsize = 0; sw_ctx->ec = (EC_KEY *)eckey; md = (EVP_MD *)EVP_sm3(); e = sm2_compute_msg_hash(md, eckey, smctx->id, smctx->id_len, tbs, tbslen); dgst = OPENSSL_zalloc(SM3_DIGEST_LENGTH); dlen = BN_bn2bin(e, dgst); if (sw_sm2_signature.sign) { sts = sw_sm2_signature.verify(sw_ctx, sig, siglen, dgst, dlen); } else { WARN("Failed to obtain sm2 verify func from default provider.\n"); sts = 0; } OPENSSL_free(dgst); BN_free(e); OPENSSL_free(sw_ctx); return sts; # else /* When using OpenSSL 1.1.1 */ EVP_PKEY_meth_get_verify((EVP_PKEY_METHOD *)sw_sm2_pmeth, NULL, &pverify); md = (EVP_MD *)EVP_sm3(); e = sm2_compute_msg_hash(md, eckey, smctx->id, smctx->id_len, tbs, tbslen); dgst = OPENSSL_zalloc(SM3_DIGEST_LENGTH); dlen = BN_bn2bin(e, dgst); sts = (*pverify)(pctx, sig, siglen, dgst, dlen); OPENSSL_free(dgst); BN_free(e); DEBUG("SW Finished, ret: %d\n", sts); return sts; # endif #endif /* QAT_OPENSSL_PROVIDER */ } #endif /*ENABLE_QAT_SW_SM2*/ qatengine-1.9.0/qat_sw_sm2.h000066400000000000000000000104161500416242000157200ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm2.h * * This file provides multibuffer support interface for SM2 ECDSA * *****************************************************************************/ #ifndef QAT_SW_SM2_H # define QAT_SW_SM2_H # include # include # include # include # include /* Local includes */ # include "e_qat.h" # include "qat_utils.h" # include "qat_events.h" # include "qat_fork.h" # include "qat_evp.h" # include "qat_sw_request.h" # include "qat_sw_ec.h" # if defined(QAT_OPENSSL_3) || defined(QAT_OPENSSL_PROVIDER) # include "qat_prov_sign_sm2.h" # endif /* Crypto_mb includes */ # include "crypto_mb/ec_sm2.h" # include "crypto_mb/cpu_features.h" /* The default user id as specified in GM/T 0009-2012 */ # define SM2_DEFAULT_USERID "1234567812345678" # define SM2_DEFAULT_USERID_LEN sizeof(SM2_DEFAULT_USERID) - 1 # define SM3_DIGEST_LENGTH 32 # ifdef ENABLE_QAT_SW_SM2 int qat_sm2_compute_z_digest(uint8_t *out, const EVP_MD *digest, const uint8_t *id, const size_t id_len, const EC_KEY *key); # ifdef QAT_OPENSSL_PROVIDER int mb_ecdsa_sm2_sign(QAT_PROV_SM2_CTX *ctx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen); int mb_ecdsa_sm2_verify(QAT_PROV_SM2_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); # else int mb_ecdsa_sm2_sign(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); int mb_ecdsa_sm2_verify(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); # endif /* QAT_OPENSSL_PROVIDER */ #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_SW_SM2 int mb_sm2_init(EVP_PKEY_CTX *ctx); int mb_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); void mb_sm2_cleanup(EVP_PKEY_CTX *ctx); int mb_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); # endif #endif # endif /* ENABLE_QAT_SW_SM2 */ #endif /* QAT_SW_SM2_H */ qatengine-1.9.0/qat_sw_sm3.c000066400000000000000000000562141500416242000157220ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2020-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm3.c * * This file contains the engine implementation for SM3 QAT_SW operations * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include /* Local includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" #include "qat_sw_sm3.h" #include "qat_sw_request.h" /* Crypto_mb includes */ #include "crypto_mb/sm3.h" /* SM3 nid */ int sm3_nid[] = { NID_sm3, }; void process_sm3_init_reqs(mb_thread_data *tlv) { sm3_init_op_data *sm3_init_req_array[MULTIBUFF_SM3_BATCH] = {0}; SM3_CTX_mb16 sm3_init_ctx = {0}; unsigned int sm3_sts = 0; int local_request_no = 0; int req_num = 0, i = 0; START_RDTSC(&sm3_cycles_init_execute); /* Build Arrays of pointers for call */ while ((sm3_init_req_array[req_num] = mb_queue_sm3_init_dequeue(tlv->sm3_init_queue)) != NULL) { req_num++; if (req_num == MULTIBUFF_SM3_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d SM3 init requests\n", local_request_no); sm3_sts = mbx_sm3_init_mb16(&sm3_init_ctx); for (req_num = 0; req_num < local_request_no; req_num++) { if (sm3_init_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sm3_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM3 init request[%d] success\n", req_num); *sm3_init_req_array[req_num]->sts = 1; /* sm3_init_ctx->msg_buff_idx, msg_len and msg_buffer as it * will be initialized to zero in cryto_mb as well */ /* Copying only msg_hash as crypto_mb initializes it to * default hash values as per std instead of zero */ for (i=0; i < SM3_SIZE_IN_WORDS; i++) sm3_init_req_array[req_num]->state->msg_hash[i] = sm3_init_ctx.msg_hash[i][req_num]; } else { WARN("QAT_SW SM3 init request[%d] failure\n", req_num); *sm3_init_req_array[req_num]->sts = 0; } } if (sm3_init_req_array[req_num]->job) { qat_wake_job(sm3_init_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm3_init_req_array[req_num], sizeof(sm3_init_op_data)); mb_flist_sm3_init_push(tlv->sm3_init_freelist, sm3_init_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm3_init_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm3_cycles_init_execute, 1, "[SM3:init_execute]"); DEBUG("Processed Final Request\n"); } void process_sm3_update_reqs(mb_thread_data *tlv) { sm3_update_op_data *sm3_update_req_array[MULTIBUFF_SM3_BATCH] = {0}; int sm3_data_len[MULTIBUFF_SM3_BATCH] = {0}; const unsigned char *sm3_data[MULTIBUFF_SM3_BATCH] = {0}; SM3_CTX_mb16 sm3_update_ctx = {0}; unsigned int sm3_sts = 0; int local_request_no = 0; int req_num = 0, i = 0; START_RDTSC(&sm3_cycles_update_execute); /* Build Arrays of pointers for call */ while ((sm3_update_req_array[req_num] = mb_queue_sm3_update_dequeue(tlv->sm3_update_queue)) != NULL) { sm3_data_len[req_num] = sm3_update_req_array[req_num]->sm3_len; sm3_data[req_num] = sm3_update_req_array[req_num]->sm3_data; sm3_update_ctx.msg_buff_idx[req_num] = sm3_update_req_array[req_num]->state->msg_buff_idx; sm3_update_ctx.msg_len[req_num] = sm3_update_req_array[req_num]->state->msg_len; memcpy(sm3_update_ctx.msg_buffer[req_num], sm3_update_req_array[req_num]->state->msg_buffer, SM3_MSG_BLOCK_SIZE); for (i = 0; i < SM3_SIZE_IN_WORDS; i++) sm3_update_ctx.msg_hash[i][req_num] = sm3_update_req_array[req_num]->state->msg_hash[i]; req_num++; if (req_num == MULTIBUFF_SM3_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d SM3 Update requests\n", local_request_no); sm3_sts = mbx_sm3_update_mb16(sm3_data, sm3_data_len, &sm3_update_ctx); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(sm3_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM3 Update request[%d] success\n", req_num); *sm3_update_req_array[req_num]->sts = 1; sm3_update_req_array[req_num]->state->msg_buff_idx = sm3_update_ctx.msg_buff_idx[req_num]; sm3_update_req_array[req_num]->state->msg_len = sm3_update_ctx.msg_len[req_num]; memcpy(sm3_update_req_array[req_num]->state->msg_buffer, sm3_update_ctx.msg_buffer[req_num], SM3_MSG_BLOCK_SIZE); for (i = 0; i < SM3_SIZE_IN_WORDS; i++) sm3_update_req_array[req_num]->state->msg_hash[i] = sm3_update_ctx.msg_hash[i][req_num]; } else { WARN("QAT_SW SM3 Update request[%d] Failure\n", req_num); *sm3_update_req_array[req_num]->sts = 0; } if (sm3_update_req_array[req_num]->job) { qat_wake_job(sm3_update_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm3_update_req_array[req_num], sizeof(sm3_update_op_data)); mb_flist_sm3_update_push(tlv->sm3_update_freelist, sm3_update_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm3_update_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm3_cycles_update_execute, 1, "[SM3:update_execute]"); DEBUG("Processed Final Request\n"); } void process_sm3_final_reqs(mb_thread_data *tlv) { sm3_final_op_data *sm3_final_req_array[MULTIBUFF_SM3_BATCH] = {0}; int8u *sm3_hash[MULTIBUFF_SM3_BATCH] = {0}; SM3_CTX_mb16 sm3_final_ctx = {0}; unsigned int sm3_sts = 0; int local_request_no = 0; int req_num = 0, i = 0; START_RDTSC(&sm3_cycles_final_execute); /* Build Arrays of pointers for call */ while ((sm3_final_req_array[req_num] = mb_queue_sm3_final_dequeue(tlv->sm3_final_queue)) != NULL) { sm3_hash[req_num] = sm3_final_req_array[req_num]->sm3_hash; sm3_final_ctx.msg_buff_idx[req_num] = sm3_final_req_array[req_num]->state->msg_buff_idx; sm3_final_ctx.msg_len[req_num] = sm3_final_req_array[req_num]->state->msg_len; memcpy(sm3_final_ctx.msg_buffer[req_num], sm3_final_req_array[req_num]->state->msg_buffer, SM3_MSG_BLOCK_SIZE); for (i = 0; i < SM3_SIZE_IN_WORDS; i++) sm3_final_ctx.msg_hash[i][req_num] = sm3_final_req_array[req_num]->state->msg_hash[i]; req_num++; if (req_num == MULTIBUFF_SM3_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting %d SM3 Final requests\n", local_request_no); sm3_sts = mbx_sm3_final_mb16(sm3_hash, &sm3_final_ctx); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(sm3_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM3 Final request[%d] success\n", req_num); *sm3_final_req_array[req_num]->sts = 1; sm3_final_req_array[req_num]->state->msg_buff_idx = sm3_final_ctx.msg_buff_idx[req_num]; sm3_final_req_array[req_num]->state->msg_len = sm3_final_ctx.msg_len[req_num]; memcpy(sm3_final_req_array[req_num]->state->msg_buffer,sm3_final_ctx.msg_buffer[req_num], SM3_MSG_BLOCK_SIZE); for (i = 0; i < SM3_SIZE_IN_WORDS; i++) sm3_final_req_array[req_num]->state->msg_hash[i] = sm3_final_ctx.msg_hash[i][req_num]; } else { WARN("QAT_SW SM3 Final request[%d] Failure\n", req_num); *sm3_final_req_array[req_num]->sts = 0; } if (sm3_final_req_array[req_num]->job) { qat_wake_job(sm3_final_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm3_final_req_array[req_num], sizeof(sm3_final_op_data)); mb_flist_sm3_final_push(tlv->sm3_final_freelist, sm3_final_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm3_final_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm3_cycles_final_execute, 1, "[SM3:final_execute]"); DEBUG("Processed Final Request\n"); } #ifndef QAT_OPENSSL_PROVIDER int qat_sw_sm3_init(EVP_MD_CTX *ctx) #else int qat_sw_sm3_init(QAT_SM3_CTX_mb *ctx) #endif { ASYNC_JOB *job; int sts = 0, job_ret = 0; sm3_init_op_data *sm3_init_req = NULL; #ifndef QAT_OPENSSL_PROVIDER int (*sw_fn_ptr)(EVP_MD_CTX *) = NULL; #endif mb_thread_data *tlv = NULL; static __thread int req_num = 0; /* Check input parameters */ if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL.\n"); QATerr(QAT_F_QAT_SW_SM3_INIT, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER QAT_SM3_CTX_mb *sm3_ctx = (QAT_SM3_CTX_mb *) EVP_MD_CTX_md_data(ctx); #else QAT_SM3_CTX_mb *sm3_ctx = (QAT_SM3_CTX_mb *) ctx; sm3_ctx->sw_md_ctx = EVP_MD_CTX_new(); if (sm3_ctx->sw_md_ctx == NULL) WARN("EVP_MD_CTX_new failed.\n"); sm3_ctx->sw_md = EVP_MD_fetch(NULL, "sm3", "provider=default"); if (sm3_ctx->sw_md == NULL) WARN("EVP_MD_fetch failed.\n"); #endif if (unlikely(sm3_ctx == NULL)) { WARN("sm3_ctx (type QAT_SM3_CTX_mb) is NULL.\n"); QATerr(QAT_F_QAT_SW_SM3_INIT, QAT_R_CTX_NULL); return sts; } if ((qat_openssl3_sm3_fallback == 1) || (!qat_sw_sm3_offload)) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((sm3_init_req = mb_flist_sm3_init_pop(tlv->sm3_init_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM3 Init Started %p\n", sm3_init_req); START_RDTSC(&sm3_cycles_init_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm3_init_req->state = sm3_ctx; sm3_init_req->job = job; sm3_init_req->sts = &sts; mb_queue_sm3_init_enqueue(tlv->sm3_init_queue, sm3_init_req); STOP_RDTSC(&sm3_cycles_init_setup, 1, "[SM3:init_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM3_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm3_ctx %p\n", sm3_init_req, sts, sm3_init_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", sm3_init_req, sts); if (sts) { return sts; } else { WARN("Failure in SM3 Init\n"); QATerr(QAT_F_QAT_SW_SM3_INIT, QAT_R_SM3_INIT_FAILURE); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_fn_ptr = EVP_MD_meth_get_init((EVP_MD *)EVP_sm3()); sts = (*sw_fn_ptr)(ctx); DEBUG("SW Finished %p\n", ctx); return sts; #else if (!EVP_DigestInit_ex2(sm3_ctx->sw_md_ctx, sm3_ctx->sw_md, NULL)) { WARN("Software calculate failed \n"); return 0; } DEBUG("SW Init Finished %p\n", sm3_ctx); return 1; #endif } #ifndef QAT_OPENSSL_PROVIDER int qat_sw_sm3_update(EVP_MD_CTX *ctx, const void *in, size_t len) #else int qat_sw_sm3_update(QAT_SM3_CTX_mb *ctx, const void *in, size_t len) #endif { ASYNC_JOB *job; int sts = 0, job_ret = 0; sm3_update_op_data *sm3_update_req = NULL; #ifndef QAT_OPENSSL_PROVIDER int (*sw_fn_ptr)(EVP_MD_CTX *, const void *, size_t) = NULL; #endif mb_thread_data *tlv = NULL; static __thread int req_num = 0; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_MD_CTX) is NULL.\n"); QATerr(QAT_F_QAT_SW_SM3_UPDATE, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER QAT_SM3_CTX_mb *sm3_ctx = (QAT_SM3_CTX_mb *) EVP_MD_CTX_md_data(ctx); #else QAT_SM3_CTX_mb *sm3_ctx = (QAT_SM3_CTX_mb *) ctx; #endif if (unlikely(sm3_ctx == NULL)) { WARN("sm3_ctx (type QAT_SM3_CTX_mb) is NULL.\n"); QATerr(QAT_F_QAT_SW_SM3_UPDATE, QAT_R_CTX_NULL); return sts; } if ((qat_openssl3_sm3_fallback == 1) || (!qat_sw_sm3_offload)) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((sm3_update_req = mb_flist_sm3_update_pop(tlv->sm3_update_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM3 Update Started %p len %zu\n", sm3_update_req, len); START_RDTSC(&sm3_cycles_update_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm3_update_req->state = sm3_ctx; sm3_update_req->sm3_data = (const unsigned char *)in; sm3_update_req->sm3_len = len; sm3_update_req->job = job; sm3_update_req->sts = &sts; mb_queue_sm3_update_enqueue(tlv->sm3_update_queue, sm3_update_req); STOP_RDTSC(&sm3_cycles_update_setup, 1, "[SM3:update_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM3_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm3_ctx %p\n", sm3_update_req, sts, sm3_update_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", sm3_update_req, sts); if (sts) { return sts; } else { WARN("Failure in SM3 Update\n"); QATerr(QAT_F_QAT_SW_SM3_UPDATE, QAT_R_SM3_UPDATE_FAILURE); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_fn_ptr = EVP_MD_meth_get_update((EVP_MD *)EVP_sm3()); sts = (*sw_fn_ptr)(ctx, in, len); DEBUG("SW Finished %p\n", ctx); return sts; #else if (!EVP_DigestUpdate(sm3_ctx->sw_md_ctx, in, len)) { WARN("Software calculate failed \n"); return 0; } DEBUG("SW Update Finished %p\n", sm3_ctx); return 1; #endif } #ifndef QAT_OPENSSL_PROVIDER int qat_sw_sm3_final(EVP_MD_CTX *ctx, unsigned char *md) #else int qat_sw_sm3_final(QAT_SM3_CTX_mb *ctx, unsigned char *md) #endif { ASYNC_JOB *job; int sts = 0, job_ret = 0; sm3_final_op_data *sm3_final_req = NULL; #ifndef QAT_OPENSSL_PROVIDER int (*sw_fn_ptr)(EVP_MD_CTX *, unsigned char *) = NULL; #endif mb_thread_data *tlv = NULL; static __thread int req_num = 0; if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_PKEY_CTX) is NULL.\n"); QATerr(QAT_F_QAT_SW_SM3_FINAL, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER QAT_SM3_CTX_mb *sm3_ctx = (QAT_SM3_CTX_mb *) EVP_MD_CTX_md_data(ctx); #else QAT_SM3_CTX_mb *sm3_ctx = (QAT_SM3_CTX_mb *) ctx; #endif if (unlikely(sm3_ctx == NULL)) { WARN("sm3_ctx (type QAT_SM3_CTX_mb) is NULL.\n"); QATerr(QAT_F_QAT_SW_SM3_FINAL, QAT_R_CTX_NULL); return sts; } if ((qat_openssl3_sm3_fallback == 1) || (!qat_sw_sm3_offload)) { DEBUG("- Switched to software mode\n"); goto use_sw_method; } /* QAT SW initialization fail, switching to OpenSSL. */ if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((sm3_final_req = mb_flist_sm3_final_pop(tlv->sm3_final_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM3 final Started %p\n", sm3_final_req); START_RDTSC(&sm3_cycles_final_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm3_final_req->state = sm3_ctx; sm3_final_req->sm3_hash = md; sm3_final_req->job = job; sm3_final_req->sts = &sts; mb_queue_sm3_final_enqueue(tlv->sm3_final_queue, sm3_final_req); STOP_RDTSC(&sm3_cycles_final_setup, 1, "[SM3:final_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM3_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm3_ctx %p\n", sm3_final_req, sts, sm3_final_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: %p status = %d\n", sm3_final_req, sts); if (sts) { return sts; } else { WARN("Failure in SM3 Final\n"); QATerr(QAT_F_QAT_SW_SM3_FINAL, QAT_R_SM3_FINAL_FAILURE); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_fn_ptr = EVP_MD_meth_get_final((EVP_MD *)EVP_sm3()); sts = (*sw_fn_ptr)(ctx, md); DEBUG("SW Finished %p\n", ctx); return sts; #else if (!EVP_DigestFinal_ex(sm3_ctx->sw_md_ctx, md, NULL)) { WARN("Software calculate failed \n"); return 0; } DEBUG("SW Final Finished %p\n", sm3_ctx); return 1; #endif } qatengine-1.9.0/qat_sw_sm3.h000066400000000000000000000047311500416242000157240ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm3.h * * This file provides an SM3 interface for an OpenSSL engine * *****************************************************************************/ #ifndef QAT_SW_SM3_H # define QAT_SW_SM3_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include /* QAT_SW SM3 methods declaration */ const EVP_MD *qat_sw_create_sm3_meth(int nid , int key_type); void process_sm3_init_reqs(mb_thread_data *tlv); void process_sm3_update_reqs(mb_thread_data *tlv); void process_sm3_final_reqs(mb_thread_data *tlv); #endif /* QAT_SW_SM3_H */ qatengine-1.9.0/qat_sw_sm4_cbc.c000066400000000000000000000535261500416242000165350ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm4_cbc.c * * This file contains the engine implementation for SM4-CBC operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include /* Local includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" #include "qat_evp.h" #include "qat_sw_ec.h" #include "qat_sw_request.h" #include "qat_sw_sm4_cbc.h" #ifdef ENABLE_QAT_HW_SM4_CBC # include "qat_hw_sm4_cbc.h" #endif #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_sm4_cbc.h" #endif /* Crypto_mb includes */ #include "crypto_mb/sm4.h" #include "crypto_mb/cpu_features.h" #ifdef ENABLE_QAT_SW_SM4_CBC # define GET_SW_CIPHER(ctx) \ sm4_cipher_sw_impl(EVP_CIPHER_CTX_nid((ctx))) static inline const EVP_CIPHER *sm4_cipher_sw_impl(int nid) { switch (nid) { case NID_sm4_cbc: return EVP_sm4_cbc(); default: WARN("Invalid nid %d\n", nid); return NULL; } } #ifdef QAT_OPENSSL_PROVIDER static QAT_EVP_CIPHER_SM4_CBC get_default_cipher_sm4_cbc() { static QAT_EVP_CIPHER_SM4_CBC sm4_cipher; static int initilazed = 0; if (!initilazed) { QAT_EVP_CIPHER_SM4_CBC *cipher = (QAT_EVP_CIPHER_SM4_CBC *)EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); if (cipher) { sm4_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initilazed = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return sm4_cipher; } #endif static void process_mb_sm4_cbc_cipher_set_key(mbx_sm4_key_schedule *key_sched, const sm4_key **mb_key, int req_num) { mbx_status16 sm4_cbc_sts; int i; sm4_cbc_sts = mbx_sm4_set_key_mb16(key_sched, (const sm4_key**)mb_key); DEBUG("QAT_SW SM4_CBC cipher set key, sm4_cbc_sts=%llu \n", sm4_cbc_sts); for (i = 0; i < req_num; i++) { if (MBX_GET_STS(sm4_cbc_sts, i) != MBX_STATUS_OK) { WARN("QAT_SW SM4_CBC cipher set key[%d] failure\n", i); } } } void process_mb_sm4_cbc_cipher_enc_reqs(mb_thread_data *tlv) { sm4_cbc_cipher_op_data *sm4_cbc_cipher_req_array[MULTIBUFF_SM4_BATCH] = {0}; int local_request_no = 0; int req_num = 0; mbx_status16 sm4_cbc_sts; /* MB input data */ mbx_sm4_key_schedule key_sched __attribute__((aligned(64))) = {0}; const sm4_key *mb_key[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; const int8u *mb_iv[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; int8u *mb_out[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; const int8u *mb_in[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; int mb_in_len[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; START_RDTSC(&sm4_cbc_cycles_cipher_execute); /* Build Arrays of pointers for call */ while ((sm4_cbc_cipher_req_array[req_num] = mb_queue_sm4_cbc_cipher_dequeue(tlv->sm4_cbc_cipher_queue)) != NULL) { mb_key[req_num] = &(sm4_cbc_cipher_req_array[req_num]->in_key); mb_iv[req_num] = sm4_cbc_cipher_req_array[req_num]->in_iv; mb_out[req_num] = sm4_cbc_cipher_req_array[req_num]->in_out; mb_in[req_num] = sm4_cbc_cipher_req_array[req_num]->in_txt; mb_in_len[req_num] = sm4_cbc_cipher_req_array[req_num]->in_txt_len; req_num++; if (req_num == MULTIBUFF_SM4_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting req_num %d SM4_CBC cipher requests\n", local_request_no); process_mb_sm4_cbc_cipher_set_key(&key_sched, mb_key, local_request_no); sm4_cbc_sts = mbx_sm4_encrypt_cbc_mb16(mb_out, mb_in, mb_in_len, &key_sched, mb_iv); DEBUG("mbx_sm4_encrypt_cbc_mb16 sm4_cbc_sts=%llu \n", sm4_cbc_sts); for (req_num = 0; req_num < local_request_no; req_num++) { if (sm4_cbc_cipher_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sm4_cbc_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM4_CBC cipher request[%d] success\n", req_num); *sm4_cbc_cipher_req_array[req_num]->sts = 1; } else { WARN("QAT_SW SM4_CBC cipher request[%d] failure\n", req_num); *sm4_cbc_cipher_req_array[req_num]->sts = 0; } } if (sm4_cbc_cipher_req_array[req_num]->job) { qat_wake_job(sm4_cbc_cipher_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm4_cbc_cipher_req_array[req_num], sizeof(sm4_cbc_cipher_op_data)); mb_flist_sm4_cbc_cipher_push(tlv->sm4_cbc_cipher_freelist, sm4_cbc_cipher_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm4_cbc_cipher_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm4_cbc_cycles_cipher_execute, 1, "[SM4_CBC:cipher_execute]"); DEBUG("Processed SM4_CBC cipher Request\n"); } void process_mb_sm4_cbc_cipher_dec_reqs(mb_thread_data *tlv) { sm4_cbc_cipher_op_data *sm4_cbc_cipher_req_array[MULTIBUFF_SM4_BATCH] = {0}; int local_request_no = 0; int req_num = 0; mbx_status16 sm4_cbc_sts; /* MB input data */ mbx_sm4_key_schedule key_sched __attribute__((aligned(64))); const sm4_key *mb_key[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; const int8u *mb_iv[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; int8u *mb_out[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; const int8u *mb_in[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; int mb_in_len[MULTIBUFF_SM4_BATCH] __attribute__((aligned(64))) = {0}; START_RDTSC(&sm4_cbc_cycles_cipher_dec_execute); /* Build Arrays of pointers for call */ while ((sm4_cbc_cipher_req_array[req_num] = mb_queue_sm4_cbc_cipher_dequeue(tlv->sm4_cbc_cipher_dec_queue)) != NULL) { mb_key[req_num] = &(sm4_cbc_cipher_req_array[req_num]->in_key); mb_iv[req_num] = sm4_cbc_cipher_req_array[req_num]->in_iv; mb_out[req_num] = sm4_cbc_cipher_req_array[req_num]->in_out; mb_in[req_num] = sm4_cbc_cipher_req_array[req_num]->in_txt; mb_in_len[req_num] = sm4_cbc_cipher_req_array[req_num]->in_txt_len; req_num++; if (req_num == MULTIBUFF_SM4_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting req_num %d SM4_CBC cipher requests\n", local_request_no); process_mb_sm4_cbc_cipher_set_key(&key_sched, mb_key, local_request_no); sm4_cbc_sts = mbx_sm4_decrypt_cbc_mb16(mb_out, mb_in, mb_in_len, &key_sched, mb_iv); DEBUG("mbx_sm4_decrypt_cbc_mb16 sts=%llu \n", sm4_cbc_sts); for (req_num = 0; req_num < local_request_no; req_num++) { if (sm4_cbc_cipher_req_array[req_num]->sts != NULL) { if (MBX_GET_STS(sm4_cbc_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM4_CBC cipher request[%d] success\n", req_num); *sm4_cbc_cipher_req_array[req_num]->sts = 1; } else { WARN("QAT_SW SM4_CBC cipher request[%d] failure\n", req_num); *sm4_cbc_cipher_req_array[req_num]->sts = 0; } } if (sm4_cbc_cipher_req_array[req_num]->job) { qat_wake_job(sm4_cbc_cipher_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm4_cbc_cipher_req_array[req_num], sizeof(sm4_cbc_cipher_op_data)); mb_flist_sm4_cbc_cipher_push(tlv->sm4_cbc_cipher_dec_freelist, sm4_cbc_cipher_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm4_cbc_cipher_dec_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm4_cbc_cycles_cipher_dec_execute, 1, "[SM4_CBC:cipher_dec_execute]"); DEBUG("Processed SM4_CBC cipher decryption Request\n"); } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_cbc_key_init(void *ctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc) #else int qat_sw_sm4_cbc_key_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_CBC sw_sm4_cbc_cipher; QAT_PROV_CBC_CTX *sm4_cbc_ctx = (QAT_PROV_CBC_CTX *)ctx; #else SM4_CBC_CTX *sm4_cbc_ctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; #ifdef ENABLE_QAT_HW_SM4_CBC sm4cbc_coexistence_ctx *sm4cbc_hw_sw_ctx = NULL; #endif DEBUG("started: ctx=%p key=%p iv=%p enc=%d\n", ctx, key, iv, enc); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CBC_KEY_INIT, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_HW_SM4_CBC if (qat_sm4_cbc_coexist) { sm4cbc_hw_sw_ctx = (sm4cbc_coexistence_ctx *)(EVP_CIPHER_CTX_get_cipher_data(ctx)); sm4_cbc_ctx = &(sm4cbc_hw_sw_ctx->sm4cbc_qat_sw_ctx); } else { sm4_cbc_ctx = (SM4_CBC_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); } # else sm4_cbc_ctx = (SM4_CBC_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); # endif #endif if (sm4_cbc_ctx == NULL) { WARN("SM4-CBC CTX is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_CBC_KEY_INIT, QAT_R_CIPHER_DATA_NULL); return sts; } sm4_cbc_ctx->enc = enc; if (key == NULL) { WARN("SM4-CBC key is NULL \n"); #ifndef QAT_OPENSSL_PROVIDER QATerr(QAT_F_QAT_SW_SM4_CBC_KEY_INIT, QAT_R_KEY_NULL); return sts; #endif } else { DEBUG("qat_sw_sm4_cbc_key_init: save key=%p parameter for later use key_len=%u\n", key, SM4_KEY_SIZE); memmove(sm4_cbc_ctx->key, key, SM4_KEY_SIZE); } if (iv) { DEBUG("qat_sw_sm4_cbc_key_init: save iv=%p parameter for later use\n", iv); memmove(sm4_cbc_ctx->iv, iv, SM4_IV_LEN); sm4_cbc_ctx->iv_set = 1; } #ifdef QAT_OPENSSL_PROVIDER OSSL_PARAM params[2] = {OSSL_PARAM_END, OSSL_PARAM_END}; sw_sm4_cbc_cipher = get_default_cipher_sm4_cbc(); if (enc) { if (!sm4_cbc_ctx->sw_ctx) sm4_cbc_ctx->sw_ctx = sw_sm4_cbc_cipher.newctx(ctx); sts = sw_sm4_cbc_cipher.einit(sm4_cbc_ctx->sw_ctx, key, keylen, iv, ivlen, params); } else { if (!sm4_cbc_ctx->sw_ctx) sm4_cbc_ctx->sw_ctx = sw_sm4_cbc_cipher.newctx(ctx); unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); sts = sw_sm4_cbc_cipher.dinit(sm4_cbc_ctx->sw_ctx, key, keylen, iv, ivlen, params); } if (sts != 1) { QATerr(QAT_F_QAT_SW_SM4_CBC_KEY_INIT, QAT_R_INIT_FAILURE); return sts; } #else /* cipher context init, used by sw_fallback */ sw_ctx_cipher_data = OPENSSL_zalloc(sizeof(EVP_SM4_KEY)); if (sw_ctx_cipher_data == NULL) { QATerr(QAT_F_QAT_SW_SM4_CBC_KEY_INIT, QAT_R_MALLOC_FAILURE); WARN("Unable to allocate memory for sw_ctx_cipher_data.\n"); return sts; } EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_init(GET_SW_CIPHER(ctx))(ctx, key, iv, enc); if (sts != 1) { QATerr(QAT_F_QAT_SW_SM4_CBC_KEY_INIT, QAT_R_FALLBACK_INIT_FAILURE); WARN("Failed to init the openssl sw cipher context.\n"); return sts; } sm4_cbc_ctx->sw_ctx_cipher_data = sw_ctx_cipher_data; # ifdef ENABLE_QAT_HW_SM4_CBC if (qat_sm4_cbc_coexist) { EVP_CIPHER_CTX_set_cipher_data(ctx, sm4cbc_hw_sw_ctx); } else { EVP_CIPHER_CTX_set_cipher_data(ctx, sm4_cbc_ctx); } # else EVP_CIPHER_CTX_set_cipher_data(ctx, sm4_cbc_ctx); # endif #endif /* Save key in ctx and return, key_init will be done in cipher operation. */ return sts; } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_cbc_cipher(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t len) #else int qat_sw_sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { int sts = 0, job_ret = 0; ASYNC_JOB *job; sm4_cbc_cipher_op_data *sm4_cbc_cipher_req = NULL; #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_CBC sw_sm4_cbc_cipher; QAT_PROV_CBC_CTX *sm4_cbc_ctx = (QAT_PROV_CBC_CTX *)ctx; #else SM4_CBC_CTX *sm4_cbc_ctx = NULL; void *sw_ctx_cipher_data = NULL; #endif mb_thread_data *tlv = NULL; static __thread int req_num = 0; int8u *in_iv = NULL; sm4_key *in_key = NULL; int in_enc; #ifdef ENABLE_QAT_HW_SM4_CBC sm4cbc_coexistence_ctx *sm4cbc_hw_sw_ctx = NULL; #endif DEBUG("Started: ctx=%p out=%p in=%p len=%lu\n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CBC_CIPHER, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_HW_SM4_CBC if (qat_sm4_cbc_coexist) { sm4cbc_hw_sw_ctx = (sm4cbc_coexistence_ctx *)(EVP_CIPHER_CTX_get_cipher_data(ctx)); sm4_cbc_ctx = &(sm4cbc_hw_sw_ctx->sm4cbc_qat_sw_ctx); } else { sm4_cbc_ctx = (SM4_CBC_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); } # else sm4_cbc_ctx = (SM4_CBC_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); # endif #endif if (sm4_cbc_ctx == NULL) { WARN("SM4-CBC CTX is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_CBC_CIPHER, QAT_R_CIPHER_DATA_NULL); return sts; } in_key = &sm4_cbc_ctx->key; in_enc = sm4_cbc_ctx->enc; if (!sm4_cbc_ctx->iv_set) in_iv = EVP_CIPHER_CTX_iv_noconst(ctx); else in_iv = sm4_cbc_ctx->iv; #ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD # ifndef QAT_OPENSSL_PROVIDER if (len <= qat_pkt_threshold_table_get_threshold(EVP_CIPHER_CTX_nid(ctx))) goto use_sw_method; # else if (len <= qat_pkt_threshold_table_get_threshold(sm4_cbc_ctx->nid)) goto use_sw_method; # endif #endif if (fallback_to_openssl) goto use_sw_method; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } if (in_enc) { while ((sm4_cbc_cipher_req = mb_flist_sm4_cbc_cipher_pop(tlv->sm4_cbc_cipher_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } } else { /* decryption */ while ((sm4_cbc_cipher_req = mb_flist_sm4_cbc_cipher_pop(tlv->sm4_cbc_cipher_dec_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } } DEBUG("QAT SW SM4_CBC cipher Started %p\n", sm4_cbc_cipher_req); START_RDTSC(&sm4_cbc_cycles_cipher_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm4_cbc_cipher_req->job = job; sm4_cbc_cipher_req->sts = &sts; sm4_cbc_cipher_req->in_enc = in_enc; memmove(sm4_cbc_cipher_req->in_key, *in_key, sizeof(sm4_key)); memmove(sm4_cbc_cipher_req->in_iv, in_iv, SM4_IV_LEN); sm4_cbc_cipher_req->in_txt = in; sm4_cbc_cipher_req->in_txt_len = len; sm4_cbc_cipher_req->in_out = out; if (in_enc) { DEBUG("encryption enqueue \n"); mb_queue_sm4_cbc_cipher_enqueue(tlv->sm4_cbc_cipher_queue, sm4_cbc_cipher_req); } else { DEBUG("decryption enqueue \n"); mb_queue_sm4_cbc_cipher_enqueue(tlv->sm4_cbc_cipher_dec_queue, sm4_cbc_cipher_req); } STOP_RDTSC(&sm4_cbc_cycles_cipher_setup, 1, "[SM4_CBC:cipher_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM4_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d \n", sm4_cbc_cipher_req, sts); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) sched_yield(); } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: cipher %p status = %d\n", sm4_cbc_cipher_req, sts); num_sm4_cbc_sw_cipher_reqs++; #ifndef QAT_OPENSSL_PROVIDER return sts; #else *outl = len; return 1; #endif use_sw_method: DEBUG("SW method offload\n"); #ifdef QAT_OPENSSL_PROVIDER sw_sm4_cbc_cipher = get_default_cipher_sm4_cbc(); if (sw_sm4_cbc_cipher.cupdate == NULL) goto err; if (in != NULL) { sts = sw_sm4_cbc_cipher.cupdate(sm4_cbc_ctx->sw_ctx, out, outl, outsize, in, len); *outl = len; return 1; } else { sts = sw_sm4_cbc_cipher.cfinal(sm4_cbc_ctx->sw_ctx, out, outl, outsize); *outl = len; return 1; } DEBUG("SW Offload Finished sts=%d\n", sts); #else sw_ctx_cipher_data = sm4_cbc_ctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx))(ctx, out, in, len); # ifdef ENABLE_QAT_HW_SM4_CBC if (qat_sm4_cbc_coexist) { EVP_CIPHER_CTX_set_cipher_data(ctx, sm4cbc_hw_sw_ctx); } else { EVP_CIPHER_CTX_set_cipher_data(ctx, sm4_cbc_ctx); } # else EVP_CIPHER_CTX_set_cipher_data(ctx, sm4_cbc_ctx); # endif #endif err: return sts; } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_cbc_cleanup(void *ctx) #else int qat_sw_sm4_cbc_cleanup(EVP_CIPHER_CTX *ctx) #endif { int sts = 0; #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CBC_CTX *sm4_cbc_ctx = (QAT_PROV_CBC_CTX *)ctx; #else SM4_CBC_CTX *sm4_cbc_ctx = NULL; void *sw_ctx_cipher_data = NULL; #endif #ifdef ENABLE_QAT_HW_SM4_CBC sm4cbc_coexistence_ctx *sm4cbc_hw_sw_ctx = NULL; #endif DEBUG("Started: ctx=%p\n", ctx); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CBC_CLEANUP, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER # ifdef ENABLE_QAT_HW_SM4_CBC if (qat_sm4_cbc_coexist) { sm4cbc_hw_sw_ctx = (sm4cbc_coexistence_ctx *)(EVP_CIPHER_CTX_get_cipher_data(ctx)); sm4_cbc_ctx = &(sm4cbc_hw_sw_ctx->sm4cbc_qat_sw_ctx); } else { sm4_cbc_ctx = (SM4_CBC_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); } # else sm4_cbc_ctx = (SM4_CBC_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); # endif #endif if (sm4_cbc_ctx == NULL) { WARN("SM4-CBC CTX is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_CBC_CLEANUP, QAT_R_CIPHER_DATA_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = sm4_cbc_ctx->sw_ctx_cipher_data; if (sw_ctx_cipher_data) OPENSSL_free(sw_ctx_cipher_data); #else if (sm4_cbc_ctx->sw_ctx) OPENSSL_free(sm4_cbc_ctx->sw_ctx); #endif sts = 1; return sts; } #endif qatengine-1.9.0/qat_sw_sm4_cbc.h000066400000000000000000000102141500416242000165250ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm4_cbc.h * * This file provides an SM4 interface for an OpenSSL engine * *****************************************************************************/ #ifndef QAT_SW_SM4_CBC_H # define QAT_SW_SM4_CBC_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include /* BabaSSL includes needed for sw method */ # include /* QAT_SW SM4 methods declaration */ #ifdef ENABLE_QAT_SW_SM4_CBC #define SM4_IV_LEN 16 /* BabaSSL flags needed for sw method */ # define SM4_CBC_CUSTOM_FLAGS ( EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 ) /* Guarantee the compatibility of OPENSSL1.1 */ #ifndef ecb128_f typedef void (*ecb128_f) (const unsigned char *in, unsigned char *out, size_t len, const void *key, int enc); #endif typedef struct { sm4_key key; int8u iv[SM4_IV_LEN]; int iv_set; int enc; void *sw_ctx_cipher_data; } SM4_CBC_CTX; /* sm4 key struct from BabaSSL */ # define SM4_KEY_SCHEDULE 32 typedef struct SM4_KEY_st { uint32_t rk[SM4_KEY_SCHEDULE]; } SM4_KEY; typedef struct { union { SM4_KEY ks; } ks; block128_f block; union { ecb128_f ecb; cbc128_f cbc; ctr128_f ctr; } stream; } EVP_SM4_KEY; #ifndef QAT_OPENSSL_PROVIDER int qat_sw_sm4_cbc_key_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); int qat_sw_sm4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_sw_sm4_cbc_cleanup(EVP_CIPHER_CTX *ctx); #else int qat_sw_sm4_cbc_cipher(void *ctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t len); int qat_sw_sm4_cbc_key_init(void *ctx, const unsigned char *inkey, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_sw_sm4_cbc_cleanup(void *ctx); #endif void process_mb_sm4_cbc_key_init_reqs(mb_thread_data *tlv); void process_mb_sm4_cbc_cipher_enc_reqs(mb_thread_data *tlv); void process_mb_sm4_cbc_cipher_dec_reqs(mb_thread_data *tlv); #endif /* ENABLE_QAT_SW_SM4_CBC */ #endif /* QAT_SW_SM4_CBC_H */ qatengine-1.9.0/qat_sw_sm4_ccm.c000066400000000000000000001330251500416242000165410ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm4_ccm.c * * This file contains the engine implementation of SM4 CCM operations for * QAT SW * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include /* Local includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" #include "qat_evp.h" #include "qat_sw_request.h" #include "qat_sw_sm4_ccm.h" #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_sm4_ccm.h" #endif /* Crypto_mb includes */ #ifdef ENABLE_QAT_SW_SM4_CCM #include "crypto_mb/sm4_ccm.h" #endif #include "crypto_mb/cpu_features.h" #ifdef ENABLE_QAT_SW_SM4_CCM #ifndef QAT_OPENSSL_PROVIDER # define GET_SW_CIPHER(ctx) \ sm4_cipher_sw_impl(EVP_CIPHER_CTX_nid((ctx))) static inline const EVP_CIPHER *sm4_cipher_sw_impl(int nid) { switch (nid) { case NID_sm4_ccm: return EVP_sm4_ccm(); default: WARN("Invalid nid %d\n", nid); return NULL; } } #endif /* QAT_OPENSSL_PROVIDER */ #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER qat_get_default_cipher_sm4_ccm() { static QAT_EVP_CIPHER sm4_cipher; static int initilazed = 0; if (!initilazed) { QAT_EVP_CIPHER *cipher = (QAT_EVP_CIPHER *) EVP_CIPHER_fetch(NULL, "SM4-CCM", "provider=default"); if (cipher) { sm4_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initilazed = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return sm4_cipher; } void qat_sm4_ccm_dupctx(void *in, void *out) { QAT_PROV_CCM_CTX *inctx = (QAT_PROV_CCM_CTX *)in; PROV_CCM_CTX *outctx = (PROV_CCM_CTX *)out; outctx->tag_set = inctx->tag_set; outctx->l = inctx->L; outctx->m = inctx->M; memcpy(outctx->buf, inctx->buf, inctx->tag_len); } #endif #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_ccm_init(void *ctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc) { #else int qat_sw_sm4_ccm_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { #endif #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER sw_sm4_ccm_cipher; QAT_PROV_CCM_CTX* qctx = (QAT_PROV_CCM_CTX*)ctx; #else QAT_SM4_CCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; DEBUG("started: ctx=%p key=%p iv=%p enc=%d \n", ctx, key, iv, enc); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_INIT, QAT_R_CTX_NULL); return sts; } #ifdef QAT_OPENSSL_PROVIDER qctx->enc = enc; #else qctx = (QAT_SM4_CCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); if (qctx == NULL) { WARN("qctx is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_INIT, QAT_R_QCTX_NULL); return sts; } #endif if (iv == NULL && key == NULL) { DEBUG("iv is NULL and key is NULL \n"); return 1; } /* Allocate ccm auth tag */ if (!qctx->tag) { qctx->tag = OPENSSL_zalloc(EVP_CCM_TLS_TAG_LEN); if (qctx->tag) { qctx->tag_len = EVP_CCM_TLS_TAG_LEN; qctx->tag_set = 0; } else { qctx->tag_len = 0; WARN("Failed to allocate qctx->tag \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_INIT, QAT_R_ALLOC_TAG_FAILURE); return sts; } } /* Allocate ccm calculated_tag */ if (!qctx->calculated_tag) { qctx->calculated_tag = OPENSSL_zalloc(EVP_CCM_TLS_TAG_LEN); if (qctx->calculated_tag) { qctx->tag_calculated = 0; } else { qctx->tag_len = 0; WARN("Failed to allocate qctx->calculated_tag \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_INIT, QAT_R_ALLOC_TAG_FAILURE); return sts; } } if (qctx->iv_len <=0) { qctx->iv_len = QAT_SM4_CCM_OP_VALUE - qctx->L; DEBUG("Setting IV length = %d \n", qctx->iv_len); } /* If we have an IV passed in and have yet to allocate memory for the IV */ qctx->iv = OPENSSL_realloc(qctx->iv, qctx->iv_len); DEBUG("Reallocated IV Buffer = %p, with size %d \n", qctx->iv, qctx->iv_len); qctx->next_iv = OPENSSL_realloc(qctx->next_iv, qctx->iv_len); DEBUG("Reallocated Next_IV Buffer = %p, with size %d \n", qctx->next_iv, qctx->iv_len); if (key != NULL) { #ifndef QAT_OPENSSL_PROVIDER qctx->key_len = EVP_CIPHER_CTX_key_length(ctx); #endif if (!qctx->key) qctx->key = OPENSSL_zalloc(qctx->key_len); DEBUG("key=%p parameter for later use key_len=%lu \n", key, strlen((const char *)key)); memcpy(qctx->key, key, qctx->key_len); qctx->key_set = 1; } if (iv != NULL) { DEBUG("iv=%p parameter for later use iv_len=%lu \n", iv, strlen((const char *)iv)); if (qctx->iv) { DEBUG("Copying iv to qctx->iv with qctx->iv_len %d \n", qctx->iv_len); memcpy(qctx->iv, iv, QAT_SM4_CCM_OP_VALUE - qctx->L ); memcpy(qctx->next_iv, iv, QAT_SM4_CCM_OP_VALUE - qctx->L ); qctx->iv_set = 1; } } qctx->tls_aad_len = -1; qctx->init_flag = 0; if (ASYNC_get_current_job() != NULL) { qctx->init_flag = 1; } else { #ifdef QAT_OPENSSL_PROVIDER OSSL_PARAM params[4] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; sw_sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (enc) { if (!qctx->sw_ctx) { qctx->sw_ctx = sw_sm4_ccm_cipher.newctx(ctx); qat_sm4_ccm_dupctx(qctx, qctx->sw_ctx); } return sw_sm4_ccm_cipher.einit(qctx->sw_ctx, key, keylen, iv, ivlen, params); } else { if (!qctx->sw_ctx) { qctx->sw_ctx = sw_sm4_ccm_cipher.newctx(ctx); qat_sm4_ccm_dupctx(qctx, qctx->sw_ctx); } return sw_sm4_ccm_cipher.dinit(qctx->sw_ctx, key, keylen, iv, ivlen, params); } #else if (!qctx->sw_ctx_cipher_data) { /* cipher context init, used by sw_fallback */ sw_ctx_cipher_data = OPENSSL_zalloc(sizeof(EVP_SM4_CCM_CTX)); if (sw_ctx_cipher_data == NULL) { QATerr(QAT_F_QAT_SW_SM4_CCM_INIT, QAT_R_MALLOC_FAILURE); WARN("Unable to allocate memory for sw_ctx_cipher_data.\n"); return sts; } qctx->sw_ctx_cipher_data = sw_ctx_cipher_data; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_init(GET_SW_CIPHER(ctx))(ctx, key, iv, enc); if (sts != 1) { QATerr(QAT_F_QAT_SW_SM4_CCM_INIT, QAT_R_FALLBACK_INIT_FAILURE); WARN("Failed to init the openssl sw cipher context.\n"); } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); #endif } return 1; } #ifdef QAT_OPENSSL_PROVIDER static int qat_sw_sm4_ccm_encrypt(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) { #else static int qat_sw_sm4_ccm_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { #endif #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER sw_sm4_ccm_cipher; QAT_PROV_CCM_CTX* qctx = (QAT_PROV_CCM_CTX*)ctx; #else QAT_SM4_CCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0, job_ret = 0; ASYNC_JOB *job; sm4_ccm_encrypt_op_data *sm4_ccm_encrypt_req = NULL; mb_thread_data *tlv = NULL; static __thread int req_num = 0; int init_flag = 0; DEBUG("started: ctx=%p out=%p in=%p len=%lu \n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_ENCRYPT, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_CCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); if (qctx == NULL) { WARN("qctx is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_ENCRYPT, QAT_R_QCTX_NULL); return sts; } #endif init_flag = qctx->init_flag; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method \n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method \n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables \n"); goto use_sw_method; } while ((sm4_ccm_encrypt_req = mb_flist_sm4_ccm_encrypt_pop(tlv->sm4_ccm_encrypt_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM4_CCM encrypt Started %p \n", sm4_ccm_encrypt_req); START_RDTSC(&sm4_ccm_cycles_encrypt_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm4_ccm_encrypt_req->state = &qctx->mb_ccmctx; sm4_ccm_encrypt_req->job = job; sm4_ccm_encrypt_req->sts = &sts; sm4_ccm_encrypt_req->sm4_in = in; sm4_ccm_encrypt_req->sm4_len = len; sm4_ccm_encrypt_req->sm4_out = out; sm4_ccm_encrypt_req->sm4_key = (sm4_key *)qctx->key; sm4_ccm_encrypt_req->sm4_iv = qctx->iv; sm4_ccm_encrypt_req->sm4_ivlen = qctx->iv_len; sm4_ccm_encrypt_req->sm4_tag = qctx->tag; sm4_ccm_encrypt_req->sm4_taglen = qctx->tag_len; sm4_ccm_encrypt_req->sm4_msglen = qctx->msg_len; if (qctx->init_flag == 1) { sm4_ccm_encrypt_req->sm4_aad = qctx->tls_aad; sm4_ccm_encrypt_req->sm4_aadlen = qctx->aad_len; } sm4_ccm_encrypt_req->init_flag = init_flag; mb_queue_sm4_ccm_encrypt_enqueue(tlv->sm4_ccm_encrypt_queue, sm4_ccm_encrypt_req); STOP_RDTSC(&sm4_ccm_cycles_encrypt_setup, 1, "[SM4_CCM:encrypt_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM4_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm4ctx %p \n", sm4_ccm_encrypt_req, sts, sm4_ccm_encrypt_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) { sched_yield(); } } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); qctx->init_flag = 1; DEBUG("Finished: Encrypt %p status = %d \n", sm4_ccm_encrypt_req, sts); if (sts) { return sts; } else { WARN("Failure in SM4_CCM encrypt \n"); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx))(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("SW Encryption Finished sts=%d\n", sts); #else sw_sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (sw_sm4_ccm_cipher.cupdate == NULL) goto err; sw_sm4_ccm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); *padlen = len; return 1; #endif err: return sts; } #ifdef QAT_OPENSSL_PROVIDER static int qat_sw_sm4_ccm_decrypt(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) { #else static int qat_sw_sm4_ccm_decrypt(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { #endif #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER sw_sm4_ccm_cipher; QAT_PROV_CCM_CTX* qctx = (QAT_PROV_CCM_CTX*)ctx; #else QAT_SM4_CCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0, job_ret = 0; ASYNC_JOB *job; sm4_ccm_decrypt_op_data *sm4_ccm_decrypt_req = NULL; mb_thread_data *tlv = NULL; static __thread int req_num = 0; int init_flag = 0; DEBUG("started: ctx=%p out=%p in=%p len=%lu \n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DECRYPT, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_CCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); if (qctx == NULL) { WARN("qctx is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DECRYPT, QAT_R_QCTX_NULL); return sts; } #endif init_flag = qctx->init_flag; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables \n"); goto use_sw_method; } while ((sm4_ccm_decrypt_req = mb_flist_sm4_ccm_decrypt_pop(tlv->sm4_ccm_decrypt_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM4_CCM cipher_decrypt Started %p", sm4_ccm_decrypt_req); START_RDTSC(&sm4_ccm_cycles_decrypt_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm4_ccm_decrypt_req->state = &qctx->mb_ccmctx; sm4_ccm_decrypt_req->job = job; sm4_ccm_decrypt_req->sts = &sts; sm4_ccm_decrypt_req->sm4_in = in; sm4_ccm_decrypt_req->sm4_len = len; sm4_ccm_decrypt_req->sm4_out = out; sm4_ccm_decrypt_req->sm4_key = (sm4_key *)qctx->key; sm4_ccm_decrypt_req->sm4_iv = qctx->iv; sm4_ccm_decrypt_req->sm4_ivlen = qctx->iv_len; sm4_ccm_decrypt_req->sm4_tag = qctx->calculated_tag; sm4_ccm_decrypt_req->sm4_taglen = qctx->tag_len; sm4_ccm_decrypt_req->sm4_msglen = qctx->msg_len; if (qctx->init_flag == 1) { sm4_ccm_decrypt_req->sm4_aad = qctx->tls_aad; sm4_ccm_decrypt_req->sm4_aadlen = qctx->aad_len; } sm4_ccm_decrypt_req->init_flag = init_flag; mb_queue_sm4_ccm_decrypt_enqueue(tlv->sm4_ccm_decrypt_queue, sm4_ccm_decrypt_req); STOP_RDTSC(&sm4_ccm_cycles_decrypt_setup, 1, "[SM4_CCM:decrypt_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM4_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d \n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm4ctx %p \n", sm4_ccm_decrypt_req, sts, sm4_ccm_decrypt_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) { sched_yield(); } } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: Decrypt %p status = %d \n", sm4_ccm_decrypt_req, sts); qctx->init_flag = 1; if (sts) { return sts; } else { WARN("Failure in SM4_CCM decrypt \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DECRYPT, QAT_R_SM4_CCM_DECRYPT_FAILURE); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx))(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("SW Decryption Finished sts=%d\n", sts); #else sw_sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (sw_sm4_ccm_cipher.cupdate == NULL) goto err; sw_sm4_ccm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); *padlen = len; return 1; #endif err: return sts; } #ifdef QAT_OPENSSL_PROVIDER int QAT_SM4_CCM_CIPHER_CTX_encrypting(QAT_PROV_CCM_CTX *qctx) { return qctx->enc; } #endif #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_ccm_do_cipher(void *ctx, unsigned char* out, size_t *padlen, size_t outsize, const unsigned char* in, size_t len) #else int qat_sw_sm4_ccm_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *)ctx; QAT_EVP_CIPHER sw_sm4_ccm_cipher; #else QAT_SM4_CCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; int enc = 0; unsigned char *out_text = NULL; DEBUG("started: ctx=%p out=%p in=%p len=%lu\n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_CCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_QCTX_NULL); return sts; } #endif #ifdef QAT_OPENSSL_PROVIDER enc = QAT_SM4_CCM_CIPHER_CTX_encrypting(ctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif if (fallback_to_openssl) goto use_sw_method; if (ASYNC_get_current_job() == NULL) { DEBUG("SW Cipher Offload Started\n"); goto use_sw_method; } if (!qctx->key_set) { WARN("key_set is not set \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_KEY_NOTSET); return -1 ; } if ((in == NULL ) && (out != NULL)) { DEBUG("in is NULL while out is not NULL \n"); #ifdef QAT_OPENSSL_PROVIDER return 1; #else return sts; #endif } if (!qctx->iv_set) { WARN("iv_set is not set \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_IV_NOTSET); return -1; } if (out == NULL) { if (in == NULL) { memcpy(qctx->iv, qctx->next_iv, QAT_SM4_CCM_OP_VALUE - qctx->L); qctx->iv_len = QAT_SM4_CCM_OP_VALUE - qctx->L; qctx->msg_len = len; qctx->len_set = 1; #ifdef QAT_OPENSSL_PROVIDER *padlen = len; #endif return len; } /* If have AAD need message length */ if (!qctx->len_set && len){ WARN("Message length is not set \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_MSGLEN_NOTSET); return -1; } qctx->tls_aad = OPENSSL_zalloc(len); if (qctx->tls_aad == NULL) { WARN("Failed to allocate qctx->aad\n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_MALLOC_FAILURE); return sts; } memcpy(qctx->tls_aad, in, len); qctx->aad_len = len; #ifdef QAT_OPENSSL_PROVIDER *padlen = len; #endif return len; } /* The tag must be set before actually decrypting data */ if (!enc && !qctx->tag_set) { WARN("tag_set is not set \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_DO_CIPHER, QAT_R_TAG_NOTSET); return -1; } /* If not set length yet do it */ if (!qctx->len_set) { memcpy(qctx->iv, qctx->next_iv, QAT_SM4_CCM_OP_VALUE - qctx->L); qctx->iv_len = QAT_SM4_CCM_OP_VALUE - qctx->L; qctx->len_set = 1; } if (enc) { qctx->msg_len = len; qctx->tag_set = 1; #ifdef QAT_OPENSSL_PROVIDER sts = qat_sw_sm4_ccm_encrypt(qctx, out, padlen, outsize, in, len); #else sts = qat_sw_sm4_ccm_encrypt(ctx, out, in, len); #endif sts = 1; } else { qctx->tag_calculated = 1; out_text = OPENSSL_zalloc(len); qctx->msg_len = len; #ifdef QAT_OPENSSL_PROVIDER sts = qat_sw_sm4_ccm_decrypt(qctx, out_text, padlen, outsize, in, len); #else sts = qat_sw_sm4_ccm_decrypt(ctx, out_text, in, len); #endif memcpy(out, out_text, len); if (qctx->tag_set) { if (memcmp(qctx->calculated_tag, qctx->tag, qctx->tag_len) == 0){ DEBUG("Decrypt - CCM tag comparison success \n"); sts = 1; } else{ WARN("SM4-CCM calculated tag comparison failed \n"); DUMPL("Expected Tag:", (const unsigned char *)qctx->tag, qctx->tag_len); DUMPL("Calculated Tag:", (const unsigned char *)qctx->calculated_tag, qctx->tag_len); DUMPL("Decrypt - Calculated Tag", (const unsigned char*)qctx->calculated_tag , qctx->tag_len); #ifdef QAT_OPENSSL_PROVIDER *padlen = 0; #endif sts = -1; } } qctx->iv_set = 0; qctx->tag_set = 0; qctx->len_set = 0; qctx->msg_len = 0; } #ifdef QAT_OPENSSL_PROVIDER if(sts == 1) *padlen = len; if (sts == -1) OPENSSL_free(out_text); return 1; #else if (sts == 1) sts = len; if(sts == -1) OPENSSL_free(out_text); return sts; #endif use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(GET_SW_CIPHER(ctx))(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("SW Offload Finished sts=%d\n", sts); #else sw_sm4_ccm_cipher = qat_get_default_cipher_sm4_ccm(); if (sw_sm4_ccm_cipher.cupdate == NULL) goto err; if (in == NULL && out != NULL) { sts = sw_sm4_ccm_cipher.cfinal(qctx->sw_ctx, out, padlen, outsize); if (enc) { OSSL_PARAM params[4] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; void *ptr = OPENSSL_zalloc(EVP_CCM_TLS_TAG_LEN); params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, ptr, EVP_CCM_TLS_TAG_LEN); sw_sm4_ccm_cipher.get_ctx_params(qctx->sw_ctx, params); memcpy(qctx->tag, (char*)params->data, EVP_CCM_TLS_TAG_LEN); qctx->tag_set = 1; } *padlen = len; DEBUG("SW Offload Finished sts=%d\n", sts); return 1; } else { sw_sm4_ccm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); *padlen = len; return 1; } #endif err: return sts; } void process_mb_sm4_ccm_encrypt_reqs(mb_thread_data *tlv) { sm4_ccm_encrypt_op_data *sm4_ccm_encrypt_req_array[MULTIBUFF_SM4_BATCH] = {0}; SM4_CCM_CTX_mb16 sm4_ccm_ctx; int8u *sm4_data_out[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_in[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_len[MULTIBUFF_SM4_BATCH] = {0}; const sm4_key *sm4_data_key[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_iv[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_ivlen[MULTIBUFF_SM4_BATCH] = {0}; int64u sm4_data_msglen[MULTIBUFF_SM4_BATCH] = {0}; int8u *sm4_data_tag[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_taglen[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_aad[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_aadlen[MULTIBUFF_SM4_BATCH] = {0}; int sm4_init_flag[MULTIBUFF_SM4_BATCH] = {0}; int local_request_no = 0; int req_num = 0; unsigned int sm4_ccm_sts = 0; START_RDTSC(&sm4_ccm_cycles_encrypt_execute); /* Build Arrays of pointers for call */ while ((sm4_ccm_encrypt_req_array[req_num] = mb_queue_sm4_ccm_encrypt_dequeue(tlv->sm4_ccm_encrypt_queue)) != NULL) { sm4_init_flag[req_num] = sm4_ccm_encrypt_req_array[req_num]->init_flag; sm4_data_in[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_in; sm4_data_len[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_len; sm4_data_out[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_out; sm4_data_key[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_key; sm4_data_iv[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_iv; sm4_data_ivlen[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_ivlen; sm4_data_tag[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_tag; sm4_data_taglen[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_taglen; sm4_data_msglen[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_msglen; if (sm4_init_flag[0] == 1) { sm4_data_aad[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_aad; sm4_data_aadlen[req_num] = sm4_ccm_encrypt_req_array[req_num]->sm4_aadlen; } req_num++; if (req_num == MULTIBUFF_SM4_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting req_num %d SM4_CCM encrypt requests \n", local_request_no); START_RDTSC(&sm4_ccm_cycles_init_execute); mbx_sm4_ccm_init_mb16(sm4_data_key, sm4_data_iv, sm4_data_ivlen, sm4_data_taglen, sm4_data_msglen, &sm4_ccm_ctx); STOP_RDTSC(&sm4_ccm_cycles_init_execute, 1, "[SM4_CCM:init_execute]"); if (sm4_init_flag[0] == 1) { START_RDTSC(&sm4_ccm_cycles_update_aad_execute); mbx_sm4_ccm_update_aad_mb16(sm4_data_aad, sm4_data_aadlen, &sm4_ccm_ctx); STOP_RDTSC(&sm4_ccm_cycles_update_aad_execute, 1, "[SM4_CCM:update_aad_execute]"); } mbx_sm4_ccm_encrypt_mb16(sm4_data_out, sm4_data_in, sm4_data_len, &sm4_ccm_ctx); START_RDTSC(&sm4_ccm_cycles_get_tag_execute); sm4_ccm_sts = mbx_sm4_ccm_get_tag_mb16(sm4_data_tag, sm4_data_taglen, &sm4_ccm_ctx); STOP_RDTSC(&sm4_ccm_cycles_get_tag_execute, 1, "[SM4_CCM:get_tag_execute]"); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(sm4_ccm_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM4_CCM encrypt request[%d] success \n", req_num); *sm4_ccm_encrypt_req_array[req_num]->sts = 1; sm4_ccm_encrypt_req_array[req_num]->sm4_tag = sm4_data_tag[req_num]; } else { WARN("QAT_SW SM4 CCM encrypt request[%d] failure \n", req_num); *sm4_ccm_encrypt_req_array[req_num]->sts = 0; sm4_ccm_encrypt_req_array[req_num]->sm4_tag = sm4_data_tag[req_num]; } if (sm4_ccm_encrypt_req_array[req_num]->job) { qat_wake_job(sm4_ccm_encrypt_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm4_ccm_encrypt_req_array[req_num], sizeof(sm4_ccm_encrypt_op_data)); mb_flist_sm4_ccm_encrypt_push(tlv->sm4_ccm_encrypt_freelist, sm4_ccm_encrypt_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm4_ccm_encrypt_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm4_ccm_cycles_encrypt_execute, 1, "[SM4_CCM:encrypt_execute]"); DEBUG("Processed SM4_CCM encrypt Request \n"); } void process_mb_sm4_ccm_decrypt_reqs(mb_thread_data *tlv) { sm4_ccm_decrypt_op_data *sm4_ccm_decrypt_req_array[MULTIBUFF_SM4_BATCH] = {0}; SM4_CCM_CTX_mb16 sm4_ccm_ctx; int8u *sm4_data_out[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_in[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_len[MULTIBUFF_SM4_BATCH] = {0}; const sm4_key *sm4_data_key[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_iv[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_ivlen[MULTIBUFF_SM4_BATCH] = {0}; int8u *sm4_data_tag[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_taglen[MULTIBUFF_SM4_BATCH] = {0}; int64u sm4_data_msglen[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_aad[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_aadlen[MULTIBUFF_SM4_BATCH] = {0}; int sm4_init_flag[MULTIBUFF_SM4_BATCH] = {0}; int local_request_no = 0; int req_num = 0; unsigned int sm4_ccm_sts = 0; START_RDTSC(&sm4_ccm_cycles_decrypt_execute); /* Build Arrays of pointers for call */ while ((sm4_ccm_decrypt_req_array[req_num] = mb_queue_sm4_ccm_decrypt_dequeue(tlv->sm4_ccm_decrypt_queue)) != NULL) { sm4_init_flag[req_num] = sm4_ccm_decrypt_req_array[req_num]->init_flag; sm4_data_in[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_in; sm4_data_len[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_len; sm4_data_out[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_out; sm4_data_key[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_key; sm4_data_iv[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_iv; sm4_data_ivlen[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_ivlen; sm4_data_tag[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_tag; sm4_data_taglen[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_taglen; sm4_data_msglen[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_msglen; if (sm4_init_flag[0] == 1) { sm4_data_aad[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_aad; sm4_data_aadlen[req_num] = sm4_ccm_decrypt_req_array[req_num]->sm4_aadlen; } req_num++; if (req_num == MULTIBUFF_SM4_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting req_num %d SM4_CCM decrypt requests \n", local_request_no); mbx_sm4_ccm_init_mb16(sm4_data_key, sm4_data_iv, sm4_data_ivlen, sm4_data_taglen, sm4_data_msglen, &sm4_ccm_ctx); if (sm4_init_flag[0] == 1) { mbx_sm4_ccm_update_aad_mb16(sm4_data_aad, sm4_data_aadlen, &sm4_ccm_ctx); } mbx_sm4_ccm_decrypt_mb16(sm4_data_out, sm4_data_in, sm4_data_len, &sm4_ccm_ctx); sm4_ccm_sts = mbx_sm4_ccm_get_tag_mb16(sm4_data_tag, sm4_data_taglen, &sm4_ccm_ctx); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(sm4_ccm_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM4_CCM decrypt request[%d] success \n", req_num); *sm4_ccm_decrypt_req_array[req_num]->sts = 1; } else { WARN("QAT_SW SM4 CCM decrypt request[%d] failure \n", req_num); *sm4_ccm_decrypt_req_array[req_num]->sts = 0; } if (sm4_ccm_decrypt_req_array[req_num]->job) { qat_wake_job(sm4_ccm_decrypt_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm4_ccm_decrypt_req_array[req_num], sizeof(sm4_ccm_decrypt_op_data)); mb_flist_sm4_ccm_decrypt_push(tlv->sm4_ccm_decrypt_freelist, sm4_ccm_decrypt_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm4_ccm_decrypt_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm4_ccm_cycles_decrypt_execute, 1, "[SM4_CCM:decrypt_execute]"); DEBUG("Processed SM4_CCM decrypt Request \n"); } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_ccm_cleanup(void *ctx) #else int qat_sw_sm4_ccm_cleanup(EVP_CIPHER_CTX *ctx) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX *qctx = (QAT_PROV_CCM_CTX *)ctx; #else QAT_SM4_CCM_CTX *qctx; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; DEBUG("started: ctx=%p \n", ctx); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CLEANUP, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_CCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); if (qctx == NULL) { WARN("qctx is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CLEANUP, QAT_R_QCTX_NULL); return sts; } #endif if (qctx->iv != NULL) { DEBUG("qctx->iv_len = %d \n", qctx->iv_len); OPENSSL_free(qctx->iv); qctx->iv = NULL; qctx->iv_len = 0; qctx->iv_set = 0; qctx->msg_len = 0; } if (qctx->next_iv != NULL) { OPENSSL_free(qctx->next_iv); qctx->next_iv = NULL; } if (qctx->key != NULL) { OPENSSL_free(qctx->key); qctx->key = NULL; qctx->key_set = 0; } if (qctx->tls_aad != NULL) { #ifdef QAT_OPENSSL_PROVIDER DEBUG("qctx->tls_aad_len = %ld \n", qctx->tls_aad_len); #else DEBUG("qctx->tls_aad_len = %d \n", qctx->tls_aad_len); #endif OPENSSL_free(qctx->tls_aad); qctx->tls_aad = NULL; qctx->tls_aad_len = -1; qctx->tls_aad_set = 0; } if (qctx->tag != NULL) { DEBUG("qctx->tag_len = %d \n", qctx->tag_len); OPENSSL_free(qctx->tag); qctx->tag = NULL; qctx->tag_len = 0; qctx->tag_set = 0; } if (qctx->calculated_tag != NULL) { OPENSSL_free(qctx->calculated_tag); qctx->calculated_tag = NULL; qctx->tag_calculated = 0; } #ifdef QAT_OPENSSL_PROVIDER if (qctx->sw_ctx != NULL) { OPENSSL_free(qctx->sw_ctx); qctx->sw_ctx = NULL; } #else sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (sw_ctx_cipher_data) OPENSSL_free(sw_ctx_cipher_data); #endif qctx->iv_set = 0; qctx->tag_set = 0; qctx->len_set = 0; qctx->msg_len = 0; return 1; } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_ccm_ctrl(void *ctx, int type, int arg, void *ptr) #else int qat_sw_sm4_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_CCM_CTX* qctx = (QAT_PROV_CCM_CTX*)ctx; #else QAT_SM4_CCM_CTX *qctx; void *sw_ctx_cipher_data = NULL; #endif int ret_val = 0; int enc = 0; DEBUG("started: ctx=%p type=%x arg=%d ptr=%p \n", ctx, type, arg, ptr); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_CTX_NULL); return -1; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_CCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); if (qctx == NULL) { WARN("qctx cannot be NULL \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_QCTX_NULL); return -1; } if (ASYNC_get_current_job() == NULL ) { DEBUG("Inside ASYNC in CTRL \n"); if( type == EVP_CTRL_INIT ){ qctx->tls_aad_len = -1; qctx->L = QAT_SM4_CCM_L_VALUE; qctx->M = QAT_SM4_CCM_M_VALUE; qctx->iv_set = 0; qctx->len_set = 0; qctx->tag_set = 0; qctx->msg_len = 0; qctx->iv_len = 0; } if (!qctx->sw_ctx_cipher_data) { /* cipher context init, used by sw_fallback */ sw_ctx_cipher_data = OPENSSL_zalloc(sizeof(EVP_SM4_CCM_CTX)); if (sw_ctx_cipher_data == NULL) { QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_MALLOC_FAILURE); WARN("Unable to allocate memory for sw_ctx_cipher_data.\n"); return ret_val; } qctx->sw_ctx_cipher_data = sw_ctx_cipher_data; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_ctrl(GET_SW_CIPHER(ctx))(ctx, type, arg, ptr); if (ret_val != 1) { QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_FALLBACK_INIT_FAILURE); WARN("Failed to init the openssl sw cipher context.\n"); return ret_val; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); return ret_val; } #endif #ifdef QAT_OPENSSL_PROVIDER enc = qctx->enc; #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif switch (type) { case EVP_CTRL_INIT: qctx->tls_aad_len = -1; qctx->L = QAT_SM4_CCM_L_VALUE; qctx->M = QAT_SM4_CCM_M_VALUE; qctx->iv_set = 0; qctx->len_set = 0; qctx->tag_set = 0; qctx->msg_len = 0; qctx->iv_len = 0; ret_val = 1; break; case EVP_CTRL_GET_IVLEN: DEBUG("CTRL Type = EVP_CTRL_GET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p \n", (void*)ctx, type, arg, ptr); *(int*)ptr = QAT_SM4_CCM_OP_VALUE - qctx->L; qctx->iv_len = QAT_SM4_CCM_OP_VALUE - qctx->L; ret_val = 1; break; case EVP_CTRL_AEAD_TLS1_AAD: DEBUG("CTRL Type = EVP_CTRL_AEAD_TLS1_AAD, ctx = %p, type = %d," " arg = %d, ptr = %p \n", (void*)ctx, type, arg, ptr); if (arg != EVP_AEAD_TLS1_AAD_LEN) { WARN("AAD Length not valid %d \n", arg); ret_val = 0; break; } /* Check to see if tls_aad already allocated with correct size, * if so, reuse and save ourselves a free and malloc */ if ((qctx->tls_aad_len == EVP_AEAD_TLS1_AAD_LEN) && qctx->tls_aad){ memcpy(qctx->tls_aad, ptr, arg); } else { if (qctx->tls_aad) { OPENSSL_free(qctx->tls_aad); qctx->tls_aad_len = -1; qctx->tls_aad_set = 0; } qctx->tls_aad_len = EVP_AEAD_TLS1_AAD_LEN; qctx->tls_aad = OPENSSL_malloc(qctx->tls_aad_len); if (qctx->tls_aad) { /* Copy the header from payload into the buffer */ memcpy(qctx->tls_aad, ptr, qctx->tls_aad_len); } else { WARN("AAD alloc failed \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_MALLOC_FAILURE); ret_val = 0; break; } } /* Extract the length of the payload from the TLS header */ unsigned int plen = qctx->tls_aad[arg - QAT_SM4_TLS_PAYLOADLENGTH_MSB_OFFSET] << QAT_BYTE_SHIFT | qctx->tls_aad[arg - QAT_SM4_TLS_PAYLOADLENGTH_LSB_OFFSET]; /* Correct length for explicit IV */ if (plen < EVP_CCM_TLS_EXPLICIT_IV_LEN) return 0; /* The payload contains the explicit IV -> correct the length */ plen -= EVP_CCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!enc) { if (plen < qctx->M) return 0; plen -= qctx->M; } /* Fix the length like in the SW version of SM4 */ qctx->tls_aad[EVP_AEAD_TLS1_AAD_LEN - QAT_SM4_TLS_PAYLOADLENGTH_MSB_OFFSET] = plen >> QAT_BYTE_SHIFT; qctx->tls_aad[EVP_AEAD_TLS1_AAD_LEN - QAT_SM4_TLS_PAYLOADLENGTH_LSB_OFFSET] = plen & 0xff; qctx->tls_aad_set = 1; ret_val = qctx->M; break; case EVP_CTRL_AEAD_SET_IVLEN: DEBUG("CTRL Type = EVP_CTRL_AEAD_SET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p \n", (void*)ctx, type, arg, ptr); if (arg <= 0) { WARN("Invalid IV length provided\n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } arg = QAT_SM4_CCM_OP_VALUE - arg; /* fall thru */ case EVP_CTRL_CCM_SET_L: DEBUG("CTRL Type = EVP_CTRL_CCM_SET_L, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if(arg < 2 || arg > 8) { WARN("L value is out of expected range, L = %d\n", arg); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_INVALID_L); ret_val = 0; break; } qctx->L = arg; ret_val = 1; break; case EVP_CTRL_CCM_SET_IV_FIXED: DEBUG("CTRL Type = EVP_CTRL_CCM_SET_IV_FIXED, ctx = %p, type = %d," " arg = %d, ptr = %p \n", (void*)ctx, type, arg, ptr); if (arg != EVP_CCM_TLS_FIXED_IV_LEN) { WARN("IV length is not currently supported, iv_len = %d \n", arg); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } if (!qctx->iv) { qctx->iv = OPENSSL_zalloc(arg); if (qctx->iv == NULL) { WARN("Failed to allocate %d bytes \n", arg); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_IV_ALLOC_FAILURE); qctx->iv_len = 0; ret_val = 0; break; } else { qctx->iv_len = arg; } } if (arg) { memcpy(qctx->iv, ptr, arg); } ret_val = 1; break; case EVP_CTRL_AEAD_SET_TAG: DEBUG("CTRL Type = EVP_CTRL_AEAD_SET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p , enc =%d \n", (void*)ctx, type, arg, ptr, enc); DUMPL(" EVP_CTRL_AEAD_SET_TAG ptr:", (void *)ptr, arg); if ((arg & 1) || arg <= 4 || arg > QAT_SM4_TAG_MAX_LEN) { WARN("Bad input parameters \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_BAD_INPUT_PARAMS); ret_val = 0; break; } if (enc && ptr) { WARN("Bad input parameters \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_BAD_INPUT_PARAMS); ret_val = 0; break; } if (qctx->tag) { OPENSSL_free(qctx->tag); qctx->tag = NULL; } if (ptr) { qctx->tag = OPENSSL_zalloc(arg); if (qctx->tag) { memcpy(qctx->tag, ptr, arg); qctx->tag_set = 1; qctx->tag_len = arg; DUMPL(" EVP_CTRL_AEAD_SET_TAG Tag:", (const unsigned char *)qctx->tag, qctx->tag_len); } else { WARN("Tag alloc failure \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_ALLOC_TAG_FAILURE); } } qctx->M = arg; ret_val = 1; break; case EVP_CTRL_AEAD_GET_TAG: DEBUG("CTRL Type = EVP_CTRL_AEAD_GET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p, enc = %d \n", (void*)ctx, type, arg, ptr, enc); if ( !enc || ( ptr == NULL )) { WARN("Bad input parameters \n"); QATerr(QAT_F_QAT_SW_SM4_CCM_CTRL, QAT_R_INVALID_TAG_LEN); ret_val = 0; break; } if (!qctx->tag_set ) { WARN("Tag not set \n"); ret_val = 0; break; } memcpy(ptr, qctx->tag, arg); DEBUG("CTRL Type = EVP_CTRL_AEAD_GET_TAG, the tag is = %p \n", qctx->tag); qctx->iv_set = 0; qctx->len_set = 0; qctx->tag_set = 0; qctx->msg_len = 0; qctx->iv_len = 0; ret_val = 1; break; default: WARN("Invalid type %d \n", type); ret_val = -1; break; } return ret_val; } #endif qatengine-1.9.0/qat_sw_sm4_ccm.h000066400000000000000000000131721500416242000165460ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm4_ccm.h * * This file provides an SM4 CCM interfaces for an OpenSSL engine * *****************************************************************************/ #ifndef QAT_SW_SM4_CCM_H # define QAT_SW_SM4_CCM_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include # include # ifdef ENABLE_QAT_SW_SM4_CCM #define QAT_BYTE_SHIFT 8 #define QAT_SM4_TAG_MIN_LEN 0 #define QAT_SM4_TAG_MAX_LEN 16 #define QAT_SM4_TLS_PAYLOADLENGTH_MSB_OFFSET 2 #define QAT_SM4_TLS_PAYLOADLENGTH_LSB_OFFSET 1 #define QAT_SM4_CCM_M_VALUE 12 #define QAT_SM4_CCM_L_VALUE 8 #define QAT_SM4_CCM_OP_VALUE 15 #define SM4_KEY_SCHEDULE 32 /* babassl flags needed for sw method */ #define CUSTOM_CCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_AEAD_CIPHER \ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CUSTOM_IV_LENGTH \ | EVP_CIPH_CCM_MODE) typedef struct { SM4_CCM_CTX_mb16 mb_ccmctx; int init_flag; unsigned char* key; int key_len; int key_set; /* Set if key initialized */ unsigned char* tls_aad; int aad_len; int tls_aad_len; /* TLS AAD length */ unsigned int tls_aad_set; unsigned char* tag; unsigned char* calculated_tag; int tag_len; unsigned int tag_set; unsigned int tag_calculated; unsigned char* iv; unsigned char* next_iv; int iv_len; unsigned int iv_set; int msg_len; /* Message Length */ int len_set; /* Set if message length set */ int L, M; /* L and M parameters from RFC3610 */ void* sw_ctx_cipher_data; } QAT_SM4_CCM_CTX; typedef unsigned char u8; typedef unsigned long long u64; typedef struct SM4_CCM_KEY_st { uint32_t rk[SM4_KEY_SCHEDULE]; } SM4_CCM_KEY; struct ccm128_context { union { u64 u[2]; u8 c[16]; } nonce, cmac; u64 blocks; block128_f block; void *key; }; typedef struct ccm128_context CCM128_CONTEXT; typedef struct { SM4_CCM_KEY ks; /* SM4 key schedule to use */ int key_set; /* Set if key initialized */ int iv_set; /* Set if an iv is set */ int tag_set; /* Set if tag is valid */ int len_set; /* Set if message length set */ int L, M; /* L and M parameters from RFC3610 */ int tls_aad_len; /* TLS AAD length */ CCM128_CONTEXT ccm; ccm128_f str; } EVP_SM4_CCM_CTX; # ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_ccm_init(void *ctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_sw_sm4_ccm_ctrl(void *ctx, int type, int p1, void *p2); int qat_sw_sm4_ccm_do_cipher(void *ctx, unsigned char* out, size_t *padlen, size_t outsize, const unsigned char* in, size_t len); int qat_sw_sm4_ccm_cleanup(void *ctx); # else int qat_sw_sm4_ccm_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); int qat_sw_sm4_ccm_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void *p2); int qat_sw_sm4_ccm_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_sw_sm4_ccm_cleanup(EVP_CIPHER_CTX *ctx); # endif /* QAT_OPENSSL_PROVIDER */ void process_mb_sm4_ccm_encrypt_reqs(mb_thread_data *tlv); void process_mb_sm4_ccm_decrypt_reqs(mb_thread_data *tlv); # endif /* ENABLE_QAT_SW_SM4_CCM */ #endif /* QAT_SW_SM4_H */ qatengine-1.9.0/qat_sw_sm4_gcm.c000066400000000000000000001420531500416242000165460ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm4_gcm.c * * This file contains the engine implementation for SM4 GCM operations * *****************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #define __USE_GNU #include #include #include #include #include #include /* Local includes */ #include "e_qat.h" #include "qat_utils.h" #include "qat_events.h" #include "qat_fork.h" #include "qat_evp.h" #include "qat_sw_request.h" #include "qat_sw_sm4_gcm.h" #ifdef QAT_OPENSSL_PROVIDER # include "qat_prov_sm4_gcm.h" #endif /* Crypto_mb includes */ #ifdef ENABLE_QAT_SW_SM4_GCM #include "crypto_mb/sm4_gcm.h" #endif #include "crypto_mb/cpu_features.h" #ifdef ENABLE_QAT_SW_SM4_GCM # ifdef QAT_OPENSSL_PROVIDER int QAT_SM4_CIPHER_CTX_encrypting(QAT_PROV_GCM_CTX *qctx) { return qctx->enc; } QAT_EVP_CIPHER_SM4_GCM get_default_cipher_sm4_gcm() { static QAT_EVP_CIPHER_SM4_GCM sm4_cipher; static int initilazed = 0; if (!initilazed) { QAT_EVP_CIPHER_SM4_GCM *cipher = (QAT_EVP_CIPHER_SM4_GCM *)EVP_CIPHER_fetch(NULL, "SM4-GCM", "provider=default"); if (cipher) { sm4_cipher = *cipher; EVP_CIPHER_free((EVP_CIPHER *)cipher); initilazed = 1; } else { WARN("EVP_CIPHER_fetch from default provider failed"); } } return sm4_cipher; } # endif void process_mb_sm4_gcm_decrypt_reqs(mb_thread_data *tlv) { sm4_gcm_decrypt_op_data *sm4_gcm_decrypt_req_array[MULTIBUFF_SM4_BATCH] = {0}; SM4_GCM_CTX_mb16 sm4_gcm_ctx; int8u *sm4_data_out[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_in[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_len[MULTIBUFF_SM4_BATCH] = {0}; const sm4_key *sm4_data_key[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_iv[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_ivlen[MULTIBUFF_SM4_BATCH] = {0}; int8u *sm4_data_tag[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_taglen[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_aad[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_aadlen[MULTIBUFF_SM4_BATCH] = {0}; int sm4_init_flag[MULTIBUFF_SM4_BATCH] = {0}; int local_request_no = 0; int req_num = 0; unsigned int sm4_gcm_sts = 0; START_RDTSC(&sm4_gcm_cycles_decrypt_execute); /* Build Arrays of pointers for call */ while ((sm4_gcm_decrypt_req_array[req_num] = mb_queue_sm4_gcm_decrypt_dequeue(tlv->sm4_gcm_decrypt_queue)) != NULL) { sm4_init_flag[req_num] = sm4_gcm_decrypt_req_array[req_num]->init_flag; sm4_data_in[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_in; sm4_data_len[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_len; sm4_data_out[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_out; sm4_data_key[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_key; sm4_data_iv[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_iv; sm4_data_ivlen[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_ivlen; sm4_data_tag[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_tag; sm4_data_taglen[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_taglen; if (sm4_init_flag[0] == 1) { sm4_data_aad[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_aad; sm4_data_aadlen[req_num] = sm4_gcm_decrypt_req_array[req_num]->sm4_aadlen; } req_num++; if (req_num == MULTIBUFF_SM4_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting req_num %d SM4_GCM decrypt requests\n", local_request_no); mbx_sm4_gcm_init_mb16(sm4_data_key, sm4_data_iv, sm4_data_ivlen, &sm4_gcm_ctx); if (sm4_init_flag[0] == 1) { mbx_sm4_gcm_update_aad_mb16(sm4_data_aad, sm4_data_aadlen, &sm4_gcm_ctx); } mbx_sm4_gcm_decrypt_mb16(sm4_data_out, sm4_data_in, sm4_data_len, &sm4_gcm_ctx); sm4_gcm_sts = mbx_sm4_gcm_get_tag_mb16(sm4_data_tag, sm4_data_taglen, &sm4_gcm_ctx); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(sm4_gcm_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM4_GCM decrypt request[%d] success\n", req_num); *sm4_gcm_decrypt_req_array[req_num]->sts = 1; } else { WARN("QAT_SW SM4 GCM decrypt request[%d] failure\n", req_num); *sm4_gcm_decrypt_req_array[req_num]->sts = 0; } if (sm4_gcm_decrypt_req_array[req_num]->job) { qat_wake_job(sm4_gcm_decrypt_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm4_gcm_decrypt_req_array[req_num], sizeof(sm4_gcm_decrypt_op_data)); mb_flist_sm4_gcm_decrypt_push(tlv->sm4_gcm_decrypt_freelist, sm4_gcm_decrypt_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm4_gcm_decrypt_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm4_gcm_cycles_decrypt_execute, 1, "[SM4_GCM:decrypt_execute]"); DEBUG("Processed SM4_GCM decrypt Request\n"); } void process_mb_sm4_gcm_encrypt_reqs(mb_thread_data *tlv) { sm4_gcm_encrypt_op_data *sm4_gcm_encrypt_req_array[MULTIBUFF_SM4_BATCH] = {0}; SM4_GCM_CTX_mb16 sm4_gcm_ctx; int8u *sm4_data_out[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_in[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_len[MULTIBUFF_SM4_BATCH] = {0}; const sm4_key *sm4_data_key[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_iv[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_ivlen[MULTIBUFF_SM4_BATCH] = {0}; int8u *sm4_data_tag[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_taglen[MULTIBUFF_SM4_BATCH] = {0}; const int8u *sm4_data_aad[MULTIBUFF_SM4_BATCH] = {0}; int sm4_data_aadlen[MULTIBUFF_SM4_BATCH] = {0}; int sm4_init_flag[MULTIBUFF_SM4_BATCH] = {0}; int local_request_no = 0; int req_num = 0; unsigned int sm4_gcm_sts = 0; START_RDTSC(&sm4_gcm_cycles_encrypt_execute); /* Build Arrays of pointers for call */ while ((sm4_gcm_encrypt_req_array[req_num] = mb_queue_sm4_gcm_encrypt_dequeue(tlv->sm4_gcm_encrypt_queue)) != NULL) { sm4_init_flag[req_num] = sm4_gcm_encrypt_req_array[req_num]->init_flag; sm4_data_in[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_in; sm4_data_len[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_len; sm4_data_out[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_out; sm4_data_key[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_key; sm4_data_iv[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_iv; sm4_data_ivlen[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_ivlen; sm4_data_tag[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_tag; sm4_data_taglen[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_taglen; if (sm4_init_flag[0] == 1) { sm4_data_aad[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_aad; sm4_data_aadlen[req_num] = sm4_gcm_encrypt_req_array[req_num]->sm4_aadlen; } req_num++; if (req_num == MULTIBUFF_SM4_MIN_BATCH) break; } local_request_no = req_num; DEBUG("Submitting req_num %d SM4_GCM encrypt requests\n", local_request_no); mbx_sm4_gcm_init_mb16(sm4_data_key, sm4_data_iv, sm4_data_ivlen, &sm4_gcm_ctx); if (sm4_init_flag[0] == 1) { mbx_sm4_gcm_update_aad_mb16(sm4_data_aad, sm4_data_aadlen, &sm4_gcm_ctx); } mbx_sm4_gcm_encrypt_mb16(sm4_data_out, sm4_data_in, sm4_data_len, &sm4_gcm_ctx); sm4_gcm_sts = mbx_sm4_gcm_get_tag_mb16(sm4_data_tag, sm4_data_taglen, &sm4_gcm_ctx); for (req_num = 0; req_num < local_request_no; req_num++) { if (MBX_GET_STS(sm4_gcm_sts, req_num) == MBX_STATUS_OK) { DEBUG("QAT_SW SM4_GCM encrypt request[%d] success\n", req_num); *sm4_gcm_encrypt_req_array[req_num]->sts = 1; } else { WARN("QAT_SW SM4 GCM encrypt request[%d] failure\n", req_num); *sm4_gcm_encrypt_req_array[req_num]->sts = 0; } if (sm4_gcm_encrypt_req_array[req_num]->job) { qat_wake_job(sm4_gcm_encrypt_req_array[req_num]->job, ASYNC_STATUS_OK); } OPENSSL_cleanse(sm4_gcm_encrypt_req_array[req_num], sizeof(sm4_gcm_encrypt_op_data)); mb_flist_sm4_gcm_encrypt_push(tlv->sm4_gcm_encrypt_freelist, sm4_gcm_encrypt_req_array[req_num]); } # ifdef QAT_SW_HEURISTIC_TIMEOUT mb_sm4_gcm_encrypt_req_rates.req_this_period += local_request_no; # endif STOP_RDTSC(&sm4_gcm_cycles_encrypt_execute, 1, "[SM4_GCM:encrypt_execute]"); DEBUG("Processed SM4_GCM encrypt Request\n"); } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_gcm_init(void *ctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc) #else int qat_sw_sm4_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_GCM sw_sm4_gcm_cipher; QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; #else QAT_SM4_GCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; DEBUG("started: ctx=%p key=%p iv=%p enc=%d\n", ctx, key, iv, enc); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_CTX_NULL); return sts; } #ifdef QAT_OPENSSL_PROVIDER qctx->enc = enc; #else qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_QCTX_NULL); return sts; } /* If a key is set and a tag has already been calculated * this cipher ctx is being reused, so zero the gcm ctx and tag state variables */ if (qctx->key_set && qctx->tag_calculated) { qctx->tag_set = 0; qctx->tag_calculated = 0; } /* Allocate gcm auth tag */ if (!qctx->tag) { qctx->tag = OPENSSL_zalloc(EVP_GCM_TLS_TAG_LEN); if (qctx->tag) { qctx->tag_len = EVP_GCM_TLS_TAG_LEN; qctx->tag_set = 0; } else { qctx->tag_len = 0; WARN("Failed to allocate qctx->tag\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_ALLOC_TAG_FAILURE); return 0; } } /* Allocate gcm calculated_tag */ if (!qctx->calculated_tag) { qctx->calculated_tag = OPENSSL_zalloc(EVP_GCM_TLS_TAG_LEN); if (qctx->calculated_tag) { qctx->tag_calculated = 0; } else { qctx->tag_len = 0; WARN("Failed to allocate qctx->calculated_tag\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_ALLOC_TAG_FAILURE); return 0; } } /* If we have an IV passed in, and the iv_len has not yet been set * default to QAT_SM4_TLS_TOTAL_IV_LEN (if IV size isn't 12 bytes, * it would have been set via ctrl function before we got here) */ if (qctx->iv_len <=0) { qctx->iv_len = QAT_SM4_TLS_TOTAL_IV_LEN; DEBUG("Setting IV length = %d\n", qctx->iv_len); } /* If we have an IV passed in and have yet to allocate memory for the IV */ qctx->iv = OPENSSL_realloc(qctx->iv, qctx->iv_len); DEBUG("Reallocated IV Buffer = %p, with size %d\n", qctx->iv, qctx->iv_len); qctx->next_iv = OPENSSL_realloc(qctx->next_iv, qctx->iv_len); DEBUG("Reallocated Next_IV Buffer = %p, with size %d\n", qctx->next_iv, qctx->iv_len); if (iv != NULL) { DEBUG("iv=%p parameter for later use iv_len=%lu\n", iv, strlen((const char *)iv)); if (qctx->iv) { DEBUG("Copying iv to qctx->iv with qctx->iv_len %d\n", qctx->iv_len); memcpy(qctx->iv, iv, qctx->iv_len); memcpy(qctx->next_iv, iv, qctx->iv_len); qctx->iv_set = 1; } qctx->iv_gen = 0; } else { WARN("iv is NULL\n"); } if (key) { #ifndef QAT_OPENSSL_PROVIDER qctx->key_len = EVP_CIPHER_CTX_key_length(ctx); #endif if (!qctx->key) { qctx->key = OPENSSL_zalloc(qctx->key_len); if (qctx->key == NULL) { QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_QCTX_NULL); return sts; } } DEBUG("key=%p parameter for later use key_len=%lu\n", key, strlen((const char *)key)); memcpy(qctx->key, key, qctx->key_len); qctx->key_set = 1; } else { WARN("key is NULL\n"); } qctx->tls_aad_len = -1; qctx->init_flag = 0; if (ASYNC_get_current_job() != NULL) { qctx->init_flag = 1; } else { #ifdef QAT_OPENSSL_PROVIDER OSSL_PARAM params[4] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; sw_sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (enc) { if (!qctx->sw_ctx) qctx->sw_ctx = sw_sm4_gcm_cipher.newctx(ctx); return sw_sm4_gcm_cipher.einit(qctx->sw_ctx, key, keylen, iv, ivlen, params); } else { if (!qctx->sw_ctx) qctx->sw_ctx = sw_sm4_gcm_cipher.newctx(ctx); return sw_sm4_gcm_cipher.dinit(qctx->sw_ctx, key, keylen, iv, ivlen, params); } #else if (!qctx->sw_ctx_cipher_data) { /* cipher context init, used by sw_fallback */ sw_ctx_cipher_data = OPENSSL_zalloc(sizeof(EVP_SM4_GCM_CTX)); if (sw_ctx_cipher_data == NULL) { QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_MALLOC_FAILURE); WARN("Unable to allocate memory for sw_ctx_cipher_data.\n"); return sts; } qctx->sw_ctx_cipher_data = sw_ctx_cipher_data; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_init(EVP_sm4_gcm())(ctx, key, iv, enc); if (sts != 1) { QATerr(QAT_F_QAT_SW_SM4_GCM_INIT, QAT_R_FALLBACK_INIT_FAILURE); WARN("Failed to init the openssl sw cipher context.\n"); return sts; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); #endif } return 1; } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_gcm_cleanup(void *ctx) #else int qat_sw_sm4_gcm_cleanup(EVP_CIPHER_CTX *ctx) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; #else QAT_SM4_GCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; DEBUG("qat_sw_sm4_gcm_cleanup started: ctx=%p\n", ctx); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CLEANUP, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (qctx) { if (qctx->iv != NULL) { DEBUG("qctx->iv_len = %d\n", qctx->iv_len); OPENSSL_free(qctx->iv); qctx->iv = NULL; qctx->iv_len = 0; qctx->iv_set = 0; } if (qctx->next_iv != NULL) { OPENSSL_free(qctx->next_iv); qctx->next_iv = NULL; } if (qctx->key != NULL) { OPENSSL_free(qctx->key); qctx->key = NULL; qctx->key_set = 0; } if (qctx->tls_aad != NULL) { DEBUG("qctx->tls_aad_len = %d\n", qctx->tls_aad_len); OPENSSL_free(qctx->tls_aad); qctx->tls_aad = NULL; qctx->tls_aad_len = -1; qctx->tls_aad_set = 0; } if (qctx->tag != NULL) { DEBUG("qctx->tag_len = %d\n", qctx->tag_len); OPENSSL_free(qctx->tag); qctx->tag = NULL; qctx->tag_len = 0; qctx->tag_set = 0; } if (qctx->calculated_tag != NULL) { OPENSSL_free(qctx->calculated_tag); qctx->calculated_tag = NULL; qctx->tag_calculated = 0; } #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (sw_ctx_cipher_data) OPENSSL_free(sw_ctx_cipher_data); #endif } return 1; } static inline void sm4_gcm_increment_counter(unsigned char* ifc) { int inv_field_size = 8; unsigned char byte = 0; /* Loop over ifc starting with the least significant byte * and work towards the most significant byte of ifc*/ do { --inv_field_size; byte = ifc[inv_field_size]; /* Increment by one and copy back to invocation field */ ++byte; ifc[inv_field_size] = byte; if (byte) return; } while (inv_field_size); } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_gcm_ctrl(void *ctx, int type, int arg, void *ptr) #else int qat_sw_sm4_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; #else QAT_SM4_GCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int ret_val = 0; int enc = 0; DEBUG("qat_sw_sm4_gcm_ctrl started: ctx=%p type=%x arg=%d ptr=%p\n", ctx, type, arg, ptr); if (ctx == NULL) { WARN("ctx == NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_CTX_NULL); return -1; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (unlikely(qctx == NULL)) { WARN("qctx cannot be NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_QCTX_NULL); return -1; } #ifndef QAT_OPENSSL_PROVIDER if (ASYNC_get_current_job() == NULL) { if (!qctx->sw_ctx_cipher_data) { /* cipher context init, used by sw_fallback */ sw_ctx_cipher_data = OPENSSL_zalloc(sizeof(EVP_SM4_GCM_CTX)); if (sw_ctx_cipher_data == NULL) { QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_MALLOC_FAILURE); WARN("Unable to allocate memory for sw_ctx_cipher_data.\n"); return 0; } qctx->sw_ctx_cipher_data = sw_ctx_cipher_data; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx->sw_ctx_cipher_data); ret_val = EVP_CIPHER_meth_get_ctrl(EVP_sm4_gcm())(ctx, type, arg, ptr); if (ret_val != 1) { QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_FALLBACK_INIT_FAILURE); WARN("Failed to init the openssl sw cipher context.\n"); return ret_val; } EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); return ret_val; } #endif #ifdef QAT_OPENSSL_PROVIDER enc = QAT_SM4_CIPHER_CTX_encrypting(qctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif switch (type) { case EVP_CTRL_INIT: DEBUG("CTRL Type = EVP_CTRL_INIT, ctx = %p, type = %d, " "arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); qctx->tls_aad_len = -1; qctx->iv_gen = -1; ret_val = 1; break; case EVP_CTRL_AEAD_SET_IVLEN: DEBUG("CTRL Type = EVP_CTRL_GCM_SET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (arg <= 0) { WARN("Invalid IV length provided\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } qctx->iv_len = arg; qctx->iv_set = 0; ret_val = 1; break; case EVP_CTRL_AEAD_SET_TAG: DEBUG("CTRL Type = EVP_CTRL_AEAD_SET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (enc || arg <= QAT_SM4_TAG_MIN_LEN || arg > QAT_SM4_TAG_MAX_LEN) { ret_val = 0; WARN("Bad input parameters\n"); break; } if (qctx->tag) { OPENSSL_free(qctx->tag); qctx->tag = NULL; } qctx->tag = OPENSSL_zalloc(arg); if (qctx->tag) { memcpy(qctx->tag, ptr, arg); qctx->tag_len = arg; qctx->tag_set = 1; ret_val = 1; } else { WARN("Tag alloc failure\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_ALLOC_TAG_FAILURE); ret_val = 0; } break; case EVP_CTRL_AEAD_GET_TAG: DEBUG("CTRL Type = EVP_CTRL_AEAD_GET_TAG, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (!enc || arg <= QAT_SM4_TAG_MIN_LEN || arg > QAT_SM4_TAG_MAX_LEN || qctx->tag_len <= 0) { WARN("Bad input parameters\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_TAG_LEN); ret_val = 0; break; } if (!qctx->tag_set || (ptr == NULL)) { WARN("Tag not set\n"); ret_val = 0; break; } else memcpy(ptr, qctx->tag, arg); qctx->iv_set = 0; qctx->tag_calculated = 0; qctx->tag_set = 0; ret_val = 1; break; case EVP_CTRL_GCM_SET_IV_FIXED: DEBUG("CTRL Type = EVP_CTRL_GCM_SET_IV_FIXED, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (ptr == NULL || qctx->next_iv == NULL) { WARN("ptr || next_iv == NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_PTR_IV); ret_val = 0; break; } /* Special case: -1 length restores whole IV */ if (arg == -1) { DEBUG("Special case - Restoring IV, arg = %d\n", arg); memcpy(qctx->next_iv, ptr, qctx->iv_len); qctx->iv_gen = 1; ret_val = 1; break; } /* Fixed field must be at least 4 bytes (EVP_GCM_TLS_FIXED_IV_LEN) * and invocation field at least 8 (EVP_GCM_TLS_EXPLICIT_IV_LEN) */ if ((arg < EVP_GCM_TLS_FIXED_IV_LEN) || (qctx->iv_len - arg) < EVP_GCM_TLS_EXPLICIT_IV_LEN) { WARN("Length is not valid\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } if (arg != EVP_GCM_TLS_FIXED_IV_LEN) { WARN("IV length is not currently supported, iv_len = %d\n", arg); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_IVLEN); ret_val = 0; break; } int iv_len = EVP_GCM_TLS_FIXED_IV_LEN; if (!qctx->iv) { qctx->next_iv = OPENSSL_zalloc(iv_len); if (qctx->iv == NULL) { WARN("Failed to allocate %d bytes\n", arg); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_IV_ALLOC_FAILURE); qctx->iv_len = 0; qctx->iv_gen = 0; ret_val = 0; break; } else qctx->iv_len = iv_len; } if (arg) { memcpy(qctx->next_iv, ptr, arg); } /* Generate the explicit part of the IV for encryption */ if (enc && RAND_bytes(qctx->next_iv + arg, qctx->iv_len - arg) <= 0) { WARN("RAND_Bytes Failed to generate explicit IV\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_RAND_BYTES_FAILURE); ret_val = 0; break; } qctx->iv_gen = 1; ret_val = 1; break; case EVP_CTRL_GCM_IV_GEN: DEBUG("CTRL Type = EVP_CTRL_GCM_IV_GEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (NULL == qctx->iv || NULL == qctx->next_iv || NULL == ptr) { WARN("Invalid memory ptr\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_QCTX_MEMORY); ret_val = 0; break; } if (0 == qctx->iv_gen || qctx->key_set == 0) { WARN("Operation not valid\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_QCTX_MEMORY); ret_val = 0; break; } /* Set the IV that will be used in the current operation */ memcpy(qctx->iv, qctx->next_iv, qctx->iv_len); if (arg <= 0 || arg > qctx->iv_len) { arg = qctx->iv_len; } /* Copy the explicit IV in the output buffer */ memcpy(ptr, qctx->next_iv + qctx->iv_len - arg, arg); /* Increment invocation field counter (last 8 bytes of IV) */ sm4_gcm_increment_counter(qctx->next_iv + qctx->iv_len - 8); qctx->iv_set = 1; ret_val = 1; break; case EVP_CTRL_GCM_SET_IV_INV: /* Called in TLS case before decryption */ DEBUG("CTRL Type = EVP_CTRL_GCM_SET_IV_INV, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (0 == qctx->iv_gen || enc) { WARN("Operation not valid\n"); ret_val = 0; break; } if (NULL == qctx->iv || NULL == qctx->next_iv || NULL == ptr) { WARN("Memory Pointer not valid\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_QCTX_MEMORY); ret_val = 0; break; } /* Retrieve the explicit IV from the message buffer */ memcpy(qctx->next_iv + qctx->iv_len - arg, ptr, arg); /* Set the IV that will be used in the current operation */ memcpy(qctx->iv, qctx->next_iv, qctx->iv_len); qctx->iv_set = 1; ret_val = 1; break; case EVP_CTRL_AEAD_TLS1_AAD: DEBUG("CTRL Type = EVP_CTRL_AEAD_TLS1_AAD, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); if (arg != EVP_AEAD_TLS1_AAD_LEN) { WARN("AAD Length not valid %d\n", arg); ret_val = 0; break; } /* Check to see if tls_aad already allocated with correct size, * if so, reuse and save ourselves a free and malloc */ if ((qctx->tls_aad_len == EVP_AEAD_TLS1_AAD_LEN) && qctx->tls_aad) memcpy(qctx->tls_aad, ptr, qctx->tls_aad_len); else { if (qctx->tls_aad) { OPENSSL_free(qctx->tls_aad); qctx->tls_aad_len = -1; qctx->tls_aad_set = 0; } qctx->tls_aad_len = EVP_AEAD_TLS1_AAD_LEN; qctx->tls_aad = OPENSSL_malloc(qctx->tls_aad_len); if (qctx->tls_aad) { /* Copy the header from payload into the buffer */ memcpy(qctx->tls_aad, ptr, qctx->tls_aad_len); } else { WARN("AAD alloc failed\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_MALLOC_FAILURE); ret_val = 0; break; } } /* Extract the length of the payload from the TLS header */ unsigned int plen = qctx->tls_aad[arg - QAT_SM4_TLS_PAYLOADLENGTH_MSB_OFFSET] << QAT_BYTE_SHIFT | qctx->tls_aad[arg - QAT_SM4_TLS_PAYLOADLENGTH_LSB_OFFSET]; /* The payload contains the explicit IV -> correct the length */ plen -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!enc) { plen -= EVP_GCM_TLS_TAG_LEN; } /* Fix the length like in the SW version of SM4 */ qctx->tls_aad[EVP_AEAD_TLS1_AAD_LEN - QAT_SM4_TLS_PAYLOADLENGTH_MSB_OFFSET] = plen >> QAT_BYTE_SHIFT; qctx->tls_aad[EVP_AEAD_TLS1_AAD_LEN - QAT_SM4_TLS_PAYLOADLENGTH_LSB_OFFSET] = plen; //& 0xff; qctx->tls_aad_set = 1; /* Extra padding: tag appended to record */ ret_val = EVP_GCM_TLS_TAG_LEN; break; case EVP_CTRL_GET_IVLEN: DEBUG("CTRL Type = EVP_CTRL_GET_IVLEN, ctx = %p, type = %d," " arg = %d, ptr = %p\n", (void*)ctx, type, arg, ptr); DEBUG("EVP_CTRL_GET_IVLEN qctx->iv_len %d\n",qctx->iv_len); *(int*)ptr = qctx->iv_len; ret_val = 1; break; case EVP_CTRL_AEAD_SET_MAC_KEY: /* no-op */ ret_val = 1; break; default: WARN("Invalid type %d\n", type); QATerr(QAT_F_QAT_SW_SM4_GCM_CTRL, QAT_R_INVALID_TYPE); ret_val = -1; break; } return ret_val; } #ifdef QAT_OPENSSL_PROVIDER static int qat_sw_sm4_gcm_decrypt(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) #else static int qat_sw_sm4_gcm_decrypt(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_GCM sw_sm4_gcm_cipher; QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; #else QAT_SM4_GCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0, job_ret = 0; ASYNC_JOB *job; sm4_gcm_decrypt_op_data *sm4_gcm_decrypt_req = NULL; mb_thread_data *tlv = NULL; static __thread int req_num = 0; int init_flag = 0; DEBUG("started: ctx=%p out=%p in=%p len=%lu\n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_DECRYPT, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_DECRYPT, QAT_R_QCTX_NULL); return sts; } init_flag = qctx->init_flag; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((sm4_gcm_decrypt_req = mb_flist_sm4_gcm_decrypt_pop(tlv->sm4_gcm_decrypt_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM4_GCM cipher_decrypt Started %p", sm4_gcm_decrypt_req); START_RDTSC(&sm4_gcm_cycles_decrypt_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm4_gcm_decrypt_req->state = &qctx->smctx; sm4_gcm_decrypt_req->job = job; sm4_gcm_decrypt_req->sts = &sts; sm4_gcm_decrypt_req->sm4_in = in; sm4_gcm_decrypt_req->sm4_len = len; sm4_gcm_decrypt_req->sm4_out = out; sm4_gcm_decrypt_req->sm4_key = (sm4_key *)qctx->key; sm4_gcm_decrypt_req->sm4_iv = qctx->iv; sm4_gcm_decrypt_req->sm4_ivlen = qctx->iv_len; sm4_gcm_decrypt_req->sm4_tag = qctx->calculated_tag; sm4_gcm_decrypt_req->sm4_taglen = qctx->tag_len; if (qctx->init_flag == 1) { sm4_gcm_decrypt_req->sm4_aad = qctx->tls_aad; #ifdef QAT_NTLS sm4_gcm_decrypt_req->sm4_aadlen = qctx->tls_aad_len; #else sm4_gcm_decrypt_req->sm4_aadlen = qctx->aad_len; #endif } sm4_gcm_decrypt_req->init_flag = init_flag; mb_queue_sm4_gcm_decrypt_enqueue(tlv->sm4_gcm_decrypt_queue, sm4_gcm_decrypt_req); STOP_RDTSC(&sm4_gcm_cycles_decrypt_setup, 1, "[SM4_GCM:decrypt_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM4_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm4ctx %p\n", sm4_gcm_decrypt_req, sts, sm4_gcm_decrypt_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) { sched_yield(); } } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); DEBUG("Finished: Decrypt %p status = %d\n", sm4_gcm_decrypt_req, sts); qctx->init_flag = 1; if (sts) { return sts; } else { WARN("Failure in SM4_GCM decrypt\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_DECRYPT, QAT_R_SM4_GCM_DECRYPT_FAILURE); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(EVP_sm4_gcm())(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("SW Decryption Finished sts=%d\n", sts); #else sw_sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (sw_sm4_gcm_cipher.cupdate == NULL) goto err; sw_sm4_gcm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); *padlen = len; return 1; #endif err: return sts; } #ifdef QAT_OPENSSL_PROVIDER static int qat_sw_sm4_gcm_encrypt(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) #else static int qat_sw_sm4_gcm_encrypt(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_EVP_CIPHER_SM4_GCM sw_sm4_gcm_cipher; QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; #else QAT_SM4_GCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0, job_ret = 0; ASYNC_JOB *job; sm4_gcm_encrypt_op_data *sm4_gcm_encrypt_req = NULL; mb_thread_data *tlv = NULL; static __thread int req_num = 0; int init_flag = 0; DEBUG("started: ctx=%p out=%p in=%p len=%lu\n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_ENCRYPT, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_ENCRYPT, QAT_R_QCTX_NULL); return sts; } init_flag = qctx->init_flag; /* Check if we are running asynchronously. If not use the SW method */ if ((job = ASYNC_get_current_job()) == NULL) { DEBUG("Running synchronously using sw method\n"); goto use_sw_method; } /* Setup asynchronous notifications */ if (!qat_setup_async_event_notification(job)) { DEBUG("Failed to setup async notifications, using sw method\n"); goto use_sw_method; } tlv = mb_check_thread_local(); if (NULL == tlv) { WARN("Could not create thread local variables\n"); goto use_sw_method; } while ((sm4_gcm_encrypt_req = mb_flist_sm4_gcm_encrypt_pop(tlv->sm4_gcm_encrypt_freelist)) == NULL) { qat_wake_job(job, ASYNC_STATUS_EAGAIN); qat_pause_job(job, ASYNC_STATUS_EAGAIN); } DEBUG("QAT SW SM4_GCM encrypt Started %p\n", sm4_gcm_encrypt_req); START_RDTSC(&sm4_gcm_cycles_encrypt_setup); /* Buffer up the requests and call the new functions when we have enough requests buffered up */ sm4_gcm_encrypt_req->state = &qctx->smctx; sm4_gcm_encrypt_req->job = job; sm4_gcm_encrypt_req->sts = &sts; sm4_gcm_encrypt_req->sm4_in = in; sm4_gcm_encrypt_req->sm4_len = len; sm4_gcm_encrypt_req->sm4_out = out; sm4_gcm_encrypt_req->sm4_key = (sm4_key *)qctx->key; sm4_gcm_encrypt_req->sm4_iv = qctx->iv; sm4_gcm_encrypt_req->sm4_ivlen = qctx->iv_len; sm4_gcm_encrypt_req->sm4_tag = qctx->tag; sm4_gcm_encrypt_req->sm4_taglen = qctx->tag_len; if (qctx->init_flag == 1) { sm4_gcm_encrypt_req->sm4_aad = qctx->tls_aad; #ifdef QAT_NTLS sm4_gcm_encrypt_req->sm4_aadlen = qctx->tls_aad_len; #else sm4_gcm_encrypt_req->sm4_aadlen = qctx->aad_len; #endif } sm4_gcm_encrypt_req->init_flag = init_flag; mb_queue_sm4_gcm_encrypt_enqueue(tlv->sm4_gcm_encrypt_queue, sm4_gcm_encrypt_req); STOP_RDTSC(&sm4_gcm_cycles_encrypt_setup, 1, "[SM4_GCM:encrypt_setup]"); if (!enable_external_polling && (++req_num % MULTIBUFF_SM4_MAX_BATCH) == 0) { DEBUG("Signal Polling thread, req_num %d\n", req_num); if (sem_post(&tlv->mb_polling_thread_sem) != 0) { WARN("hw sem_post failed!, mb_polling_thread_sem address: %p.\n", &tlv->mb_polling_thread_sem); /* If we fail the pthread_kill carry on as the timeout * will catch processing the request in the polling thread */ } } DEBUG("Pausing: %p status = %d sm4ctx %p\n", sm4_gcm_encrypt_req, sts, sm4_gcm_encrypt_req->state); do { /* If we get a failure on qat_pause_job then we will not flag an error here and quit because we have an asynchronous request in flight. We don't want to start cleaning up data structures that are still being used. If qat_pause_job fails we will just yield and loop around and try again until the request completes and we can continue. */ if ((job_ret = qat_pause_job(job, ASYNC_STATUS_OK)) == 0) { sched_yield(); } } while (QAT_CHK_JOB_RESUMED_UNEXPECTEDLY(job_ret)); qctx->init_flag = 1; DEBUG("Finished: Encrypt %p status = %d\n", sm4_gcm_encrypt_req, sts); if (sts) { return sts; } else { WARN("Failure in SM4_GCM encrypt\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_ENCRYPT, QAT_R_SM4_GCM_ENCRYPT_FAILURE); return sts; } use_sw_method: #ifndef QAT_OPENSSL_PROVIDER sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(EVP_sm4_gcm())(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("SW Encryption Finished sts=%d\n", sts); #else sw_sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (sw_sm4_gcm_cipher.cupdate == NULL) goto err; sw_sm4_gcm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); *padlen = len; return 1; #endif err: return sts; } #ifdef QAT_OPENSSL_PROVIDER static int qat_sw_sm4_gcm_tls_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len, int8u enc) #else static int qat_sw_sm4_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len, int8u enc) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; #else QAT_SM4_GCM_CTX *qctx = NULL; #endif int sts = -1; DEBUG("started: ctx=%p out=%p in=%p len=%lu in_txt=%d\n", ctx, out, in, len, enc); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_TLS_CIPHER, QAT_R_CTX_NULL); return sts; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_TLS_CIPHER, QAT_R_QCTX_NULL); return sts; } /* Encrypt/decrypt must be performed in place */ if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) return -1; #ifdef QAT_OPENSSL_PROVIDER if (qat_sw_sm4_gcm_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) { goto err; } #else /* * Set IV from start of buffer or generate IV and write to start of * buffer. */ if (EVP_CIPHER_CTX_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) goto err; #endif /* Fix buffer and length to point to payload */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; if (enc) { #ifdef QAT_OPENSSL_PROVIDER /* Encrypt payload */ if (!qat_sw_sm4_gcm_encrypt(ctx, out, padlen, outsize, in, len)) #else /* Encrypt payload */ if (!qat_sw_sm4_gcm_encrypt(ctx, out, in, len)) #endif goto err; out += len; memcpy(out, qctx->tag, EVP_GCM_TLS_TAG_LEN); sts = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; } else { #ifdef QAT_OPENSSL_PROVIDER /* Decrypt */ if (!qat_sw_sm4_gcm_decrypt(ctx, out, padlen, outsize, in, len)) #else /* Decrypt */ if (!qat_sw_sm4_gcm_decrypt(ctx, out, in, len)) #endif goto err; DUMPL("decrytp tag", qctx->calculated_tag, EVP_GCM_TLS_TAG_LEN); DUMPL("encrypt tag", in + len, EVP_GCM_TLS_TAG_LEN); if (memcmp(qctx->calculated_tag, in + len, EVP_GCM_TLS_TAG_LEN) == 0) sts = len; else { WARN("SM4-GCM calculated tag comparison failed\n"); sts = -1; } } err: qctx->iv_set = 0; qctx->tls_aad_len = -1; #ifdef QAT_OPENSSL_PROVIDER if (sts < 0) { *padlen = 0; return -1; } else { *padlen = sts; return 1; } #else return sts; #endif } #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_gcm_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len) #else int qat_sw_sm4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) #endif { #ifdef QAT_OPENSSL_PROVIDER QAT_PROV_GCM_CTX *qctx = (QAT_PROV_GCM_CTX *)ctx; QAT_EVP_CIPHER_SM4_GCM sw_sm4_gcm_cipher; #else QAT_SM4_GCM_CTX *qctx = NULL; void *sw_ctx_cipher_data = NULL; #endif int sts = 0; int enc = 0; DEBUG("started: ctx=%p out=%p in=%p len=%lu\n", ctx, out, in, len); if (unlikely(ctx == NULL)) { WARN("ctx (type EVP_CIPHER_CTX) is NULL \n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CIPHER, QAT_R_CTX_NULL); return 0; } #ifndef QAT_OPENSSL_PROVIDER qctx = (QAT_SM4_GCM_CTX *)EVP_CIPHER_CTX_get_cipher_data(ctx); #endif if (qctx == NULL) { WARN("qctx is NULL\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CIPHER, QAT_R_QCTX_NULL); return sts; } #ifdef QAT_OPENSSL_PROVIDER enc = QAT_SM4_CIPHER_CTX_encrypting(qctx); #else enc = EVP_CIPHER_CTX_encrypting(ctx); #endif if (fallback_to_openssl) goto use_sw_method; if (ASYNC_get_current_job() == NULL) { DEBUG("SW Cipher Offload Started\n"); goto use_sw_method; } if (qctx->tls_aad_len >= 0) #ifdef QAT_OPENSSL_PROVIDER return qat_sw_sm4_gcm_tls_cipher(ctx, out, padlen, outsize, in, len, enc); #else return qat_sw_sm4_gcm_tls_cipher(ctx, out, in, len, enc); #endif if ((out == NULL) && (in != NULL)) { qctx->tls_aad = OPENSSL_zalloc(len); if (qctx->tls_aad == NULL) { DEBUG("Failed to allocate qctx->aad\n"); QATerr(QAT_F_QAT_SW_SM4_GCM_CIPHER, QAT_R_MALLOC_FAILURE); return sts; } memcpy(qctx->tls_aad, in, len); qctx->aad_len = len; sts = len; } if (in == NULL && out != NULL) { if (enc) { #ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->buf, qctx->tag, qctx->tag_len); #else memcpy(out, qctx->tag, qctx->tag_len); #endif qctx->tag_set = 1; } else { #ifdef QAT_OPENSSL_PROVIDER memcpy(qctx->buf, qctx->calculated_tag, qctx->tag_len); #else memcpy(out, qctx->calculated_tag, qctx->tag_len); #endif qctx->tag_calculated = 1; if (qctx->tag_set) { DEBUG("Decrypt - GCM Tag Set so calling memcmp\n"); if (memcmp(qctx->calculated_tag, qctx->tag, qctx->tag_len) == 0) #ifdef QAT_OPENSSL_PROVIDER sts = len; #else sts = 0; #endif else { WARN("SM4-GCM calculated tag comparison failed\n"); DUMPL("Expected Tag:", (const unsigned char *)qctx->tag, qctx->tag_len); DUMPL("Calculated Tag:", (const unsigned char *)qctx->calculated_tag, qctx->tag_len); DUMPL("Decrypt - Calculated Tag", (const unsigned char*)qctx->calculated_tag , qctx->tag_len); #ifdef QAT_OPENSSL_PROVIDER *padlen = 0; sts = -1; goto err; #else sts = -1; #endif } } } } else if(in != NULL && out != NULL){ if (enc) { #ifdef QAT_OPENSSL_PROVIDER sts = qat_sw_sm4_gcm_encrypt(ctx, out, padlen, outsize, in, len); #else sts = qat_sw_sm4_gcm_encrypt(ctx, out, in, len); #endif } else { #ifdef QAT_OPENSSL_PROVIDER sts = qat_sw_sm4_gcm_decrypt(ctx, out, padlen, outsize, in, len); #else sts = qat_sw_sm4_gcm_decrypt(ctx, out, in, len); #endif } if (sts >= 1) sts = len; else sts = -1; } #ifdef QAT_OPENSSL_PROVIDER *padlen = sts; return 1; #else return sts; #endif use_sw_method: #ifdef QAT_OPENSSL_PROVIDER sw_sm4_gcm_cipher = get_default_cipher_sm4_gcm(); if (sw_sm4_gcm_cipher.cupdate == NULL) goto err; if (in != NULL) { sts = sw_sm4_gcm_cipher.cupdate(qctx->sw_ctx, out, padlen, outsize, in, len); *padlen = len; return 1; } else { sts = sw_sm4_gcm_cipher.cfinal(qctx->sw_ctx, out, padlen, outsize); if (enc) { OSSL_PARAM params[4] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; void *ptr = OPENSSL_zalloc(EVP_GCM_TLS_TAG_LEN); params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, ptr, EVP_GCM_TLS_TAG_LEN); sw_sm4_gcm_cipher.get_ctx_params(qctx->sw_ctx, params); memcpy(qctx->buf, (char*)params->data, EVP_GCM_TLS_TAG_LEN); } *padlen = len; return 1; } DEBUG("SW Offload Finished sts=%d\n", sts); #else sw_ctx_cipher_data = qctx->sw_ctx_cipher_data; if (!sw_ctx_cipher_data) goto err; EVP_CIPHER_CTX_set_cipher_data(ctx, sw_ctx_cipher_data); sts = EVP_CIPHER_meth_get_do_cipher(EVP_sm4_gcm())(ctx, out, in, len); EVP_CIPHER_CTX_set_cipher_data(ctx, qctx); DEBUG("SW Offload Finished sts=%d\n", sts); #endif err: return sts; } #endif /* ENABLE_QAT_SW_SM4_GCM */ qatengine-1.9.0/qat_sw_sm4_gcm.h000066400000000000000000000137631500416242000165600ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_sw_sm4_gcm.h * * This file Provides SM4-GCM interface for OpenSSL engine * *****************************************************************************/ #ifndef QAT_SW_SM4_GCM_H # define QAT_SW_SM4_GCM_H # ifndef QAT_OPENSSL_PROVIDER # include # endif # include # include # include #ifdef ENABLE_QAT_SW_SM4_GCM /* QAT_SW SM4 methods declaration */ #define QAT_BYTE_SHIFT 8 #define QAT_SM4_TAG_MIN_LEN 0 #define QAT_SM4_TAG_MAX_LEN 16 #define QAT_SM4_TLS_PAYLOADLENGTH_MSB_OFFSET 2 #define QAT_SM4_TLS_PAYLOADLENGTH_LSB_OFFSET 1 #define QAT_SM4_TLS_TOTAL_IV_LEN (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN) /* babassl flags needed for sw method */ #define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_AEAD_CIPHER \ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CUSTOM_IV_LENGTH \ | EVP_CIPH_GCM_MODE) typedef struct { SM4_GCM_CTX_mb16 smctx; int init_flag; unsigned char* key; char key_len; int key_set; /* Set if key initialized */ unsigned char* tls_aad; int aad_len; int tls_aad_len; /* TLS AAD length */ unsigned int tls_aad_set; unsigned char* tag; unsigned char* calculated_tag; int tag_len; unsigned int tag_set; unsigned int tag_calculated; unsigned char* iv; unsigned char* next_iv; int iv_len; unsigned int iv_set; int iv_gen; void* sw_ctx_cipher_data; } QAT_SM4_GCM_CTX; /* sm4 key struct from BabaSSL */ # define SM4_KEY_SCHEDULE 32 typedef struct SM4_GCM_KEY_st { uint32_t rk[SM4_KEY_SCHEDULE]; } SM4_GCM_KEY; typedef unsigned int u32; typedef unsigned char u8; typedef unsigned long long u64; typedef struct { u64 hi, lo; } u128; struct gcm128_context { /* Following 6 names follow names in GCM specification */ union { u64 u[2]; u32 d[4]; u8 c[16]; size_t t[16 / sizeof(size_t)]; } Yi, EKi, EK0, len, Xi, H; /* * Relative position of Xi, H and pre-computed Htable is used in some * assembler modules, i.e. don't change the order! */ u128 Htable[16]; void (*gmult) (u64 Xi[2], const u128 Htable[16]); void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len); unsigned int mres, ares; block128_f block; void *key; #if !defined(OPENSSL_SMALL_FOOTPRINT) unsigned char Xn[48]; #endif }; typedef struct gcm128_context GCM128_CONTEXT; typedef struct { SM4_GCM_KEY ks; /* SM4 key schedule to use */ int key_set; /* Set if key initialized */ int iv_set; /* Set if an iv is set */ GCM128_CONTEXT gcm; unsigned char *iv; /* Temporary IV store */ int ivlen; /* IV length */ int taglen; int iv_gen; /* It is OK to generate IVs */ int tls_aad_len; /* TLS AAD length */ ctr128_f ctr; } EVP_SM4_GCM_CTX; #ifdef QAT_OPENSSL_PROVIDER int qat_sw_sm4_gcm_init(void *ctx, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen, int enc); int qat_sw_sm4_gcm_ctrl(void *ctx, int type, int arg, void *ptr); int qat_sw_sm4_gcm_cipher(void *ctx, unsigned char *out, size_t *padlen, size_t outsize, const unsigned char *in, size_t len); int qat_sw_sm4_gcm_cleanup(void *ctx); #else int qat_sw_sm4_gcm_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); int qat_sw_sm4_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); int qat_sw_sm4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len); int qat_sw_sm4_gcm_cleanup(EVP_CIPHER_CTX *ctx); # endif void process_mb_sm4_gcm_encrypt_reqs(mb_thread_data *tlv); void process_mb_sm4_gcm_decrypt_reqs(mb_thread_data *tlv); #endif /* ENABLE_QAT_SW_SM4_GCM */ #endif /* QAT_SW_SM4_GCM_H */ qatengine-1.9.0/qat_utils.c000066400000000000000000000252141500416242000156430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_utils.c * * This file provides an implementation of utilities for an OpenSSL engine * *****************************************************************************/ #include #include #include "qat_utils.h" #include "e_qat.h" #ifdef QAT_HW # include "cpa.h" #endif FILE *qatDebugLogFile = NULL; #ifdef QAT_TESTS_LOG FILE *cryptoQatLogger = NULL; pthread_mutex_t test_file_mutex = PTHREAD_MUTEX_INITIALIZER; int test_file_ref_count = 0; char test_file_name[QAT_MAX_TEST_FILE_NAME_LENGTH]; #endif /* QAT_TESTS_LOG */ #ifdef QAT_CPU_CYCLES_COUNT rdtsc_prof_t rsa_cycles_priv_enc_setup; rdtsc_prof_t rsa_cycles_priv_dec_setup; rdtsc_prof_t rsa_cycles_priv_execute; rdtsc_prof_t rsa_cycles_pub_enc_setup; rdtsc_prof_t rsa_cycles_pub_dec_setup; rdtsc_prof_t rsa_cycles_pub_execute; rdtsc_prof_t x25519_cycles_keygen_setup; rdtsc_prof_t x25519_cycles_keygen_execute; rdtsc_prof_t x25519_cycles_derive_setup; rdtsc_prof_t x25519_cycles_derive_execute; rdtsc_prof_t ecdsa_cycles_sign_setup; rdtsc_prof_t ecdsa_cycles_sign_execute; rdtsc_prof_t ecdsa_cycles_sign_setup_setup; rdtsc_prof_t ecdsa_cycles_sign_setup_execute; rdtsc_prof_t ecdsa_cycles_sign_sig_setup; rdtsc_prof_t ecdsa_cycles_sign_sig_execute; rdtsc_prof_t ecdh_cycles_keygen_setup; rdtsc_prof_t ecdh_cycles_keygen_execute; rdtsc_prof_t ecdh_cycles_compute_setup; rdtsc_prof_t ecdh_cycles_compute_execute; rdtsc_prof_t sm2ecdh_cycles_keygen_setup; rdtsc_prof_t sm2ecdh_cycles_keygen_execute; rdtsc_prof_t sm2ecdh_cycles_compute_setup; rdtsc_prof_t sm2ecdh_cycles_compute_execute; rdtsc_prof_t sm3_cycles_init_setup; rdtsc_prof_t sm3_cycles_init_execute; rdtsc_prof_t sm3_cycles_update_setup; rdtsc_prof_t sm3_cycles_update_execute; rdtsc_prof_t sm3_cycles_final_setup; rdtsc_prof_t sm3_cycles_final_execute; rdtsc_prof_t ecdsa_cycles_verify_setup; rdtsc_prof_t ecdsa_cycles_verify_execute; rdtsc_prof_t sm4_gcm_cycles_init_setup; rdtsc_prof_t sm4_gcm_cycles_init_execute; rdtsc_prof_t sm4_gcm_cycles_encrypt_setup; rdtsc_prof_t sm4_gcm_cycles_encrypt_execute; rdtsc_prof_t sm4_gcm_cycles_decrypt_setup; rdtsc_prof_t sm4_gcm_cycles_decrypt_execute; rdtsc_prof_t sm4_gcm_cycles_get_tag_setup; rdtsc_prof_t sm4_gcm_cycles_get_tag_execute; rdtsc_prof_t sm4_gcm_cycles_update_iv_setup; rdtsc_prof_t sm4_gcm_cycles_update_iv_execute; rdtsc_prof_t sm4_gcm_cycles_update_aad_setup; rdtsc_prof_t sm4_gcm_cycles_update_aad_execute; rdtsc_prof_t sm4_gcm_cycles_cipher_setup; rdtsc_prof_t sm4_gcm_cycles_cipher_execute; rdtsc_prof_t sm4_gcm_cycles_ctrl_setup; rdtsc_prof_t sm4_gcm_cycles_ctrl_execute; rdtsc_prof_t sm4_gcm_cycles_cleanup_setup; rdtsc_prof_t sm4_gcm_cycles_cleanup_execute; rdtsc_prof_t sm4_cbc_cycles_cipher_execute; rdtsc_prof_t sm4_cbc_cycles_cipher_dec_execute; rdtsc_prof_t sm4_ccm_cycles_init_setup; rdtsc_prof_t sm4_ccm_cycles_init_execute; rdtsc_prof_t sm4_ccm_cycles_encrypt_setup; rdtsc_prof_t sm4_ccm_cycles_encrypt_execute; rdtsc_prof_t sm4_ccm_cycles_decrypt_setup; rdtsc_prof_t sm4_ccm_cycles_decrypt_execute; rdtsc_prof_t sm4_ccm_cycles_get_tag_setup; rdtsc_prof_t sm4_ccm_cycles_get_tag_execute; rdtsc_prof_t sm4_ccm_cycles_update_aad_setup; rdtsc_prof_t sm4_ccm_cycles_update_aad_execute; rdtsc_prof_t sm4_ccm_cycles_ctrl_setup; rdtsc_prof_t sm4_ccm_cycles_ctrl_execute; rdtsc_prof_t sm4_ccm_cycles_cleanup_setup; rdtsc_prof_t sm4_ccm_cycles_cleanup_execute; rdtsc_prof_t qat_hw_rsa_dec_req_prepare; rdtsc_prof_t qat_hw_rsa_dec_req_submit; rdtsc_prof_t qat_hw_rsa_dec_req_retry; rdtsc_prof_t qat_hw_rsa_dec_req_cleanup; rdtsc_prof_t qat_hw_ecdsa_sign_req_prepare; rdtsc_prof_t qat_hw_ecdsa_sign_req_submit; rdtsc_prof_t qat_hw_ecdsa_sign_req_retry; rdtsc_prof_t qat_hw_ecdsa_sign_req_cleanup; rdtsc_prof_t qat_hw_ecdh_derive_req_prepare; rdtsc_prof_t qat_hw_ecdh_derive_req_submit; rdtsc_prof_t qat_hw_ecdh_derive_req_retry; rdtsc_prof_t qat_hw_ecdh_derive_req_cleanup; rdtsc_prof_t qat_hw_ecx_derive_req_prepare; rdtsc_prof_t qat_hw_ecx_derive_req_submit; rdtsc_prof_t qat_hw_ecx_derive_req_retry; rdtsc_prof_t qat_hw_ecx_derive_req_cleanup; volatile static double rdtsc_prof_cost = 0.0; /* cost of measurement */ int print_cycle_count = 1; #endif #ifdef QAT_DEBUG_FILE_PATH pthread_mutex_t debug_file_mutex = PTHREAD_MUTEX_INITIALIZER; int debug_file_ref_count = 0; void crypto_qat_debug_init_log() { pthread_mutex_lock(&debug_file_mutex); if (!debug_file_ref_count) { qatDebugLogFile = fopen(STR(QAT_DEBUG_FILE_PATH), "w"); if (NULL == qatDebugLogFile) { qatDebugLogFile = stderr; WARN("unable to open %s\n", STR(QAT_DEBUG_FILE_PATH)); } else { debug_file_ref_count++; } } pthread_mutex_unlock(&debug_file_mutex); } void crypto_qat_debug_close_log() { pthread_mutex_lock(&debug_file_mutex); if (debug_file_ref_count) { if (qatDebugLogFile != NULL) { fclose(qatDebugLogFile); debug_file_ref_count--; qatDebugLogFile = stderr; } } pthread_mutex_unlock(&debug_file_mutex); } #endif /* QAT_DEBUG_FILE_PATH */ #ifdef QAT_TESTS_LOG char *crypto_qat_testing_get_log_filename() { snprintf(test_file_name, QAT_MAX_TEST_FILE_NAME_LENGTH, "/opt/qat-crypto-%d.log", getpid()); return test_file_name; } void crypto_qat_testing_init_log() { pthread_mutex_lock(&test_file_mutex); if (!test_file_ref_count) { cryptoQatLogger = fopen(crypto_qat_testing_get_log_filename(), "w"); if (NULL == cryptoQatLogger) { WARN("unable to open %s\n", test_file_name); pthread_mutex_unlock(&test_file_mutex); exit(1); } else { test_file_ref_count++; } } pthread_mutex_unlock(&test_file_mutex); } void crypto_qat_testing_close_log() { pthread_mutex_lock(&test_file_mutex); if (test_file_ref_count) { if (cryptoQatLogger != NULL) { fclose(cryptoQatLogger); test_file_ref_count--; } } pthread_mutex_unlock(&test_file_mutex); } #endif /* QAT_TESTS_LOG */ #ifdef QAT_DEBUG void qat_hex_dump(const char *func, const char *var, const unsigned char p[], int l) { fprintf(qatDebugLogFile, "%s: %s: Length %d, Address %p\n", func, var, l, p); # ifdef QAT_HEX_DUMP int i; if (NULL != p && l > 0) { for (i = 0; i < l; i++) { if (i != 0 && i % 32 == 0) fputc('\n', qatDebugLogFile); else if (i != 0 && i % 8 == 0) fputs("- ", qatDebugLogFile); fprintf(qatDebugLogFile, "%02x ", p[i]); } } fputc('\n', qatDebugLogFile); fflush(qatDebugLogFile); # endif } #endif #ifdef QAT_CPU_CYCLES_COUNT void rdtsc_prof_init(rdtsc_prof_t *p, const uint32_t bytes) { p->bytes = bytes; p->clk_start = 0; p->clk_avg = 0.0; p->clk_avgc = 0; p->clk_diff_cost_adjusted = 0.0; p->started = 0; p->cost = rdtsc_prof_cost; } void rdtsc_prof_print(rdtsc_prof_t *p, char *name) { if (p == NULL) { fprintf(qatDebugLogFile, "%s\tavg\n", " "); } else { if (p->clk_avgc > 0) { double avg_c = (p->clk_avg / ((double)p->clk_avgc)); # ifdef QAT_CPU_CYCLE_MEASUREMENT_COST fprintf(qatDebugLogFile, "\n%s - avg cycles per job (mca ENABLED): %.1f - number of samples = %ld\n", name, avg_c, p->clk_avgc); # else fprintf(qatDebugLogFile, "%s,%.1f,%ld\n", name, avg_c, p->clk_avgc); # endif if (p->bytes > 0) { double avg_pb = avg_c / ((double)p->bytes); fprintf(qatDebugLogFile, " - avg cycles per byte: %.1f\n", avg_pb); } } } } void rdtsc_initialize(void) { rdtsc_prof_t p; unsigned i; /* Figure out cost of measurement */ rdtsc_prof_init(&p, 0); print_cycle_count = 0; for (i = 0; i < 10000; i++) { rdtsc_prof_start(&p); rdtsc_prof_end(&p, 1, "Measurement cost"); } # ifdef QAT_CPU_CYCLE_COUNT_DEBUG print_cycle_count = 1; # endif rdtsc_prof_print(&p, "Cost of CPU cycle measurement "); rdtsc_prof_cost = p.clk_avg / (double)p.clk_avgc; fprintf(qatDebugLogFile, "[%s] - cost of measurement is subtracted from subsequent tests if build flag QAT_CPU_CYCLE_MEASUREMENT_COST is set\n\n", __func__); } #endif /* QAT_CPU_CYCLES_COUNT */ /* Get absolute time by relative time. */ void get_sem_wait_abs_time(struct timespec *polling_abs_timeout, const struct timespec polling_timeout) { clock_gettime(CLOCK_REALTIME, polling_abs_timeout); /* Get current real time. */ polling_abs_timeout->tv_sec += polling_timeout.tv_sec; polling_abs_timeout->tv_nsec += polling_timeout.tv_nsec; polling_abs_timeout->tv_sec += polling_abs_timeout->tv_nsec / NSEC_TO_SEC; polling_abs_timeout->tv_nsec = polling_abs_timeout->tv_nsec % NSEC_TO_SEC; } qatengine-1.9.0/qat_utils.h000066400000000000000000002261371500416242000156570ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2016-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file qat_utils.h * * This file provides an interface to utilities for the QAT engine in OpenSSL * *****************************************************************************/ #ifndef QAT_UTILS_H # define QAT_UTILS_H # include # include # include # include # ifdef QAT_HW # include "cpa.h" # include "cpa_cy_sym.h" # endif # define QAT_BYTE_ALIGNMENT 64 # define NANO_TO_MICROSECS 1000 # define NSEC_TO_SEC 1000000000L /* For best performance data buffers should be 64-byte aligned */ # define QAT_CONTIG_MEM_ALIGN(x) \ (void *)(((uintptr_t)(x) + QAT_BYTE_ALIGNMENT - 1) & \ (~(uintptr_t)(QAT_BYTE_ALIGNMENT-1))) extern FILE *qatDebugLogFile; # ifdef QAT_DEBUG_FILE_PATH extern pthread_mutex_t debug_file_mutex; extern int debug_file_ref_count; void crypto_qat_debug_init_log(); void crypto_qat_debug_close_log(); # define QAT_DEBUG_LOG_INIT() crypto_qat_debug_init_log() # define QAT_DEBUG_LOG_CLOSE() crypto_qat_debug_close_log() # else # define QAT_DEBUG_LOG_INIT() \ do { \ if (qatDebugLogFile == NULL) \ qatDebugLogFile = stderr; \ } while(0) # define QAT_DEBUG_LOG_CLOSE() # endif /* * Add -DQAT_TESTS_LOG to ./config to enable debug logging to the * CRYPTO_QAT_LOG_FILE */ # ifdef QAT_TESTS_LOG # define QAT_MAX_TEST_FILE_NAME_LENGTH 1024 extern FILE *cryptoQatLogger; extern pthread_mutex_t test_file_mutex; extern int test_file_ref_count; void crypto_qat_testing_init_log(); void crypto_qat_testing_close_log(); # define CRYPTO_INIT_QAT_LOG() crypto_qat_testing_init_log() # define CRYPTO_CLOSE_QAT_LOG() crypto_qat_testing_close_log() # define CRYPTO_QAT_LOG(...) \ do { \ pthread_mutex_lock(&test_file_mutex); \ if (test_file_ref_count) { \ if (cryptoQatLogger != NULL) { \ fprintf(cryptoQatLogger, __VA_ARGS__); \ fflush(cryptoQatLogger); \ } \ } \ pthread_mutex_unlock(&test_file_mutex); \ } while(0) # else # define CRYPTO_QAT_LOG(...) # define CRYPTO_CLOSE_QAT_LOG() # define CRYPTO_INIT_QAT_LOG() # endif /* Debug and warning messages for the QAT engine */ # ifdef QAT_DEBUG void qat_hex_dump(const char *func, const char *var, const unsigned char p[], int l); # define DEBUG(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ fprintf(qatDebugLogFile,"[DEBUG][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while (0) # define DUMPL(var,p,l) qat_hex_dump(__func__,var,p,l); # else # define DEBUG(...) # define DUMPL(...) # endif # if defined(QAT_WARN) || defined(QAT_DEBUG) # define WARN(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ fprintf(qatDebugLogFile,"[WARN][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(qatDebugLogFile); \ } while (0) # else # define WARN(...) # endif # define INFO(fmt_str, ...) \ do { \ fprintf(stderr,fmt_str, ##__VA_ARGS__); \ fflush(stderr); \ } while (0) # ifdef QAT_DEBUG # define DUMP_DH_GEN_PHASE1(instance_handle, opData, pPV) \ do { \ fprintf(qatDebugLogFile,"DH Generate Phase 1 Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("primeP.pData", opData->primeP.pData, \ opData->primeP.dataLenInBytes); \ DUMPL("baseG.pData", opData->baseG.pData, \ opData->baseG.dataLenInBytes); \ DUMPL("privateValueX.pData", opData->privateValueX.pData, \ opData->privateValueX.dataLenInBytes); \ fprintf(qatDebugLogFile, "pPV->dataLenInBytes = %u pPV->pData = %p\n", \ pPV->dataLenInBytes, pPV->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_DH_GEN_PHASE2(instance_handle, opData, pSecretKey) \ do { \ fprintf(qatDebugLogFile,"DH Generate Phase 2 Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("primeP.pData", opData->primeP.pData, \ opData->primeP.dataLenInBytes); \ DUMPL("remoteOctetStringPV.pData", \ opData->remoteOctetStringPV.pData, \ opData->remoteOctetStringPV.dataLenInBytes); \ DUMPL("privateValueX.pData", opData->privateValueX.pData, \ opData->privateValueX.dataLenInBytes); \ fprintf(qatDebugLogFile,"pSecretKey->dataLenInBytes = %u " \ "pSecretKey->pData = %p\n", \ pSecretKey->dataLenInBytes, pSecretKey->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_DH_GEN_PHASE1_OUTPUT(pPV) \ do { \ fprintf(qatDebugLogFile,"DH Generate Phase 1 Output: %p\n", pPV); \ DUMPL("pPV->pData", pPV->pData, pPV->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_DH_GEN_PHASE2_OUTPUT(pSecretKey) \ do { \ fprintf(qatDebugLogFile,"DH Generate Phase 2 Output: %p\n", \ pSecretKey); \ DUMPL("pSecretKey->pData", \ pSecretKey->pData, pSecretKey->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_EC_POINT_MULTIPLY(instance_handle, opData, pResultX, pResultY) \ do { \ fprintf(qatDebugLogFile,"EC Point Multiply Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("k.pData", opData->k.pData, opData->k.dataLenInBytes); \ DUMPL("xg.pData", opData->xg.pData, opData->xg.dataLenInBytes); \ DUMPL("yg.pData", opData->yg.pData, opData->yg.dataLenInBytes); \ DUMPL("a.pData", opData->a.pData, opData->a.dataLenInBytes); \ DUMPL("b.pData", opData->b.pData, opData->b.dataLenInBytes); \ DUMPL("q.pData", opData->q.pData, opData->q.dataLenInBytes); \ DUMPL("h.pData", opData->h.pData, opData->h.dataLenInBytes); \ fprintf(qatDebugLogFile,"opData: fieldType = %d\n", opData->fieldType);\ fprintf(qatDebugLogFile,"pResultX->dataLenInBytes = %u " \ "pResultX->pData = %p\n", \ pResultX->dataLenInBytes, pResultX->pData); \ fprintf(qatDebugLogFile,"pResultY->dataLenInBytes = %u " \ "pResultY->pData = %p\n", \ pResultY->dataLenInBytes, pResultY->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_EC_GENERIC_POINT_MULTIPLY(instance_handle, pOpData, pResultX, pResultY) \ do { \ fprintf(qatDebugLogFile,"EC Point Multiply Request: %p\n", pOpData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("k.pData", pOpData->k.pData, pOpData->k.dataLenInBytes); \ DUMPL("xP.pData", pOpData->xP.pData, pOpData->xP.dataLenInBytes); \ DUMPL("yP.pData", pOpData->yP.pData, pOpData->yP.dataLenInBytes); \ DUMPL("a.pData", pOpData->pCurve->parameters.weierstrassParameters.a.pData, \ pOpData->pCurve->parameters.weierstrassParameters.a.dataLenInBytes); \ DUMPL("b.pData", pOpData->pCurve->parameters.weierstrassParameters.b.pData, \ pOpData->pCurve->parameters.weierstrassParameters.b.dataLenInBytes); \ DUMPL("q.pData", pOpData->pCurve->parameters.weierstrassParameters.p.pData, \ pOpData->pCurve->parameters.weierstrassParameters.p.dataLenInBytes); \ DUMPL("h.pData", pOpData->pCurve->parameters.weierstrassParameters.h.pData, \ pOpData->pCurve->parameters.weierstrassParameters.a.dataLenInBytes); \ fprintf(qatDebugLogFile,"pOpData: generator = %d\n", pOpData->generator); \ fprintf(qatDebugLogFile,"pResultX->dataLenInBytes = %u " \ "pResultX->pData = %p\n", \ pResultX->dataLenInBytes, pResultX->pData); \ fprintf(qatDebugLogFile,"pResultY->dataLenInBytes = %u " \ "pResultY->pData = %p\n", \ pResultY->dataLenInBytes, pResultY->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_EC_SM2_POINT_MULTIPLY(instance_handle, pOpData, pResultX, pResultY) \ do { \ fprintf(qatDebugLogFile,"EC SM2 Point Multiply Request: %p\n", pOpData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("k.pData", pOpData->k.pData, pOpData->k.dataLenInBytes); \ DUMPL("x.pData", pOpData->x.pData, pOpData->x.dataLenInBytes); \ DUMPL("y.pData", pOpData->y.pData, pOpData->y.dataLenInBytes); \ fprintf(qatDebugLogFile,"pResultX->dataLenInBytes = %u " \ "pResultX->pData = %p\n", \ pResultX->dataLenInBytes, pResultX->pData); \ fprintf(qatDebugLogFile,"pResultY->dataLenInBytes = %u " \ "pResultY->pData = %p\n", \ pResultY->dataLenInBytes, pResultY->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_EC_MONTEDWDS_POINT_MULTIPLY(instance_handle, opData, pXk, pYk) \ do { \ fprintf(qatDebugLogFile,"EC ECX Point Multiply Request: %p\n", opData);\ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("k.pData", opData->k.pData, opData->k.dataLenInBytes); \ DUMPL("x.pData", opData->x.pData, opData->x.dataLenInBytes); \ fprintf(qatDebugLogFile,"opData: curveType = %d\n", opData->curveType);\ fprintf(qatDebugLogFile,"opData: generator = %d\n", opData->generator);\ fprintf(qatDebugLogFile,"pXk->dataLenInBytes = %u " \ "pXk->pData = %p\n", pXk->dataLenInBytes, pXk->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_EC_POINT_MULTIPLY_OUTPUT(bEcStatus, pResultX, pResultY) \ do { \ fprintf(qatDebugLogFile,"EC Point Multiply Output: pResultX %p \n", \ pResultX); \ fprintf(qatDebugLogFile,"bEcStatus = %u\n", bEcStatus); \ DUMPL("pResultX->pData", pResultX->pData, pResultX->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_EC_GENERIC_POINT_MULTIPLY_OUTPUT(bEcStatus, pResultX, pResultY) \ do { \ fprintf(qatDebugLogFile,"EC Point Multiply Output: pResultX %p \n", \ pResultX); \ fprintf(qatDebugLogFile,"bEcStatus = %u\n", bEcStatus); \ DUMPL("pResultX->pData", pResultX->pData, pResultX->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_ECDSA_SIGN(instance_handle, opData, pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"ECDSA Sign Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("xg.pData", opData->xg.pData, opData->xg.dataLenInBytes); \ DUMPL("yg.pData", opData->yg.pData, opData->yg.dataLenInBytes); \ DUMPL("n.pData", opData->n.pData, opData->n.dataLenInBytes); \ DUMPL("q.pData", opData->q.pData, opData->q.dataLenInBytes); \ DUMPL("a.pData", opData->a.pData, opData->a.dataLenInBytes); \ DUMPL("b.pData", opData->b.pData, opData->b.dataLenInBytes); \ DUMPL("k.pData", opData->k.pData, opData->k.dataLenInBytes); \ DUMPL("m.pData", opData->m.pData, opData->m.dataLenInBytes); \ DUMPL("d.pData", opData->d.pData, opData->d.dataLenInBytes); \ fprintf(qatDebugLogFile,"opData: fieldType = %d\n", opData->fieldType);\ fprintf(qatDebugLogFile,"pResultR->dataLenInBytes = %u " \ "pResultR->pData = %p\n", \ pResultR->dataLenInBytes, pResultR->pData); \ fprintf(qatDebugLogFile,"pResultS->dataLenInBytes = %u " \ "pResultS->pData = %p\n", \ pResultS->dataLenInBytes, pResultS->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_ECDSA_SIGN_OUTPUT(bEcdsaSignStatus, pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"ECDSA Sign Output:" \ " pResultR %p, pResultS %p\n", \ pResultR, pResultS); \ fprintf(qatDebugLogFile, "bEcdsaSignStatus = %u\n", bEcdsaSignStatus); \ DUMPL("pResultR->pData", pResultR->pData, pResultR->dataLenInBytes); \ DUMPL("pResultS->pData", pResultS->pData, pResultS->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_ECDSA_VERIFY(instance_handle, opData) \ do { \ fprintf(qatDebugLogFile,"ECDSA Verify Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("xg.pData", opData->xg.pData, opData->xg.dataLenInBytes); \ DUMPL("yg.pData", opData->yg.pData, opData->yg.dataLenInBytes); \ DUMPL("n.pData", opData->n.pData, opData->n.dataLenInBytes); \ DUMPL("q.pData", opData->q.pData, opData->q.dataLenInBytes); \ DUMPL("a.pData", opData->a.pData, opData->a.dataLenInBytes); \ DUMPL("b.pData", opData->b.pData, opData->b.dataLenInBytes); \ DUMPL("m.pData", opData->m.pData, opData->m.dataLenInBytes); \ DUMPL("r.pData", opData->r.pData, opData->r.dataLenInBytes); \ DUMPL("s.pData", opData->s.pData, opData->s.dataLenInBytes); \ DUMPL("xp.pData", opData->xp.pData, opData->xp.dataLenInBytes); \ DUMPL("yp.pData", opData->yp.pData, opData->yp.dataLenInBytes); \ fprintf(qatDebugLogFile,"opData: fieldType = %d\n", opData->fieldType);\ fflush(qatDebugLogFile); \ } while (0) # define DUMP_DSA_SIGN(instance_handle, op_done, opData, bDsaSignStatus, \ pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"DSA Sign Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"op_done = %p\n", op_done); \ DUMPL("P.pData", opData->P.pData, opData->P.dataLenInBytes); \ DUMPL("Q.pData", opData->Q.pData, opData->Q.dataLenInBytes); \ DUMPL("G.pData", opData->G.pData, opData->G.dataLenInBytes); \ DUMPL("X.pData", opData->X.pData, opData->X.dataLenInBytes); \ DUMPL("K.pData", opData->K.pData, opData->K.dataLenInBytes); \ DUMPL("Z.pData", opData->Z.pData, opData->Z.dataLenInBytes); \ fprintf(qatDebugLogFile,"bDsaSignStatus = %p\n", bDsaSignStatus); \ fprintf(qatDebugLogFile,"pResultR->dataLenInBytes = %u\n", \ pResultR->dataLenInBytes); \ fprintf(qatDebugLogFile,"pResultR->pData = %p\n", pResultR->pData); \ fprintf(qatDebugLogFile,"pResultS->dataLenInBytes = %u\n", \ pResultS->dataLenInBytes); \ fprintf(qatDebugLogFile,"pResultS->pData = %p\n", pResultS->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_DSA_SIGN_OUTPUT(bDsaSignStatus, pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"DSA Sign Output: pResultR %p, pResultS %p\n",\ pResultR, pResultS); \ fprintf(qatDebugLogFile,"bDsaSignStatus = %u\n", bDsaSignStatus); \ DUMPL("pResultR->pData", pResultR->pData, pResultR->dataLenInBytes); \ DUMPL("pResultS->pData", pResultS->pData, pResultS->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_DSA_VERIFY(instance_handle, op_done, opData, bDsaVerifyStatus) \ do { \ fprintf(qatDebugLogFile,"DSA Verify Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"op_done = %p\n", op_done); \ DUMPL("P.pData", opData->P.pData, opData->P.dataLenInBytes); \ DUMPL("Q.pData", opData->Q.pData, opData->Q.dataLenInBytes); \ DUMPL("G.pData", opData->G.pData, opData->G.dataLenInBytes); \ DUMPL("Y.pData", opData->Y.pData, opData->Y.dataLenInBytes); \ DUMPL("Z.pData", opData->Z.pData, opData->Z.dataLenInBytes); \ DUMPL("R.pData", opData->R.pData, opData->R.dataLenInBytes); \ DUMPL("S.pData", opData->S.pData, opData->S.dataLenInBytes); \ fprintf(qatDebugLogFile,"bDsaVerifyStatus = %p\n", bDsaVerifyStatus); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_RSA_ENCRYPT(instance_handle, op_done, opData, output_buf) \ do { \ fprintf(qatDebugLogFile,"RSA Encrypt Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"op_done = %p\n", op_done); \ DUMPL("opData->pPublicKey->modulusN.pData", \ opData->pPublicKey->modulusN.pData, \ opData->pPublicKey->modulusN.dataLenInBytes); \ DUMPL("opData->pPublicKey->publicExponentE.pData", \ opData->pPublicKey->publicExponentE.pData, \ opData->pPublicKey->publicExponentE.dataLenInBytes); \ DUMPL("opData->inputData.pData", opData->inputData.pData, \ opData->inputData.dataLenInBytes); \ fprintf(qatDebugLogFile,"output_buf = %p\n", output_buf); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_RSA_ENCRYPT_OUTPUT(output_buf) \ do { \ fprintf(qatDebugLogFile,"RSA Encrypt Output: %p\n", output_buf); \ DUMPL("output_buf", output_buf->pData, output_buf->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_RSA_DECRYPT(instance_handle, op_done, opData, output_buf) \ do { \ fprintf(qatDebugLogFile,"RSA Decrypt Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"op_done = %p\n", op_done); \ fprintf(qatDebugLogFile,"opData: pRecipientPrivateKey->version = %d\n",\ opData->pRecipientPrivateKey->version); \ fprintf(qatDebugLogFile,"opData: pRecipientPrivateKey" \ "->privateKeyRepType = %d\n", \ opData->pRecipientPrivateKey->privateKeyRepType); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep1.modulusN.pData", \ opData->pRecipientPrivateKey->privateKeyRep1.modulusN.pData, \ opData->pRecipientPrivateKey->privateKeyRep1.modulusN. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep1.privateExponentD." \ "pData", opData->pRecipientPrivateKey->privateKeyRep1. \ privateExponentD.pData, opData->pRecipientPrivateKey-> \ privateKeyRep1.privateExponentD.dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.prime1P.pData", \ opData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData, \ opData->pRecipientPrivateKey->privateKeyRep2.prime1P. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.prime2Q.pData", \ opData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData, \ opData->pRecipientPrivateKey->privateKeyRep2.prime2Q. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.exponent1Dp." \ "pData", \ opData->pRecipientPrivateKey->privateKeyRep2.exponent1Dp.pData, \ opData->pRecipientPrivateKey->privateKeyRep2.exponent1Dp. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.exponent2Dq." \ "pData", \ opData->pRecipientPrivateKey->privateKeyRep2.exponent2Dq.pData, \ opData->pRecipientPrivateKey->privateKeyRep2.exponent2Dq. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.coefficientQInv." \ "pData", \ opData->pRecipientPrivateKey->privateKeyRep2.coefficientQInv. \ pData, opData->pRecipientPrivateKey->privateKeyRep2. \ coefficientQInv.dataLenInBytes); \ DUMPL("opData: inputData.pData", opData->inputData.pData, \ opData->inputData.dataLenInBytes); \ fprintf(qatDebugLogFile,"output_buf = %p\n", output_buf); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_RSA_DECRYPT_OUTPUT(output_buf) \ do { \ fprintf(qatDebugLogFile,"RSA Decrypt Output: %p\n", output_buf); \ DUMPL("output_buf", output_buf->pData, output_buf->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_KEYGEN_TLS(instance_handle, generated_key) \ do { \ fprintf(qatDebugLogFile,"TLS Keygen Request: \n"); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("generated_key->pData", generated_key->pData, \ generated_key->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_KEYGEN_TLS_OUTPUT(generated_key) \ do { \ fprintf(qatDebugLogFile,"TLS Keygen Output: %p\n", generated_key); \ DUMPL("generated_key->pData", generated_key->pData, \ generated_key->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SESSION_SETUP_DATA(ssd) \ do { \ fprintf(qatDebugLogFile,"Symmetric crypto session setup data: %p\n", \ ssd); \ DUMPL("Cipher Key", ssd->cipherSetupData.pCipherKey, \ ssd->cipherSetupData.cipherKeyLenInBytes); \ if (ssd->symOperation != CPA_CY_SYM_OP_CIPHER) { \ DUMPL("MAC Key", ssd->hashSetupData.authModeSetupData.authKey, \ ssd->hashSetupData. \ authModeSetupData.authKeyLenInBytes); \ } \ fprintf(qatDebugLogFile,"ssd->sessionPriority = %d\n", \ ssd->sessionPriority); \ fprintf(qatDebugLogFile,"ssd->symOperation = %d\n", \ ssd->symOperation); \ fprintf(qatDebugLogFile,"ssd->cipherSetupData.cipherAlgorithm = %d\n", \ ssd->cipherSetupData.cipherAlgorithm); \ fprintf(qatDebugLogFile,"ssd->cipherSetupData.cipherKeyLenInBytes " \ "= %u\n", ssd->cipherSetupData.cipherKeyLenInBytes); \ fprintf(qatDebugLogFile,"ssd->cipherSetupData.pCipherKey = %p\n", \ ssd->cipherSetupData.pCipherKey); \ fprintf(qatDebugLogFile,"ssd->cipherSetupData.cipherDirection = %d\n", \ ssd->cipherSetupData.cipherDirection); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.hashAlgorithm = %d\n", \ ssd->hashSetupData.hashAlgorithm); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.hashMode = %d\n", \ ssd->hashSetupData.hashMode); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.digestResultLenInBytes " \ "= %u\n", ssd->hashSetupData.digestResultLenInBytes); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.authModeSetupData.authKey "\ "= %p\n", ssd->hashSetupData.authModeSetupData.authKey); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.authModeSetupData" \ ".authKeyLenInBytes = %u\n", \ ssd->hashSetupData.authModeSetupData.authKeyLenInBytes); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.authModeSetupData" \ ".aadLenInBytes = %u\n", \ ssd->hashSetupData.authModeSetupData.aadLenInBytes); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.nestedModeSetupData" \ ".pInnerPrefixData = %p\n", \ ssd->hashSetupData.nestedModeSetupData.pInnerPrefixData); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.nestedModeSetupData" \ ".innerPrefixLenInBytes= %u\n", \ ssd->hashSetupData.nestedModeSetupData.innerPrefixLenInBytes); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.nestedModeSetupData." \ "outerHashAlgorithm = %d\n", ssd->hashSetupData. \ nestedModeSetupData.outerHashAlgorithm); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.nestedModeSetupData" \ ".pOuterPrefixData = %p\n", \ ssd->hashSetupData.nestedModeSetupData.pOuterPrefixData); \ fprintf(qatDebugLogFile,"ssd->hashSetupData.nestedModeSetupData" \ ".outerPrefixLenInBytes= %u\n", \ ssd->hashSetupData.nestedModeSetupData.outerPrefixLenInBytes); \ fprintf(qatDebugLogFile,"ssd->algChainOrder = %d\n", \ ssd->algChainOrder); \ fprintf(qatDebugLogFile,"ssd->digestIsAppended = %d\n", \ ssd->digestIsAppended); \ fprintf(qatDebugLogFile,"ssd->verifyDigest = %d\n", \ ssd->verifyDigest); \ fprintf(qatDebugLogFile,"ssd->partialsNotRequired = %d\n", \ ssd->partialsNotRequired); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SYM_PERFORM_OP(instance_handle, pOpData, pSrcBuffer, \ pDstBuffer) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"Symmetric crypto perform op req: %p\n", \ pOpData); \ fprintf(qatDebugLogFile,"Instance Handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"pOpData->packetType = %d\n", \ pOpData->packetType); \ DUMPL("Cipher IV", pOpData->pIv, pOpData->ivLenInBytes); \ fprintf(qatDebugLogFile,"pOpData->cryptoStartSrcOffsetInBytes = %u\n", \ pOpData->cryptoStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData->messageLenToCipherInBytes = %u\n", \ pOpData->messageLenToCipherInBytes); \ fprintf(qatDebugLogFile,"pOpData->hashStartSrcOffsetInBytes = %u\n", \ pOpData->hashStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData->messageLenToHashInBytes = %u\n", \ pOpData->messageLenToHashInBytes); \ fprintf(qatDebugLogFile,"pOpData->pDigestResult = %p\n", \ pOpData->pDigestResult); \ for (index = 0; index < pSrcBuffer->numBuffers; index++) { \ DUMPL("pSrcBuffer->pBuffers[%u].pData", \ pSrcBuffer->pBuffers[index].pData, \ pSrcBuffer->pBuffers[index].dataLenInBytes); \ } \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SYM_PERFORM_OP_OUTPUT(pVerifyResult, pDstBuffer) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"Symmetric crypto perform op Output: %p\n", \ pDstBuffer); \ fprintf(qatDebugLogFile,"pVerifyResult = %d\n", *pVerifyResult); \ for (index = 0; index < pDstBuffer->numBuffers; index++) { \ DUMPL("pDstBuffer->pBuffers[%u].pData", \ pDstBuffer->pBuffers[index].pData, \ pDstBuffer->pBuffers[index].dataLenInBytes); \ } \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SYM_PERFORM_OP_GCM_CCM(instance_handle, pOpData, pSrcBuffer, \ pDstBuffer) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"Symmetric crypto perform op req: %p\n", \ &pOpData); \ fprintf(qatDebugLogFile,"Instance Handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"pOpData.packetType = %d\n", \ pOpData.packetType); \ DUMPL("Cipher IV", pOpData.pIv, pOpData.ivLenInBytes); \ fprintf(qatDebugLogFile,"pOpData.cryptoStartSrcOffsetInBytes = %u\n", \ pOpData.cryptoStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData.messageLenToCipherInBytes = %u\n", \ pOpData.messageLenToCipherInBytes); \ fprintf(qatDebugLogFile,"pOpData.hashStartSrcOffsetInBytes = %u\n", \ pOpData.hashStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData.messageLenToHashInBytes = %u\n", \ pOpData.messageLenToHashInBytes); \ fprintf(qatDebugLogFile,"pOpData.pDigestResult = %p\n", \ pOpData.pDigestResult); \ for (index = 0; index < pSrcBuffer.numBuffers; index++) { \ DUMPL("pSrcBuffer.pBuffers[%u].pData", \ pSrcBuffer.pBuffers[index].pData, \ pSrcBuffer.pBuffers[index].dataLenInBytes); \ } \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(pDstBuffer) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"Symmetric crypto perform op Output: %p\n", \ &pDstBuffer); \ for (index = 0; index < pDstBuffer.numBuffers; index++) { \ DUMPL("pDstBuffer.pBuffers[%u].pData", \ pDstBuffer.pBuffers[index].pData, \ pDstBuffer.pBuffers[index].dataLenInBytes); \ } \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_PRF_OP_DATA(prfOpData) \ do { \ fprintf(qatDebugLogFile,"PRF Op Data: %p\n", &prfOpData); \ if (prfOpData.tlsOp == \ CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE) \ fprintf(qatDebugLogFile,"tlsOp: MASTER_SECRET_DERIVE\n"); \ else if (prfOpData.tlsOp == \ CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE) \ fprintf(qatDebugLogFile,"tlsOp: KEY_MATERIAL_DERIVE\n"); \ else if (prfOpData.tlsOp == \ CPA_CY_KEY_TLS_OP_CLIENT_FINISHED_DERIVE) \ fprintf(qatDebugLogFile,"tlsOp: CLIENT_FINISHED_DERIVE\n"); \ else if (prfOpData.tlsOp == \ CPA_CY_KEY_TLS_OP_SERVER_FINISHED_DERIVE) \ fprintf(qatDebugLogFile,"tlsOp: SERVER_FINISHED_DERIVE\n"); \ else if (prfOpData.tlsOp == \ CPA_CY_KEY_TLS_OP_USER_DEFINED) \ fprintf(qatDebugLogFile,"tlsOp: USER_DEFINED:\n"); \ DUMPL("Secret", prfOpData.secret.pData, \ prfOpData.secret.dataLenInBytes); \ DUMPL("Seed", prfOpData.seed.pData, \ prfOpData.seed.dataLenInBytes); \ DUMPL("User Label", prfOpData.userLabel.pData, \ prfOpData.userLabel.dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_HKDF_OP_DATA(hkdfOpData) \ do { \ fprintf(qatDebugLogFile,"HKDF Op Data: %p\n", &hkdfOpData); \ if (hkdfOpData->hkdfKeyOp == CPA_CY_HKDF_KEY_EXTRACT_EXPAND) \ fprintf(qatDebugLogFile,"hkdfOp: HKDF_EXTRACT_AND_EXPAND \n"); \ if (hkdfOpData->hkdfKeyOp == CPA_CY_HKDF_KEY_EXTRACT) \ fprintf(qatDebugLogFile,"hkdfOp: HKDF_EXTRACT \n"); \ if (hkdfOpData->hkdfKeyOp == CPA_CY_HKDF_KEY_EXPAND) \ fprintf(qatDebugLogFile,"hkdfOp: HKDF_EXPAND \n"); \ DUMPL("Secret", hkdfOpData->secret, hkdfOpData->secretLen); \ DUMPL("Seed", hkdfOpData->seed, hkdfOpData->seedLen); \ DUMPL("Info", hkdfOpData->info , hkdfOpData->infoLen); \ } while (0) # define DUMP_SYM_PERFORM_OP_SHA3(instance_handle, pOpData, pSrcBuffer, \ pDstBuffer) \ do { \ fprintf(qatDebugLogFile,"Symmetric SHA3 hash perform op req: %p\n", \ &pOpData); \ fprintf(qatDebugLogFile,"Instance Handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"pOpData.packetType = %d\n", \ pOpData->packetType); \ fprintf(qatDebugLogFile,"pOpData.cryptoStartSrcOffsetInBytes = %u\n", \ pOpData->cryptoStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData.messageLenToCipherInBytes = %u\n", \ pOpData->messageLenToCipherInBytes); \ fprintf(qatDebugLogFile,"pOpData.hashStartSrcOffsetInBytes = %u\n", \ pOpData->hashStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData.messageLenToHashInBytes = %u\n", \ pOpData->messageLenToHashInBytes); \ fprintf(qatDebugLogFile,"pOpData.pDigestResult = %p\n", \ pOpData->pDigestResult); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_CP_PERFORM_OP(instance_handle, pOpData, pSrcBuffer, \ pDstBuffer) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"Symmetric crypto perform op req: %p\n", \ pOpData); \ fprintf(qatDebugLogFile,"Instance Handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"pOpData->packetType = %d\n", \ pOpData->packetType); \ DUMPL("Cipher IV", pOpData->pIv, pOpData->ivLenInBytes); \ fprintf(qatDebugLogFile,"pOpData->cryptoStartSrcOffsetInBytes = %u\n", \ pOpData->cryptoStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData->messageLenToCipherInBytes = %u\n", \ pOpData->messageLenToCipherInBytes); \ fprintf(qatDebugLogFile,"pOpData->hashStartSrcOffsetInBytes = %u\n", \ pOpData->hashStartSrcOffsetInBytes); \ fprintf(qatDebugLogFile,"pOpData->messageLenToHashInBytes = %u\n", \ pOpData->messageLenToHashInBytes); \ fprintf(qatDebugLogFile,"pOpData->pDigestResult = %p\n", \ pOpData->pDigestResult); \ for (index = 0; index < pSrcBuffer.numBuffers; index++) { \ DUMPL("pSrcBuffer->pBuffers[%u].pData", \ pSrcBuffer.pBuffers[index].pData, \ pSrcBuffer.pBuffers[index].dataLenInBytes); \ } \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SYM_PERFORM_OP_SHA3_OUTPUT(pOpData, pDstBuffer) \ do { \ fprintf(qatDebugLogFile,"Symmetric SHA3 hash perform op Output: %p\n", \ &pDstBuffer); \ fprintf(qatDebugLogFile,"pOpData->pDigestResult = %p\n", \ pOpData->pDigestResult); \ DUMPL("pOpData->pDigestResult", \ pOpData->pDigestResult, \ pOpData->messageLenToHashInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_CP_PERFORM_OP_OUTPUT(pVerifyResult, pDstBuffer) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"Symmetric crypto perform op Output:\n"); \ fprintf(qatDebugLogFile,"pVerifyResult = %d\n", *pVerifyResult); \ for (index = 0; index < pDstBuffer.numBuffers; index++) { \ DUMPL("pDstBuffer->pBuffers[%u].pData", \ pDstBuffer.pBuffers[index].pData, \ pDstBuffer.pBuffers[index].dataLenInBytes); \ } \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_INSTANCE_MAPPING(title, map_instance, num_instances) \ do { \ unsigned int index = 0; \ fprintf(qatDebugLogFile,"%s: ", title); \ \ for (index = 0; index < num_instances; index++) { \ fprintf(qatDebugLogFile, "%d ", map_instance[index]); \ } \ fprintf(qatDebugLogFile, "\n"); \ fflush(qatDebugLogFile); \ } while (0) # ifdef ENABLE_QAT_HW_KPT # define DUMP_KPT_WRAPPING_DATA(eswk, len_eswk, sig, len_sig, iv, len_iv, \ aad, len_aad) \ do { \ fprintf(qatDebugLogFile,"KPT Wrapping Metadata\n"); \ DUMPL("ESWK", eswk, len_eswk); \ DUMPL("Signature", sig, len_sig); \ DUMPL("IV", iv, len_iv); \ DUMPL("AAD", aad, len_aad); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_KPT_RSA_DECRYPT(instance_handle, kpt_handle, \ op_done, opData, output_buf) \ do { \ fprintf(qatDebugLogFile,"RSA Decrypt Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ fprintf(qatDebugLogFile,"KPT handle = 0x%lx\n", kpt_handle); \ fprintf(qatDebugLogFile,"op_done = %p\n", op_done); \ fprintf(qatDebugLogFile,"opData: pRecipientPrivateKey->version = %d\n",\ opData->pRecipientPrivateKey->version); \ fprintf(qatDebugLogFile,"opData: pRecipientPrivateKey" \ "->privateKeyRepType = %d\n", \ opData->pRecipientPrivateKey->privateKeyRepType); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep1.privateKey.pData", \ opData->pRecipientPrivateKey->privateKeyRep1.privateKey.pData, \ opData->pRecipientPrivateKey->privateKeyRep1.privateKey. \ dataLenInBytes); \ DUMPL("opData: pRecipientPrivateKey->privateKeyRep2.privateKey.pData", \ opData->pRecipientPrivateKey->privateKeyRep2.privateKey.pData, \ opData->pRecipientPrivateKey->privateKeyRep2.privateKey. \ dataLenInBytes); \ DUMPL("opData: inputData.pData", opData->inputData.pData, \ opData->inputData.dataLenInBytes); \ fprintf(qatDebugLogFile,"output_buf = %p\n", output_buf); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_KPT_ECDSA_SIGN(instance_handle, kpt_handle, \ opData, pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"KPT ECDSA Sign Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle ptr = %p\n", instance_handle);\ fprintf(qatDebugLogFile,"KPT handle = 0x%lx\n", kpt_handle); \ DUMPL("m.pData", opData->m.pData, opData->m.dataLenInBytes); \ DUMPL("WPK data", opData->privateKey.pData, \ opData->privateKey.dataLenInBytes); \ fprintf(qatDebugLogFile,"pResultR->dataLenInBytes = %u " \ "pResultR->pData = %p\n", \ pResultR->dataLenInBytes, pResultR->pData); \ fprintf(qatDebugLogFile,"pResultS->dataLenInBytes = %u " \ "pResultS->pData = %p\n", \ pResultS->dataLenInBytes, pResultS->pData); \ fflush(qatDebugLogFile); \ } while (0) # endif # define DUMP_SM2_SIGN(instance_handle, opData, pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"SM2 Sign Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("k.pData", opData->k.pData, opData->k.dataLenInBytes); \ DUMPL("e.pData", opData->e.pData, opData->e.dataLenInBytes); \ DUMPL("d.pData", opData->d.pData, opData->d.dataLenInBytes); \ fprintf(qatDebugLogFile,"opData: fieldType = %d\n", opData->fieldType);\ fprintf(qatDebugLogFile,"pResultR->dataLenInBytes = %u " \ "pResultR->pData = %p\n", \ pResultR->dataLenInBytes, pResultR->pData); \ fprintf(qatDebugLogFile,"pResultS->dataLenInBytes = %u " \ "pResultS->pData = %p\n", \ pResultS->dataLenInBytes, pResultS->pData); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SM2_SIGN_OUTPUT(bSM2SignStatus, pResultR, pResultS) \ do { \ fprintf(qatDebugLogFile,"SM2 Sign Output:" \ " pResultR %p, pResultS %p\n", \ pResultR, pResultS); \ fprintf(qatDebugLogFile, "bSM2SignStatus = %u\n", bSM2SignStatus); \ DUMPL("pResultR->pData", pResultR->pData, pResultR->dataLenInBytes); \ DUMPL("pResultS->pData", pResultS->pData, pResultS->dataLenInBytes); \ fflush(qatDebugLogFile); \ } while (0) # define DUMP_SM2_VERIFY(instance_handle, opData) \ do { \ fprintf(qatDebugLogFile,"SM2 Verify Request: %p\n", opData); \ fprintf(qatDebugLogFile,"instance_handle = %p\n", instance_handle); \ DUMPL("e.pData", opData->e.pData, opData->e.dataLenInBytes); \ DUMPL("r.pData", opData->r.pData, opData->r.dataLenInBytes); \ DUMPL("s.pData", opData->s.pData, opData->s.dataLenInBytes); \ DUMPL("xP.pData", opData->xP.pData, opData->xP.dataLenInBytes); \ DUMPL("yP.pData", opData->yP.pData, opData->yP.dataLenInBytes); \ fprintf(qatDebugLogFile,"opData: fieldType = %d\n", opData->fieldType);\ fflush(qatDebugLogFile); \ } while (0) # else # ifdef ENABLE_QAT_HW_KPT # define DUMP_KPT_WRAPPING_DATA(...) # define DUMP_KPT_RSA_DECRYPT(...) # define DUMP_KPT_ECDSA_SIGN(...) # endif # define DUMP_DH_GEN_PHASE1(...) # define DUMP_DH_GEN_PHASE2(...) # define DUMP_DH_GEN_PHASE1_OUTPUT(...) # define DUMP_DH_GEN_PHASE2_OUTPUT(...) # define DUMP_EC_POINT_MULTIPLY(...) # define DUMP_EC_GENERIC_POINT_MULTIPLY(...) # define DUMP_EC_MONTEDWDS_POINT_MULTIPLY(...) # define DUMP_EC_POINT_MULTIPLY_OUTPUT(...) # define DUMP_EC_GENERIC_POINT_MULTIPLY_OUTPUT(...) # define DUMP_EC_SM2_POINT_MULTIPLY(...) # define DUMP_ECDSA_SIGN(...) # define DUMP_ECDSA_SIGN_OUTPUT(...) # define DUMP_ECDSA_VERIFY(...) # define DUMP_DSA_SIGN(...) # define DUMP_DSA_SIGN_OUTPUT(...) # define DUMP_DSA_VERIFY(...) # define DUMP_RSA_ENCRYPT(...) # define DUMP_RSA_ENCRYPT_OUTPUT(...) # define DUMP_RSA_DECRYPT(...) # define DUMP_RSA_DECRYPT_OUTPUT(...) # define DUMP_KEYGEN_TLS(...) # define DUMP_KEYGEN_TLS_OUTPUT(...) # define DUMP_SESSION_SETUP_DATA(...) # define DUMP_SYM_PERFORM_OP(...) # define DUMP_SYM_PERFORM_OP_OUTPUT(...) # define DUMP_SYM_PERFORM_OP_GCM_CCM(...) # define DUMP_SYM_PERFORM_OP_GCM_CCM_OUTPUT(...) # define DUMP_PRF_OP_DATA(...) # define DUMP_HKDF_OP_DATA(...) # define DUMP_SYM_PERFORM_OP_SHA3(...) # define DUMP_SYM_PERFORM_OP_SHA3_OUTPUT(...) # define DUMP_CP_PERFORM_OP(...) # define DUMP_CP_PERFORM_OP_OUTPUT(...) # define DUMP_INSTANCE_MAPPING(...) # define DUMP_SM2_SIGN(...) # define DUMP_SM2_SIGN_OUTPUT(...) # define DUMP_SM2_VERIFY(...) # endif /* QAT_DEBUG */ # ifdef QAT_CPU_CYCLES_COUNT # define GCC_ALWAYS_INLINE static __attribute__((always_inline)) inline typedef struct rdtsc_prof { volatile uint64_t clk_start; volatile uint64_t clk_avgc; /* count to calculate an average */ volatile double clk_avg; /* cumulative sum to calculate an average */ volatile double clk_diff_cost_adjusted; volatile double cost; volatile uint32_t bytes; volatile int started; } rdtsc_prof_t; extern rdtsc_prof_t rsa_cycles_priv_enc_setup; extern rdtsc_prof_t rsa_cycles_priv_dec_setup; extern rdtsc_prof_t rsa_cycles_priv_execute; extern rdtsc_prof_t rsa_cycles_pub_enc_setup; extern rdtsc_prof_t rsa_cycles_pub_dec_setup; extern rdtsc_prof_t rsa_cycles_pub_execute; extern rdtsc_prof_t x25519_cycles_keygen_setup; extern rdtsc_prof_t x25519_cycles_keygen_execute; extern rdtsc_prof_t x25519_cycles_derive_setup; extern rdtsc_prof_t x25519_cycles_derive_execute; extern rdtsc_prof_t ecdsa_cycles_sign_setup; extern rdtsc_prof_t ecdsa_cycles_sign_execute; extern rdtsc_prof_t ecdsa_cycles_sign_setup_setup; extern rdtsc_prof_t ecdsa_cycles_sign_setup_execute; extern rdtsc_prof_t ecdsa_cycles_sign_sig_setup; extern rdtsc_prof_t ecdsa_cycles_sign_sig_execute; extern rdtsc_prof_t ecdh_cycles_keygen_setup; extern rdtsc_prof_t ecdh_cycles_keygen_execute; extern rdtsc_prof_t ecdh_cycles_compute_setup; extern rdtsc_prof_t ecdh_cycles_compute_execute; extern rdtsc_prof_t sm2ecdh_cycles_keygen_setup; extern rdtsc_prof_t sm2ecdh_cycles_keygen_execute; extern rdtsc_prof_t sm2ecdh_cycles_compute_setup; extern rdtsc_prof_t sm2ecdh_cycles_compute_execute; extern rdtsc_prof_t sm3_cycles_init_setup; extern rdtsc_prof_t sm3_cycles_init_execute; extern rdtsc_prof_t sm3_cycles_update_setup; extern rdtsc_prof_t sm3_cycles_update_execute; extern rdtsc_prof_t sm3_cycles_final_setup; extern rdtsc_prof_t sm3_cycles_final_execute; extern rdtsc_prof_t ecdsa_cycles_verify_setup; extern rdtsc_prof_t ecdsa_cycles_verify_execute; extern rdtsc_prof_t sm4_gcm_cycles_init_setup; extern rdtsc_prof_t sm4_gcm_cycles_init_execute; extern rdtsc_prof_t sm4_gcm_cycles_encrypt_setup; extern rdtsc_prof_t sm4_gcm_cycles_encrypt_execute; extern rdtsc_prof_t sm4_gcm_cycles_decrypt_setup; extern rdtsc_prof_t sm4_gcm_cycles_decrypt_execute; extern rdtsc_prof_t sm4_gcm_cycles_get_tag_setup; extern rdtsc_prof_t sm4_gcm_cycles_get_tag_execute; extern rdtsc_prof_t sm4_gcm_cycles_update_iv_setup; extern rdtsc_prof_t sm4_gcm_cycles_update_iv_execute; extern rdtsc_prof_t sm4_gcm_cycles_update_aad_setup; extern rdtsc_prof_t sm4_gcm_cycles_update_aad_execute; extern rdtsc_prof_t sm4_gcm_cycles_cipher_setup; extern rdtsc_prof_t sm4_gcm_cycles_cipher_execute; extern rdtsc_prof_t sm4_gcm_cycles_ctrl_setup; extern rdtsc_prof_t sm4_gcm_cycles_ctrl_execute; extern rdtsc_prof_t sm4_gcm_cycles_cleanup_setup; extern rdtsc_prof_t sm4_gcm_cycles_cleanup_execute; extern rdtsc_prof_t sm4_ccm_cycles_init_setup; extern rdtsc_prof_t sm4_ccm_cycles_init_execute; extern rdtsc_prof_t sm4_ccm_cycles_encrypt_setup; extern rdtsc_prof_t sm4_ccm_cycles_encrypt_execute; extern rdtsc_prof_t sm4_ccm_cycles_decrypt_setup; extern rdtsc_prof_t sm4_ccm_cycles_decrypt_execute; extern rdtsc_prof_t sm4_ccm_cycles_ctrl_setup; extern rdtsc_prof_t sm4_ccm_cycles_ctrl_execute; extern rdtsc_prof_t sm4_ccm_cycles_cleanup_setup; extern rdtsc_prof_t sm4_ccm_cycles_cleanup_execute; extern rdtsc_prof_t sm4_ccm_cycles_get_tag_setup; extern rdtsc_prof_t sm4_ccm_cycles_get_tag_execute; extern rdtsc_prof_t sm4_ccm_cycles_update_aad_setup; extern rdtsc_prof_t sm4_ccm_cycles_update_aad_execute; extern rdtsc_prof_t qat_hw_rsa_dec_req_prepare; extern rdtsc_prof_t qat_hw_rsa_dec_req_submit; extern rdtsc_prof_t qat_hw_rsa_dec_req_retry; extern rdtsc_prof_t qat_hw_rsa_dec_req_cleanup; extern rdtsc_prof_t qat_hw_ecdsa_sign_req_prepare; extern rdtsc_prof_t qat_hw_ecdsa_sign_req_submit; extern rdtsc_prof_t qat_hw_ecdsa_sign_req_retry; extern rdtsc_prof_t qat_hw_ecdsa_sign_req_cleanup; extern rdtsc_prof_t qat_hw_ecdh_derive_req_prepare; extern rdtsc_prof_t qat_hw_ecdh_derive_req_submit; extern rdtsc_prof_t qat_hw_ecdh_derive_req_retry; extern rdtsc_prof_t qat_hw_ecdh_derive_req_cleanup; extern rdtsc_prof_t qat_hw_ecx_derive_req_prepare; extern rdtsc_prof_t qat_hw_ecx_derive_req_submit; extern rdtsc_prof_t qat_hw_ecx_derive_req_retry; extern rdtsc_prof_t qat_hw_ecx_derive_req_cleanup; extern int print_cycle_count; /** * * LFENCE used to serialize code execution (no OOO) * * Load buffers get are empty after lfence, no deliberate restrictions put on store buffers * */ GCC_ALWAYS_INLINE uint64_t rdtsc_start(void) { uint32_t cycles_high; uint32_t cycles_low; asm volatile ("lfence\n\t" "rdtscp\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t":"=r" (cycles_high), "=r"(cycles_low) ::"%rax", "%rdx", "%rcx"); return (((uint64_t)cycles_high << 32) | cycles_low); } GCC_ALWAYS_INLINE uint64_t rdtsc_end(void) { uint32_t cycles_high; uint32_t cycles_low; asm volatile ("rdtscp\n\t" "mov %%edx, %0\n\t" "mov %%eax, %1\n\t" "lfence\n\t":"=r" (cycles_high), "=r"(cycles_low) ::"%rax", "%rdx", "%rcx"); return (((uint64_t)cycles_high << 32) | cycles_low); } GCC_ALWAYS_INLINE void rdtsc_prof_start(rdtsc_prof_t * p) { p->started = 1; p->clk_start = rdtsc_start(); } GCC_ALWAYS_INLINE void rdtsc_prof_end(rdtsc_prof_t * p, const unsigned inc, char *name) { if (p->started) { /* int64_t not uint64_t because it may happen that * for low cost operations, measured time is less than * the subtracted average cost of measurement */ volatile double clk_diff = (double)(rdtsc_end() - p->clk_start); p->clk_avgc += inc; # ifdef QAT_CPU_CYCLE_MEASUREMENT_COST p->clk_avg += (clk_diff - p->cost); p->clk_diff_cost_adjusted += (clk_diff - p->cost); # else p->clk_avg += clk_diff; p->clk_diff_cost_adjusted += clk_diff; # endif p->started = 0; if (inc != 0) { if (print_cycle_count) fprintf(qatDebugLogFile, "%s - cycles taken = %.1f\n", name, p->clk_diff_cost_adjusted); p->clk_diff_cost_adjusted = 0.0; } } } void rdtsc_initialize(void); void rdtsc_prof_init(rdtsc_prof_t * p, const uint32_t bytes); void rdtsc_prof_print(rdtsc_prof_t * p, char *name); # define INITIALISE_RDTSC_CLOCKS() \ do { \ rdtsc_initialize(); \ rdtsc_prof_init(&rsa_cycles_priv_enc_setup, 0); \ rdtsc_prof_init(&rsa_cycles_priv_dec_setup, 0); \ rdtsc_prof_init(&rsa_cycles_priv_execute, 0); \ rdtsc_prof_init(&rsa_cycles_pub_enc_setup, 0); \ rdtsc_prof_init(&rsa_cycles_pub_dec_setup, 0); \ rdtsc_prof_init(&rsa_cycles_pub_execute, 0); \ rdtsc_prof_init(&x25519_cycles_keygen_setup, 0); \ rdtsc_prof_init(&x25519_cycles_keygen_execute, 0); \ rdtsc_prof_init(&x25519_cycles_derive_setup, 0); \ rdtsc_prof_init(&x25519_cycles_derive_execute, 0); \ rdtsc_prof_init(&ecdsa_cycles_sign_setup, 0); \ rdtsc_prof_init(&ecdsa_cycles_sign_execute, 0); \ rdtsc_prof_init(&ecdsa_cycles_sign_setup_setup, 0); \ rdtsc_prof_init(&ecdsa_cycles_sign_setup_execute, 0); \ rdtsc_prof_init(&ecdsa_cycles_sign_sig_setup, 0); \ rdtsc_prof_init(&ecdsa_cycles_sign_sig_execute, 0); \ rdtsc_prof_init(&ecdh_cycles_keygen_setup, 0); \ rdtsc_prof_init(&ecdh_cycles_keygen_execute, 0); \ rdtsc_prof_init(&ecdh_cycles_compute_setup, 0); \ rdtsc_prof_init(&ecdh_cycles_compute_execute, 0); \ rdtsc_prof_init(&sm2ecdh_cycles_keygen_setup, 0); \ rdtsc_prof_init(&sm2ecdh_cycles_keygen_execute, 0); \ rdtsc_prof_init(&sm2ecdh_cycles_compute_setup, 0); \ rdtsc_prof_init(&sm2ecdh_cycles_compute_execute, 0); \ rdtsc_prof_init(&sm3_cycles_init_setup, 0); \ rdtsc_prof_init(&sm3_cycles_init_execute, 0); \ rdtsc_prof_init(&sm3_cycles_update_setup, 0); \ rdtsc_prof_init(&sm3_cycles_update_execute, 0); \ rdtsc_prof_init(&sm3_cycles_final_setup, 0); \ rdtsc_prof_init(&sm3_cycles_final_execute, 0); \ rdtsc_prof_init(&ecdsa_cycles_verify_execute, 0); \ rdtsc_prof_init(&ecdsa_cycles_verify_setup, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_init_setup, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_init_execute, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_encrypt_setup, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_encrypt_execute, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_decrypt_setup, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_decrypt_execute, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_ctrl_setup, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_ctrl_execute, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_cleanup_setup, 0); \ rdtsc_prof_init(&sm4_gcm_cycles_cleanup_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_init_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_init_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_encrypt_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_encrypt_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_decrypt_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_decrypt_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_ctrl_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_ctrl_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_cleanup_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_cleanup_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_get_tag_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_get_tag_execute, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_update_aad_setup, 0); \ rdtsc_prof_init(&sm4_ccm_cycles_update_aad_execute, 0); \ } while (0) # define PRINT_RDTSC_AVERAGES() \ do { \ fprintf(qatDebugLogFile,"=========================\n"); \ fprintf(qatDebugLogFile,"Average Cycle Counts.\n"); \ fprintf(qatDebugLogFile,"=========================\n"); \ rdtsc_prof_print(&rsa_cycles_priv_enc_setup, "[RSA:priv_enc_setup]"); \ rdtsc_prof_print(&rsa_cycles_priv_dec_setup, "[RSA:priv_dec_setup]"); \ rdtsc_prof_print(&rsa_cycles_priv_execute, "[RSA:priv_execute]"); \ rdtsc_prof_print(&rsa_cycles_pub_enc_setup, "[RSA:pub_enc_setup]"); \ rdtsc_prof_print(&rsa_cycles_pub_dec_setup, "[RSA:pub_dec_setup]"); \ rdtsc_prof_print(&rsa_cycles_pub_execute, "[RSA:pub_execute]"); \ rdtsc_prof_print(&x25519_cycles_keygen_setup, "[X22519:keygen_setup]"); \ rdtsc_prof_print(&x25519_cycles_keygen_execute, "[X22519:keygen_execute]"); \ rdtsc_prof_print(&x25519_cycles_derive_setup, "[X22519:derive_setup]"); \ rdtsc_prof_print(&x25519_cycles_derive_execute, "[X22519:derive_execute]"); \ rdtsc_prof_print(&ecdsa_cycles_sign_setup, "[ECDSA:sign_setup]"); \ rdtsc_prof_print(&ecdsa_cycles_sign_execute, "[ECDSA:sign_execute]"); \ rdtsc_prof_print(&ecdsa_cycles_sign_setup_setup, "[ECDSA:sign_setup_setup]"); \ rdtsc_prof_print(&ecdsa_cycles_sign_setup_execute, "[ECDSA:sign_setup_execute]"); \ rdtsc_prof_print(&ecdsa_cycles_sign_sig_setup, "[ECDSA:sign_sig_setup]"); \ rdtsc_prof_print(&ecdsa_cycles_sign_sig_execute, "[ECDSA:sign_sig_execute]"); \ rdtsc_prof_print(&ecdh_cycles_keygen_setup, "[ECDH:keygen_setup]"); \ rdtsc_prof_print(&ecdh_cycles_keygen_execute, "[ECDH:keygen_execute]"); \ rdtsc_prof_print(&ecdh_cycles_compute_setup, "[ECDH:compute_setup]"); \ rdtsc_prof_print(&ecdh_cycles_compute_execute, "[ECDH:compute_execute]"); \ rdtsc_prof_print(&sm2ecdh_cycles_keygen_setup, "[ECDH:keygen_setup]"); \ rdtsc_prof_print(&sm2ecdh_cycles_keygen_execute, "[ECDH:keygen_execute]"); \ rdtsc_prof_print(&sm2ecdh_cycles_compute_setup, "[ECDH:compute_setup]"); \ rdtsc_prof_print(&sm2ecdh_cycles_compute_execute, "[ECDH:compute_execute]"); \ rdtsc_prof_print(&sm3_cycles_init_setup, "[SM3:init_setup]"); \ rdtsc_prof_print(&sm3_cycles_init_execute, "[SM3:init_execute]"); \ rdtsc_prof_print(&sm3_cycles_update_setup, "[SM3:update_setup]"); \ rdtsc_prof_print(&sm3_cycles_update_execute, "[SM3:update_execute]"); \ rdtsc_prof_print(&sm3_cycles_final_setup, "[SM3:final_setup]"); \ rdtsc_prof_print(&sm3_cycles_final_execute, "[SM3:final_execute]"); \ rdtsc_prof_print(&ecdsa_cycles_verify_setup, "[ECDSA:verify_setup]"); \ rdtsc_prof_print(&ecdsa_cycles_verify_execute, "[ECDSA:verify_execute]"); \ rdtsc_prof_print(&sm4_gcm_cycles_init_setup, "[SM4_GCM:init_setup]"); \ rdtsc_prof_print(&sm4_gcm_cycles_init_execute, "[SM4_GCM:init_execute]"); \ rdtsc_prof_print(&sm4_gcm_cycles_encrypt_setup, "[SM4_GCM:encrypt_setup]"); \ rdtsc_prof_print(&sm4_gcm_cycles_encrypt_execute, "[SM4_GCM:encrypt_execute]"); \ rdtsc_prof_print(&sm4_gcm_cycles_decrypt_setup, "[SM4_GCM:decrypt_setup]"); \ rdtsc_prof_print(&sm4_gcm_cycles_decrypt_execute, "[SM4_GCM:decrypt_execute]"); \ rdtsc_prof_print(&sm4_gcm_cycles_ctrl_setup, "[SM4_GCM:ctrl_setup]"); \ rdtsc_prof_print(&sm4_gcm_cycles_ctrl_execute, "[SM4_GCM:ctrl_execute]"); \ rdtsc_prof_print(&sm4_gcm_cycles_cleanup_setup, "[SM4_GCM:cleanup_setup]"); \ rdtsc_prof_print(&sm4_gcm_cycles_cleanup_execute, "[SM4_GCM:cleanup_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_init_setup, "[SM4_CCM:init_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_init_execute, "[SM4_CCM:init_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_encrypt_setup, "[SM4_CCM:encrypt_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_encrypt_execute, "[SM4_CCM:encrypt_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_decrypt_setup, "[SM4_CCM:decrypt_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_decrypt_execute, "[SM4_CCM:decrypt_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_ctrl_setup, "[SM4_CCM:ctrl_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_ctrl_execute, "[SM4_CCM:ctrl_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_cleanup_setup, "[SM4_CCM:cleanup_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_cleanup_execute, "[SM4_CCM:cleanup_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_get_tag_setup, "[SM4_CCM:get_tag_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_get_tag_execute, "[SM4_CCM:get_tag_execute]"); \ rdtsc_prof_print(&sm4_ccm_cycles_update_aad_setup, "[SM4_CCM:update_aad_setup]"); \ rdtsc_prof_print(&sm4_ccm_cycles_update_aad_execute, "[SM4_CCM:update_aad_execute]"); \ rdtsc_prof_print(&qat_hw_rsa_dec_req_prepare, "[QAT HW RSA: prepare]"); \ rdtsc_prof_print(&qat_hw_rsa_dec_req_submit, "[QAT HW RSA: submit]"); \ rdtsc_prof_print(&qat_hw_rsa_dec_req_retry, "[QAT HW RSA: retry]"); \ rdtsc_prof_print(&qat_hw_rsa_dec_req_cleanup, "[QAT HW RSA: cleanup]"); \ rdtsc_prof_print(&qat_hw_ecdsa_sign_req_prepare, "[QAT HW ECDSA: prepare]"); \ rdtsc_prof_print(&qat_hw_ecdsa_sign_req_submit, "[QAT HW ECDSA: submit]"); \ rdtsc_prof_print(&qat_hw_ecdsa_sign_req_retry, "[QAT HW ECDSA: retry]"); \ rdtsc_prof_print(&qat_hw_ecdsa_sign_req_cleanup, "[QAT HW ECDSA: cleanup]"); \ rdtsc_prof_print(&qat_hw_ecdh_derive_req_prepare, "[QAT HW ECDH: prepare]"); \ rdtsc_prof_print(&qat_hw_ecdh_derive_req_submit, "[QAT HW ECDH: submit]"); \ rdtsc_prof_print(&qat_hw_ecdh_derive_req_retry, "[QAT HW ECDH: retry]"); \ rdtsc_prof_print(&qat_hw_ecdh_derive_req_cleanup, "[QAT HW ECDH: cleanup]"); \ rdtsc_prof_print(&qat_hw_ecx_derive_req_prepare, "[QAT HW ECX: prepare]"); \ rdtsc_prof_print(&qat_hw_ecx_derive_req_submit, "[QAT HW ECX: submit]"); \ rdtsc_prof_print(&qat_hw_ecx_derive_req_retry, "[QAT HW ECX: retry]"); \ rdtsc_prof_print(&qat_hw_ecx_derive_req_cleanup, "[QAT HW ECX: cleanup]"); \ } while (0) # define START_RDTSC(ptr_clock) \ do { \ rdtsc_prof_start(ptr_clock); \ } while (0) # define STOP_RDTSC(ptr_clock, inc, ptr_name) \ do { \ rdtsc_prof_end(ptr_clock, inc, ptr_name); \ } while (0) # else # define INITIALISE_RDTSC_CLOCKS() # define PRINT_RDTSC_AVERAGES() # define START_RDTSC(ptr_clock) # define STOP_RDTSC(ptr_clock, inc, ptr_name) # endif /* QAT_CPU_CYCLES_COUNT */ /* Get absolute time by relative time. */ void get_sem_wait_abs_time(struct timespec *polling_abs_timeout, const struct timespec polling_timeout); #endif /* QAT_UTILS_H */ qatengine-1.9.0/qatengine-oot.spec000066400000000000000000000155011500416242000171160ustar00rootroot00000000000000%undefine __cmake_in_source_build %undefine _disable_source_fetch %global _lto_cflags %{nil} %global debug_package %{nil} # Dependent Library Versions %global major 2 %global minor 0 %global rev 0 %global ipsec intel-ipsec-mb %global ipsecver %{major}.%{minor} %global ipsecfull %{ipsec}-%{ipsecver} %global fullversion %{major}.%{minor}.%{rev} %global ippcp_major 12 %global ippcp_minor 1 %global ippcp cryptography-primitives %global ippcpver 1.1.0 %global ippcpfull %{ippcp}-%{ippcpver} %global ippcpfullversion %{ippcp_major}.%{ippcp_minor} %global openssl openssl-3.0.16 %global qatdriver QAT20.L.1.2.30-00078 %global openssl_source %{_builddir}/%{openssl} %global openssl_install %{buildroot}/%{_prefix}/local/ssl Name: QAT_Engine Version: 1.9.0 Release: 1%{?dist} Summary: Intel QuickAssist Technology(QAT) OpenSSL Engine License: BSD-3-Clause AND OpenSSL Source0: https://github.com/intel/QAT_Engine/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: https://github.com/openssl/openssl/releases/download/%{openssl}/%{openssl}.tar.gz#/%{openssl}.tar.gz Source2: https://downloadmirror.intel.com/843052/%{qatdriver}.tar.gz#/%{qatdriver}.tar.gz %if !0%{?suse_version} Source3: https://github.com/intel/ipp-crypto/archive/refs/tags/v%{ippcpver}.tar.gz#/%{ippcp}-%{ippcpver}.tar.gz Source4: https://github.com/intel/intel-ipsec-mb/archive/refs/tags/v%{ipsecver}.tar.gz#/%{ipsecfull}.tar.gz %endif %description This package provides the Intel QuickAssist Technology OpenSSL Engine (an OpenSSL Plug-In Engine) which provides cryptographic acceleration for both hardware and optimized software using Intel QuickAssist Technology enabled Intel platforms. %prep %setup -b 0 %setup -b 1 %if !0%{?suse_version} %setup -b 3 %setup -b 4 %endif # Setup Source2 driver package manually mkdir -p %{_builddir}/%{qatdriver} tar -zxvf %{_sourcedir}/%{qatdriver}.tar.gz -C %{_builddir}/%{qatdriver} cp -rf %{_builddir}/%{name}-%{version}/fips/driver_install.sh %{_builddir} %build cd %{_builddir}/%{openssl} ./config --prefix=%{_builddir}/openssl_install %make_build make install mkdir -p %{buildroot}/%{_prefix}/local/ssl/lib64 mkdir -p %{buildroot}/%{_prefix}/local/ssl/bin mkdir -p %{buildroot}/%{_prefix}/local/ssl/include mkdir -p %{buildroot}/%{_prefix}/local/lib mkdir -p %{buildroot}/%{_prefix}/lib cp -rf %{_builddir}/openssl_install/lib64/libcrypto.so.3 %{buildroot}/%{_prefix}/local/ssl/lib64 cp -rf %{_builddir}/openssl_install/lib64/libssl.so.3 %{buildroot}/%{_prefix}/local/ssl/lib64 cp -rf %{_builddir}/openssl_install/bin %{buildroot}/%{_prefix}/local/ssl/ cp -rf %{_builddir}/openssl_install/include %{buildroot}/%{_prefix}/local/ssl/ cd %{buildroot}/%{_prefix}/local/ssl/lib64 ln -sf libcrypto.so.3 libcrypto.so ln -sf libssl.so.3 libssl.so cd %{_builddir}/%{qatdriver} unset ICP_ROOT unset ICP_BUILD_OUTPUT ./configure %make_build %if !0%{?suse_version} cd %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb cmake . -B"build" -DOPENSSL_INCLUDE_DIR=%{openssl_install}/include -DOPENSSL_LIBRARIES=%{openssl_install} -DOPENSSL_ROOT_DIR=%{openssl_source} cd build %make_build install -d %{buildroot}/%{_includedir}/crypto_mb cp -rf %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb/include/crypto_mb/*.h /%{buildroot}/%{_includedir}/crypto_mb/ install -d %{buildroot}/%{_libdir} cp %{_builddir}/%{ippcpfull}/sources/ippcp/crypto_mb/build/bin/libcrypto_mb.so.%{ippcpfullversion} %{buildroot}/%{_libdir} cd %{buildroot}/%{_libdir} ln -sf libcrypto_mb.so.%{ippcpfullversion} libcrypto_mb.so.%{ippcp_major} ln -sf libcrypto_mb.so.%{ippcpfullversion} libcrypto_mb.so cp -rf %{buildroot}/%{_libdir}/libcrypto_mb.so.%{ippcpfullversion} %{buildroot}/%{_prefix}/local/lib cp -rf %{buildroot}/%{_libdir}/libcrypto_mb.so.%{ippcp_major} %{buildroot}/%{_prefix}/local/lib cp -rf %{buildroot}/%{_libdir} libcrypto_mb.so %{buildroot}/%{_prefix}/local/lib cd %{_builddir}/%{ipsecfull} cd lib %make_build install -d %{buildroot}/%{_includedir} install -m 0644 %{_builddir}/%{ipsecfull}/lib/intel-ipsec-mb.h %{buildroot}/%{_includedir} cp %{buildroot}/%{_includedir}/intel-ipsec-mb.h /usr/include/ install -s -m 0755 %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{fullversion} %{buildroot}/%{_libdir} cp -rf %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{fullversion} %{buildroot}/%{_prefix}/lib cp -rf %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so %{buildroot}/%{_prefix}/lib cp -rf %{_builddir}/%{ipsecfull}/lib/libIPSec_MB.so.%{major} %{buildroot}/%{_prefix}/lib cd %{buildroot}/%{_libdir} ln -sf libIPSec_MB.so.%{fullversion} libIPSec_MB.so.%{major} ln -sf libIPSec_MB.so.%{fullversion} libIPSec_MB.so %endif cd %{_builddir}/%{name}-%{version} autoreconf -ivf %if !0%{?suse_version} # Enable QAT_HW & QAT_SW Co-existence acceleration ./configure --with-openssl_install_dir=%{openssl_install} --with-qat_hw_dir=%{_builddir}/%{qatdriver} --enable-qat_sw --with-qat_sw_crypto_mb_install_dir=%{buildroot}/%{_prefix}/local --with-qat_sw_ipsec_mb_install_dir=%{buildroot}/%{_prefix} %else # Enable QAT_HW acceleration for SUSE ./configure --with-openssl_install_dir=%{openssl_install} --with-qat_hw_dir=%{_builddir}/%{qatdriver} %endif %make_build install -d %{buildroot}/%{_prefix}/local/ssl/lib64/engines-3 cp -rf %{_builddir}/%{name}-%{version}/.libs/qatengine.so %{buildroot}/%{_prefix}/local/ssl/lib64/engines-3 install -d %{buildroot}/%{_libdir}/build cp -rf %{_builddir}/%{name}-%{version}/qat_hw_config/4xxx/multi_process/4xxx_dev0.conf %{buildroot}/%{_libdir}/build cp -rf %{_builddir}/%{qatdriver}/build/libusdm_drv_s.so %{buildroot}/%{_libdir} cp -rf %{_builddir}/%{qatdriver}/build/libqat_s.so %{buildroot}/%{_libdir} cp -rf %{_builddir}/%{qatdriver}/build %{buildroot}/%{_libdir} cp %{_builddir}/%{name}-%{version}/fips/driver_install.sh %{buildroot}/%{_libdir} %post echo "RPM is getting installed" if (lspci | grep Co- >/dev/null ) then ./%{_libdir}/driver_install.sh fi %clean rm -rf %{buildroot} %files %exclude %{_prefix}/local/lib/lib64 %{_prefix}/local/ssl/lib64/engines-3/qatengine.so %{_prefix}/local/ssl/lib64 %{_prefix}/local/ssl/bin %{_prefix}/local/ssl/include %{_libdir}/libqat_s.so %{_libdir}/libusdm_drv_s.so %{_libdir}/build %{_libdir}/driver_install.sh %license LICENSE* %doc README.md docs* %if !0%{?suse_version} %{_libdir}/libcrypto_mb.so.%{ippcpfullversion} %{_libdir}/libcrypto_mb.so.%{ippcp_major} %{_libdir}/libcrypto_mb.so %{_libdir}/libIPSec_MB.so.%{fullversion} %{_libdir}/libIPSec_MB.so.%{major} %{_libdir}/libIPSec_MB.so %{_prefix}/lib/libIPSec_MB.so.%{fullversion} %{_prefix}/lib/libIPSec_MB.so.%{major} %{_prefix}/lib/libIPSec_MB.so %{_prefix}/local/lib/libcrypto_mb.so.%{ippcpfullversion} %{_prefix}/local/lib/libcrypto_mb.so.%{ippcp_major} %{_prefix}/local/lib/libcrypto_mb.so %{_includedir}/crypto_mb %{_includedir}/intel-ipsec-mb.h %endif qatengine-1.9.0/qatengine.spec000066400000000000000000000200161500416242000163140ustar00rootroot00000000000000# SPDX-License-Identifier: MIT # Build as an OpenSSL provider instead of as an engine %bcond provider %[0%{?fedora} >= 41 || 0%{?rhel} >= 10] # QAT_HW only acceleration for RHEL %bcond sw %{undefined rhel} # Define the directory where the OpenSSL engines are installed %if %{with provider} %global modulesdir %(pkg-config --variable=modulesdir libcrypto) %else %global enginesdir %(pkg-config --variable=enginesdir libcrypto) %endif Name: qatengine Version: 1.9.0 Release: 1%{?dist} Summary: Intel QuickAssist Technology (QAT) OpenSSL Engine # Most of the source code is BSD, with the following exceptions: # - qat.txt, qat_err.h & qat_err.c files are Apache License 2.0 # - qat_hw_config/* is (BSD or GPLv2) and not used during compilation License: BSD-3-Clause URL: https://github.com/intel/QAT_Engine Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz # https://bugzilla.redhat.com/show_bug.cgi?id=1909065 ExclusiveArch: x86_64 BuildRequires: autoconf BuildRequires: automake BuildRequires: gcc BuildRequires: libtool BuildRequires: openssl-devel >= 1.1.1 BuildRequires: qatlib-devel >= 23.02.0 %if !0%{?rhel} BuildRequires: intel-ipp-crypto-mb-devel >= 1.0.6 BuildRequires: intel-ipsec-mb-devel >= 2.0 %endif BuildRequires: openssl %description This package provides the Intel QuickAssist Technology OpenSSL Engine (an OpenSSL Plug-In Engine) which provides cryptographic acceleration for both hardware and optimized software using Intel QuickAssist Technology enabled Intel platforms. %prep %autosetup -n QAT_Engine-%{version} %build autoreconf -ivf %configure %{?with_sw:--enable-qat_sw} %{?with_provider:--enable-qat_provider} %make_build %install %make_install %if 0%{?rhel} find %{buildroot} -name "*.la" -delete %endif %check %if %{with provider} export OPENSSL_MODULES=%{buildroot}%{modulesdir} openssl list -providers -provider qatprovider %else export OPENSSL_ENGINES=%{buildroot}%{enginesdir} openssl engine -v %{name} %endif %files %license LICENSE* %doc README.md docs* %if %{with provider} %{modulesdir}/qatprovider.so %else %{enginesdir}/%{name}.so %endif %changelog * Mon Mar 10 2025 Nagha Abirami - 1.9.0-1 - Update to qatengine v1.9.0 * Thu Jan 23 2025 Yogaraj Alamenda - 1.8.1-1 - Update to qatengine v1.8.1 - Update e_qat_err files license info * Sat Jan 18 2025 Fedora Release Engineering - 1.8.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild * Thu Dec 5 2024 Jaya Naga Venkata Sudhakar - 1.8.0-1 - Update to qatengine v1.8.0 * Thu Nov 14 2024 Ali Erdinc Koroglu - 1.7.0-2 - Rebuilt for intel-ipsec-mb-2.0 * Thu Oct 24 2024 Yogaraj Alamenda - 1.7.0-1 - Update to qatengine v1.7.0 - Remove qat_contig_mem from upstream package * Fri Sep 20 2024 Yaakov Selkowitz - 1.6.2-2 - Build as a provider for F41 and EL10 * Wed Aug 14 2024 Krithika Kumaravelu - 1.6.2-1 - Update to qatengine v1.6.2 * Fri Aug 09 2024 Yogaraj Alamenda - 1.6.1-3 - Add openssl-devel-engine dependency from F41 * Fri Jul 19 2024 Fedora Release Engineering - 1.6.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild * Thu Jun 20 2024 Venkatesh J - 1.6.1-1 - Update to qatengine v1.6.1 * Thu Mar 14 2024 Jaya Naga Venkata Sudhakar - 1.6.0-1 - Update to qatengine v1.6.0 * Fri Jan 26 2024 Fedora Release Engineering - 1.5.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild * Mon Jan 22 2024 Fedora Release Engineering - 1.5.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild * Mon Dec 25 2023 Jaya Naga Venkata Sudhakar - 1.5.0-1 - Update to qatengine v1.5.0 * Wed Nov 22 2023 Vladis Dronov - 1.4.0-2 - Rebuild due to qatlib so-version bump * Wed Sep 13 2023 Yogaraj Alamenda - 1.4.0-1 - Update to qatengine v1.4.0 * Tue Sep 12 2023 Yogaraj Alamenda - 1.3.1-1 - Update to qatengine v1.3.1 * Fri Sep 08 2023 Giovanni Cabiddu - 1.3.0-2 - Rebuild due to qatlib so-version bump * Wed Aug 09 2023 Yogaraj Alamenda - 1.3.0-1 - Update to qatengine v1.3.0 * Fri Jul 21 2023 Fedora Release Engineering - 1.2.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild * Wed Jun 14 2023 Yogaraj Alamenda - 1.2.0-1 - Update to qatengine v1.2.0 * Thu May 04 2023 Yogaraj Alamenda - 1.1.0-1 - Update to qatengine v1.1.0 * Thu Apr 13 2023 Ali Erdinc Koroglu - 1.0.0-2 - Enable QAT_HW & QAT SW Co-ex Acceleration for non RHEL distros * Wed Mar 22 2023 Yogaraj Alamenda - 1.0.0-1 - Update to qatengine v1.0.0 * Thu Feb 09 2023 Yogaraj Alamenda - 0.6.19-1 - Update to qatengine v0.6.19 * Fri Jan 20 2023 Fedora Release Engineering - 0.6.18-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild * Thu Dec 08 2022 Yogaraj Alamenda - 0.6.18-1 - Update to qatengine v0.6.18 * Wed Nov 02 2022 Yogaraj Alamenda - 0.6.17-1 - Update to qatengine v0.6.17 * Mon Oct 03 2022 Yogaraj Alamenda - 0.6.16-1 - Update to qatengine v0.6.16 * Wed Aug 24 2022 Yogaraj Alamenda - 0.6.15-1 - Update to qatengine v0.6.15 * Sat Jul 30 2022 Vladis Dronov - 0.6.14-2 - Rebuild due to qatlib so-version bump * Wed Jul 20 2022 Yogaraj Alamenda - 0.6.14-1 - Update to qatengine v0.6.14 * Wed Jun 22 2022 Yogaraj Alamenda - 0.6.13-1 - Update to qatengine v0.6.13 * Fri Apr 01 2022 Yogaraj Alamenda - 0.6.12-1 - Update to qatengine v0.6.12 * Thu Jan 27 2022 Yogaraj Alamenda - 0.6.11-1 - Update to qatengine v0.6.11 * Fri Jan 21 2022 Fedora Release Engineering - 0.6.10-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild * Thu Oct 28 2021 Yogaraj Alamenda - 0.6.10-1 - Update to qatengine v0.6.10 * Mon Oct 18 2021 Yogaraj Alamenda - 0.6.9-1 - Update to qatengine v0.6.9 * Fri Sep 10 2021 Yogaraj Alamenda - 0.6.8-1 - Update to qatengine v0.6.8 * Thu Sep 09 2021 Yogaraj Alamenda - 0.6.7-2 - Rebuilt for qatlib v21.08 * Fri Jul 30 2021 Yogaraj Alamenda - 0.6.7-1 - Update to qatengine v0.6.7 * Fri Jul 23 2021 Fedora Release Engineering - 0.6.6-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild * Thu May 20 2021 Yogaraj Alamenda - 0.6.6-1 - Update to qatengine v0.6.6 * Thu Mar 18 2021 Yogaraj Alamenda - 0.6.5-1 - Update to qatengine v0.6.5 - Update doc with additional docs * Wed Jan 27 2021 Fedora Release Engineering - 0.6.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild * Fri Dec 11 2020 Yogaraj Alamenda 0.6.4-1 - Update to qatengine v0.6.4 * Mon Nov 30 2020 Yogaraj Alamenda 0.6.3-1 - Update to qatengine v0.6.3 - Update License and library installation * Wed Nov 18 2020 Dinesh Balakrishnan 0.6.2-1 - Update to qatengine v0.6.2 - Address review comments * Tue Sep 08 2020 Dinesh Balakrishnan 0.6.1-1 - Initial version of rpm package qatengine-1.9.0/test.am000066400000000000000000000072371500416242000147750ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2021-2025 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QAT_TEST_SRC = test/main.c \ test/tests.c \ test/tests_rsa.c \ test/tests_ecx.c \ test/tests_ecdh.c \ test/tests_ecdsa.c \ test/tests_aes128_gcm.c \ test/tests_aes256_gcm.c \ test/tests_aes128_ccm.c \ test/tests_aes192_ccm.c \ test/tests_aes256_ccm.c \ test/tests_sm2.c \ test/tests_sm3.c \ test/tests_sm4_cbc.c \ test/tests_sm4_gcm.c \ test/tests_sm4_ccm.c \ test/tests_sha2.c if QAT_PROVIDER QAT_HW_TEST_SRC = test/tests_dsa.c \ test/tests_dh.c \ test/tests_prf.c \ test/tests_hkdf.c \ test/tests_sha3.c \ test/tests_aes_cbc_hmac_sha.c \ test/tests_chacha20_poly1305.c endif if QAT_HW QAT_HW_TEST_SRC = test/tests_dsa.c \ test/tests_dh.c \ test/tests_prf.c \ test/tests_hkdf.c \ test/tests_sha3.c \ test/tests_aes_cbc_hmac_sha.c \ test/tests_chacha20_poly1305.c endif testapp_SOURCES = ${QAT_TEST_SRC} \ ${QAT_HW_TEST_SRC} testapp_CFLAGS = $(includes_qat_hw) $(includes_openssl) \ $(cflags) $(cflags_openssl_3) $(cflags_qat_hw) \ $(cflags_qat_sw) $(cflags_qat_sw_ipsec) \ $(cflags_common) testapp_LDADD = -ldl -lrt -lpthread $(OPENSSL_LIB) $(QAT_SW_CRYPTO_MB_LIB) test: testapp qatengine-1.9.0/test/000077500000000000000000000000001500416242000144455ustar00rootroot00000000000000qatengine-1.9.0/test/main.c000066400000000000000000001462471500416242000155530ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /* macros defined to allow use of the cpu get and set affinity functions */ #define _GNU_SOURCE #define __USE_GNU #include #include #include #include #ifndef __FreeBSD__ # include # else # include # include # include # include # include #endif #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define DEFAULT_KEY_SIZE 2048 #ifndef __FreeBSD__ typedef cpu_set_t qat_cpuset; #else typedef cpuset_t qat_cpuset; #endif FILE *qatDebugLogFile = NULL; static pthread_cond_t ready_cond; static pthread_cond_t start_cond; static pthread_cond_t stop_cond; static pthread_mutex_t mutex; static int cleared_to_start; static int active_thread_count; static int ready_thread_count; /* thread_count - control number of threads created */ static int thread_count = 1; /* define the initial test values */ static int core_count = 1; static int enable_engine = 0; static int enable_provider = 0; char *prov_id; #ifdef QAT_OPENSSL_PROVIDER static OSSL_PROVIDER *provider = NULL; #endif /* test_count - specify the number of operations that each thread does */ static int test_count = 1; static int test_size = DEFAULT_KEY_SIZE; static int cpu_affinity = 0; static int test_alg = 0; static int enable_perf = 0; static int enable_async = 0; #ifdef QAT_OPENSSL_3 static int use_callback_mode = 0; #endif static int enable_external_polling = 0; static int enable_event_driven_polling = 0; static int enable_negative = 0; static int print_output = 0; static int verify = 0; static int curve = P_CURVE_256; /* default curve is NIST Prime-Curve P-256 */ static int kdf = 1; static int zero_copy = 0; static int cpu_core_info = 0; static int qatPerformOpRetries; static char *engine_id; static ENGINE *engine = NULL; static char *default_tls_string = "TLSv1_2"; static char *default_digest_string = "SHA256"; static char *tls_version = NULL; static char *digest_kdf = NULL; static int prf_op = -1; static int hkdf_op = -1; static int explicit_engine = 0; static int async_jobs = 1; static int sw_fallback = 0; static int sign_only = 0; static int verify_only = 0; static int encrypt_only = 0; static int decrypt_only = 0; extern char *sw_algo_bitmap; extern char *hw_algo_bitmap; /* Thread_info structure declaration */ typedef struct { pthread_t th; int id; int count; TEST_PARAMS *test_params; } THREAD_INFO; #define MAX_STAT 10 #ifdef __FreeBSD__ # define MAX_CORE 88 #else # define MAX_CORE 48 #endif typedef union { struct { int user; int nice; int sys; int idle; int io; #ifndef __FreeBSD__ int irq; int softirq; #else /* interrupt */ int intr; #endif int context; }; int d[MAX_STAT]; } cpu_time_t; static cpu_time_t cpu_time[MAX_CORE]; static cpu_time_t cpu_time_total; #ifndef __FreeBSD__ static cpu_time_t cpu_context; #endif #define MAX_THREAD 1024 THREAD_INFO tinfo[MAX_THREAD]; #ifdef __FreeBSD__ # define CPU_STATES 5 # define CP_USER 0 # define CP_NICE 1 # define CP_SYS 2 # define CP_INTR 3 # define CP_IDLE 4 # define CP_STAT_SIZE (MAX_CORE * CPU_STATES) #endif typedef struct options_data { const char *name; int test_size; int test_alg; int curve_name; int op; } option_data; static const option_data rsa_choices[] = { {"rsa1024", 1024, TEST_RSA, 0, 0}, {"rsa2048", 2048, TEST_RSA, 0, 0}, {"rsa3072", 3072, TEST_RSA, 0, 0}, {"rsa4096", 4096, TEST_RSA, 0, 0}, {"rsa8192", 8192, TEST_RSA, 0, 0}, }; static const option_data dsa_choices[] = { {"dsa1024", 1024, TEST_DSA, 0, 0}, {"dsa2048", 2048, TEST_DSA, 0, 0}, {"dsa3072", 3072, TEST_DSA, 0, 0}, {"dsa4096", 4096, TEST_DSA, 0, 0}, }; static const option_data dh_choices[] = { {"dh512", 512, TEST_DH, 0, 0}, {"dh1024", 1024, TEST_DH, 0, 0}, {"dh2048", 2048, TEST_DH, 0, 0}, {"dh3072", 3072, TEST_DH, 0, 0}, {"dh4096", 4096, TEST_DH, 0, 0}, {"dh8192", 8192, TEST_DH, 0, 0}, }; static const option_data ecdh_choices[] = { {"ecdhp192", 0, TEST_ECDH, P_CURVE_192, 0}, {"ecdhp224", 0, TEST_ECDH, P_CURVE_224, 0}, {"ecdhp256", 0, TEST_ECDH, P_CURVE_256, 0}, {"ecdhp384", 0, TEST_ECDH, P_CURVE_384, 0}, {"ecdhp521", 0, TEST_ECDH, P_CURVE_521, 0}, {"ecdhk163", 0, TEST_ECDH, K_CURVE_163, 0}, {"ecdhk233", 0, TEST_ECDH, K_CURVE_233, 0}, {"ecdhk283", 0, TEST_ECDH, K_CURVE_283, 0}, {"ecdhk409", 0, TEST_ECDH, K_CURVE_409, 0}, {"ecdhk571", 0, TEST_ECDH, K_CURVE_571, 0}, {"ecdhb163", 0, TEST_ECDH, B_CURVE_163, 0}, {"ecdhb233", 0, TEST_ECDH, B_CURVE_233, 0}, {"ecdhb283", 0, TEST_ECDH, B_CURVE_283, 0}, {"ecdhb409", 0, TEST_ECDH, B_CURVE_409, 0}, {"ecdhb571", 0, TEST_ECDH, B_CURVE_571, 0}, {"ecdhx25519", 0, TEST_ECX, X_CURVE_25519, 0}, {"ecdhx448", 0, TEST_ECX, X_CURVE_448, 0}, {"ecdhsm2", 0, TEST_ECDH, P_CURVE_SM2, 0}, }; static const option_data ecdsa_choices[] = { {"ecdsap192", 0, TEST_ECDSA, P_CURVE_192, 0}, {"ecdsap224", 0, TEST_ECDSA, P_CURVE_224, 0}, {"ecdsap256", 0, TEST_ECDSA, P_CURVE_256, 0}, {"ecdsap384", 0, TEST_ECDSA, P_CURVE_384, 0}, {"ecdsap521", 0, TEST_ECDSA, P_CURVE_521, 0}, {"ecdsak163", 0, TEST_ECDSA, K_CURVE_163, 0}, {"ecdsak233", 0, TEST_ECDSA, K_CURVE_233, 0}, {"ecdsak283", 0, TEST_ECDSA, K_CURVE_283, 0}, {"ecdsak409", 0, TEST_ECDSA, K_CURVE_409, 0}, {"ecdsak571", 0, TEST_ECDSA, K_CURVE_571, 0}, {"ecdsab163", 0, TEST_ECDSA, B_CURVE_163, 0}, {"ecdsab233", 0, TEST_ECDSA, B_CURVE_233, 0}, {"ecdsab283", 0, TEST_ECDSA, B_CURVE_283, 0}, {"ecdsab409", 0, TEST_ECDSA, B_CURVE_409, 0}, {"ecdsab571", 0, TEST_ECDSA, B_CURVE_571, 0}, }; static const option_data aes_choices[] = { {"aes128_cbc_hmac_sha1", 0, TEST_AES128_CBC_HMAC_SHA1, 0, 0}, {"aes256_cbc_hmac_sha1", 0, TEST_AES256_CBC_HMAC_SHA1, 0, 0}, {"aes128_cbc_hmac_sha256", 0, TEST_AES128_CBC_HMAC_SHA256, 0, 0}, {"aes256_cbc_hmac_sha256", 0, TEST_AES256_CBC_HMAC_SHA256, 0, 0}, {"aes128gcm", 0, TEST_AES128_GCM, 0, 0}, {"aes256gcm", 0, TEST_AES256_GCM, 0, 0}, {"aes128ccm", 0, TEST_AES128_CCM, 0, 0}, {"aes192ccm", 0, TEST_AES192_CCM, 0, 0}, {"aes256ccm", 0, TEST_AES256_CCM, 0, 0}, }; static const option_data sha3_choices[] = { {"sha3-224", 0, TEST_SHA3_224, 0, 0}, {"sha3-256", 0, TEST_SHA3_256, 0, 0}, {"sha3-384", 0, TEST_SHA3_384, 0, 0}, {"sha3-512", 0, TEST_SHA3_512, 0, 0}, }; static const option_data sha2_choices[] = { {"sha2-224", 0, TEST_SHA2_224, 0, 0}, {"sha2-256", 0, TEST_SHA2_256, 0, 0}, {"sha2-384", 0, TEST_SHA2_384, 0, 0}, {"sha2-512", 0, TEST_SHA2_512, 0, 0}, }; /****************************************************************************** * function: * cpu_time_add (cpu_time_t *t1, cpu_time_t *t2, int subtract) * * @param t1 [IN] - cpu time * @param t2 [IN] - cpu time * @param subtract [IN] - subtract flag * * description: * CPU timing calculation functions. ******************************************************************************/ static void cpu_time_add (cpu_time_t *t1, cpu_time_t *t2, int subtract) { int i; for (i = 0; i < MAX_STAT; i++) { if (subtract) t1->d[i] -= t2->d[i]; else t1->d[i] += t2->d[i]; } } #ifndef __FreeBSD__ /****************************************************************************** * function: * read_stat (int init) * * @param init [IN] - op flag * * description: * read in CPU status from proc/stat file ******************************************************************************/ static void read_stat (int init) { char line[1024]; char tag[10]; FILE *fp; int index = 0; int i; cpu_time_t tmp; if ((fp = fopen("/proc/stat", "r")) == NULL) { WARN("# FAIL: Can't open proc stat\n"); exit(1); } while (!feof(fp)) { if (fgets(line, sizeof(line) - 1, fp) == NULL) break; if (!strncmp(line, "ctxt", 4)) { if (sscanf(line, "%*s %d", &tmp.context) < 1) goto parse_fail; cpu_time_add(&cpu_context, &tmp, init); continue; } if (strncmp(line, "cpu", 3)) continue; if (sscanf(line, "%s %d %d %d %d %d %d %d", tag, &tmp.user, &tmp.nice, &tmp.sys, &tmp.idle, &tmp.io, &tmp.irq, &tmp.softirq) < 8) goto parse_fail; if (!strcmp(tag, "cpu")) cpu_time_add(&cpu_time_total, &tmp, init); else if (!strncmp(tag, "cpu", 3)) { index = atoi(&tag[3]); if ((index >= 0) && (index < MAX_CORE)) cpu_time_add(&cpu_time[index], &tmp, init); } } if (!init && cpu_core_info) { printf(" %10s %10s %10s %10s %10s %10s %10s\n", "user", "nice", "sys", "idle", "io", "irq", "sirq"); for (i = 0; i < MAX_CORE + 1; i++) { cpu_time_t *t; if (i == MAX_CORE) { printf("total "); t = &cpu_time_total; } else { printf("cpu%d ", i); t = &cpu_time[i]; } printf(" %10d %10d %10d %10d %10d %10d %10d\n", t->user, t->nice, t->sys, t->idle, t->io, t->irq, t->softirq); } printf("Context switches: %d\n", cpu_context.context); } fclose(fp); return; parse_fail: WARN("# FAIL: Failed to parse %s\n", line); exit(1); } #else /****************************************************************************** * function: * read_stat_systemctl (int init) * * @param init [IN] - op flag * * description: * read in CPU status from systemctl system call using kern.cp_time and kern.cp_times ******************************************************************************/ static void read_stat_systemctl (int init) { int index = 0; int i; int core; cpu_time_t tmp; long cputotal[CPU_STATES]; long pcpustat[CP_STAT_SIZE]; size_t cputotal_size; size_t pcpustat_size; cputotal_size = sizeof(cputotal); pcpustat_size = sizeof(pcpustat); if (sysctlbyname("kern.cp_time", &cputotal, &cputotal_size, NULL, 0) < 0) { WARN("#FAIL: Error reading kern.cp_time sysctl : %s\n", strerror(errno)); exit(1); } tmp.user = (int) cputotal[CP_USER]; tmp.nice = (int) cputotal[CP_NICE]; tmp.sys = (int) cputotal[CP_SYS]; tmp.intr = (int) cputotal[CP_INTR]; tmp.idle = (int) cputotal[CP_IDLE]; cpu_time_add(&cpu_time_total, &tmp, init); if (sysctlbyname("kern.cp_times", &pcpustat, &pcpustat_size, NULL, 0) < 0) { WARN("#FAIL: Error reading kern.cp_times sysctl : %s\n", strerror(errno)); exit(1); } core = 0; for (index = 0; index < CP_STAT_SIZE; index += CPU_STATES) { tmp.user = (int) pcpustat[index + CP_USER]; tmp.nice = (int) pcpustat[index + CP_NICE]; tmp.sys = (int) pcpustat[index + CP_SYS]; tmp.intr = (int) pcpustat[index + CP_INTR]; tmp.idle = (int) pcpustat[index + CP_IDLE]; if(core < MAX_CORE + 1) cpu_time_add(&cpu_time[core], &tmp, init); core = core + 1; } if (!init && cpu_core_info) { printf(" %10s %10s %10s %10s %10s\n", "user", "nice", "sys", "intr", "idle"); for (i = 0; i < MAX_CORE + 1; i++) { cpu_time_t *t; if (i == MAX_CORE) { printf("total "); t = &cpu_time_total; } else { printf("cpu%d ", i); t = &cpu_time[i]; } printf(" %10d %10d %10d %10d %10d\n", t->user, t->nice, t->sys, t->intr, t->idle); } } return; } #endif /****************************************************************************** * function: * rdtsc (void) * description: * Timestamp Counter for measuring clock cycles in performance testing. ******************************************************************************/ static __inline__ unsigned long long rdtsc(void) { unsigned long a, d; asm volatile ("rdtsc":"=a" (a), "=d"(d)); return (((unsigned long long)a) | (((unsigned long long)d) << 32)); } /****************************************************************************** * function: * *test_name(int test) * * @param test [IN] - test case * * description: * test_name selection list ******************************************************************************/ char *test_name(int test) { switch (test) { case TEST_RSA: return "RSA"; case TEST_ECDH: return "ECDH"; case TEST_ECDSA: return "ECDSA"; case TEST_ECX: return "ECX"; case TEST_AES128_GCM: return "AES128 GCM"; case TEST_AES256_GCM: return "AES256 GCM"; case TEST_AES128_CCM: return "AES128 CCM"; case TEST_AES192_CCM: return "AES192 CCM"; case TEST_AES256_CCM: return "AES256 CCM"; case TEST_SM3: return "SM3"; case TEST_DSA: return "DSA"; case TEST_DH: return "DH"; case TEST_PRF: return "PRF"; case TEST_HKDF: return "HKDF"; case TEST_AES128_CBC_HMAC_SHA1: return "AES128 CBC HMAC SHA1"; case TEST_AES256_CBC_HMAC_SHA1: return "AES256 CBC HMAC SHA1"; case TEST_AES128_CBC_HMAC_SHA256: return "AES128 CBC HMAC SHA256"; case TEST_AES256_CBC_HMAC_SHA256: return "AES256 CBC HMAC SHA256"; case TEST_SHA3_224: return "SHA3-224"; case TEST_SHA3_256: return "SHA3-256"; case TEST_SHA3_384: return "SHA3-384"; case TEST_SHA3_512: return "SHA3-512"; case TEST_CHACHA20_POLY1305: return "CHACHA20-POLY1305"; case TEST_SM4_CBC: return "SM4-CBC"; case TEST_SM4_GCM: return "SM4-GCM"; case TEST_SM4_CCM: return "SM4-CCM"; case TEST_SM2: return "SM2"; case TEST_SHA2_224: return "SHA2-224"; case TEST_SHA2_256: return "SHA2-256"; case TEST_SHA2_384: return "SHA2-384"; case TEST_SHA2_512: return "SHA2-512"; case 0: return "all tests"; default: return "*unknown or not supported on this platform*"; } } /****************************************************************************** * function: * *ecdh_curve__name(int type) * * @param test [IN] - curve type * * description: * ecdh curve name selection list ******************************************************************************/ char *ecdh_curve_name(int type) { switch (type) { case P_CURVE_192: return "NIST Prime-Curve P-192"; case P_CURVE_224: return "NIST Prime-Curve P-224"; case P_CURVE_256: return "NIST Prime-Curve P-256"; case P_CURVE_384: return "NIST Prime-Curve P-384"; case P_CURVE_521: return "NIST Prime-Curve P-521"; case K_CURVE_163: return "NIST Binary-Curve K-163"; case K_CURVE_233: return "NIST Binary-Curve K-233"; case K_CURVE_283: return "NIST Binary-Curve K-283"; case K_CURVE_409: return "NIST Binary-Curve K-409"; case K_CURVE_571: return "NIST Binary-Curve K-571"; case B_CURVE_163: return "NIST Binary-Curve B-163"; case B_CURVE_233: return "NIST Binary-Curve B-233"; case B_CURVE_283: return "NIST Binary-Curve B-283"; case B_CURVE_409: return "NIST Binary-Curve B-409"; case B_CURVE_571: return "NIST Binary-Curve B-571"; case P_CURVE_SM2: return "SM2 Curve"; case 0: return "all curves"; default: return "*unknown*"; } } char *size(int type) { switch (type) { case KEY_2048_224: return "DSA key 2048-224"; case KEY_2048_256: return "DSA key 2048-256"; case 0: return "all curves"; default: return "*unknown*"; } } /****************************************************************************** * function: * usage(char *program) * * * @param program [IN] - input argument * * description: * test application usage help ******************************************************************************/ static void usage(char *program) { printf("\nUsage:\n"); printf("\t%s [-c ] ", program); printf("[-n ] [-nc ] [-af] [-p] [-v] "); #ifdef QAT_OPENSSL_3 printf("[-callback] "); #endif printf("[-u] [-perf] [-x] [-z] [-epoll] [-poll] [-f] [-engine ] "); printf("[-ne] [-tls_version ] [-di ] "); printf("[-async_jobs ] [-prf_op ] "); printf("[-hkdf_op ]"); printf("[-sw_fallback] "); printf("[-sign] [-verify] [-encrypt] [-decrypt] [-h] [] \n"); printf("Where:\n"); printf("\t-c specifies the test iteration count\n"); printf("\t-n specifies the number of threads to run\n"); printf("\t-nc specifies the number of CPU cores\n"); printf("\t-af enables core affinity\n"); printf("\t-p print the test output\n"); printf("\t-v verify the output\n"); #ifdef QAT_OPENSSL_3 printf("\t-callback enable callback mode in asynchronous processing\n"); #endif printf("\t-u display cpu usage per core\n"); printf("\t-perf run performance measurement\n"); printf("\t-x force EVP layer calls to use an explicit engine.\n"); printf("\t Note: This will cause any calls that are not implemented\n"); printf("\t by the engine under test to fail.\n"); printf("\t-z enable zero copy mode\n"); printf("\t-epoll enable event driven polling\n"); printf("\t-poll enable external polling of the engine (qat engine only)\n"); printf("\t-f specifies whether to enable(1) or disable(0) KDF for ECDH \n"); printf("\t-engine specify the engine to use, eg -engine qatengine (default is software)\n"); printf("\t-hw_algo specify the hw algorithm enabling bitmap\n"); printf("\t-sw_algo specify the sw algorithm enabling bitmap\n"); printf("\t-provider specify the provider to use, eg -provider qat (default is software)\n"); printf("\t-ne enables negative scenario test cases \n"); printf("\t-tls_version specifies tls_version TLSv1,TLSv1_1, TLSv1_2 \n"); printf("\t-di specifies digest for prf and hkdf (OpenSSL_1.1.1 & higher), MD5, SHA256, SHA384, SHA512 \n"); printf("\t-async_jobs enable asynchronous processing and specifies the number of asynchronous jobs per thread\n"); printf("\t-prf_op specifies the PRF operation required (default is to run them all)\n"); printf("\t-hkdf_op specifies the HKDF operation (0-Extract&Expand 1-Extract 2-Expand (default is to run them all))\n"); printf("\t-sw_fallback enables the sw fallback feature (qat engine only)\n"); printf("\t-sign sign only\n"); printf("\t-verify verify only\n"); printf("\t-encrypt encrypt only\n"); printf("\t-decrypt decrypt only\n"); printf("\t-h print this usage\n"); printf("\nTests:\n"); printf("\trsa1024 RSA 1024 test\n"); printf("\trsa2048 RSA 2048 test\n"); printf("\trsa3072 RSA 3072 test\n"); printf("\trsa4096 RSA 4096 test\n"); printf("\trsa8192 RSA 8192 test\n"); printf("\tdsa1024 DSA 1024 test\n"); printf("\tdsa2048 DSA 2048 test\n"); printf("\tdsa3072 DSA 3072 test\n"); printf("\tdsa4096 DSA 4096 test\n"); printf("\tdh512 DH 1024 test\n"); printf("\tdh1024 DH 1024 test\n"); printf("\tdh2048 DH 2048 test\n"); printf("\tdh3072 DH 3072 test\n"); printf("\tdh4096 DH 4096 test\n"); printf("\tdh8192 DH 8192 test\n"); printf("\taes128_cbc_hmac_sha1 AES128 CBC HMAC SHA1 test\n"); printf("\taes256_cbc_hmac_sha1 AES256 CBC HMAC SHA1 test\n"); printf("\taes128_cbc_hmac_sha256 AES128 CBC HMAC SHA256 test\n"); printf("\taes256_cbc_hmac_sha256 AES256 CBC HMAC SHA256 test\n"); /* ECDH options */ printf("\tecdhp192 ECDH P192 test\n"); printf("\tecdhp224 ECDH P224 test\n"); printf("\tecdhp256 ECDH P256 test\n"); printf("\tecdhp384 ECDH P384 test\n"); printf("\tecdhp521 ECDH P521 test\n"); printf("\tecdhk163 ECDH K163 test\n"); printf("\tecdhk233 ECDH K233 test\n"); printf("\tecdhk283 ECDH K283 test\n"); printf("\tecdhk409 ECDH K409 test\n"); printf("\tecdhk571 ECDH K571 test\n"); printf("\tecdhb163 ECDH B163 test\n"); printf("\tecdhb233 ECDH B233 test\n"); printf("\tecdhb283 ECDH B283 test\n"); printf("\tecdhb409 ECDH B409 test\n"); printf("\tecdhb571 ECDH B571 test\n"); printf("\tecdhsm2 ECDH SM2 test\n"); /* ECX options */ printf("\tecdhx25519 ECX25519 test\n"); printf("\tecdhx448 ECX448 test\n"); /* ECDSA options */ printf("\tecdsap192 ECDSA P192 test\n"); printf("\tecdsap224 ECDSA P224 test\n"); printf("\tecdsap256 ECDSA P256 test\n"); printf("\tecdsap384 ECDSA P384 test\n"); printf("\tecdsap521 ECDSA P521 test\n"); printf("\tecdsak163 ECDSA K163 test\n"); printf("\tecdsak233 ECDSA K233 test\n"); printf("\tecdsak283 ECDSA K283 test\n"); printf("\tecdsak409 ECDSA K409 test\n"); printf("\tecdsak571 ECDSA K571 test\n"); printf("\tecdsab163 ECDSA B163 test\n"); printf("\tecdsab233 ECDSA B233 test\n"); printf("\tecdsab283 ECDSA B283 test\n"); printf("\tecdsab409 ECDSA B409 test\n"); printf("\tecdsab571 ECDSA B571 test\n"); printf("\tprf PRF test\n"); printf("\thkdf HKDF test\n"); printf("\taes128gcm AES128 GCM test\n"); printf("\taes256gcm AES256 GCM test\n"); printf("\taes128ccm AES128 CCM test\n"); printf("\taes192ccm AES192 CCM test\n"); printf("\taes256ccm AES256 CCM test\n"); printf("\tsha3-224 SHA3 224 test\n"); printf("\tsha3-256 SHA3 256 test\n"); printf("\tsha3-384 SHA3 384 test\n"); printf("\tsha3-512 SHA3 512 test\n"); printf("\tsm3 SM3 test\n"); printf("\tsm4-cbc SM4 CBC test\n"); printf("\tsm4-gcm SM4 GCM test\n"); printf("\tsm4-ccm SM4 CCM test\n"); printf("\tchachapoly CHACHAPOLY test\n\n"); printf("\tsha2-224 SHA2 224 test\n"); printf("\tsha2-256 SHA2 256 test\n"); printf("\tsha2-384 SHA2 384 test\n"); printf("\tsha2-512 SHA2 512 test\n"); printf("\tsm2 SM2 test\n\n"); printf("\nIf test algo is not specified, default tests" "(RSA, ECDH, ECDSA) will be executed.\n"); /* In order to measure the maximum throughput from QAT, the iteration * test will repeat actual operation to keep QAT busy without reset * input variables such as initial vector. Thus, the iteration count should * limited to one for verification propose. */ printf("The test iteration count will set to 1 if the verify flag raised.\n\n"); exit(EXIT_SUCCESS); } /****************************************************************************** * function: * parse_option(int *index, * int argc, * char *argv[], * int *value) * * @param index [IN] - index pointer * @param argc [IN] - input argument count * @param argv [IN] - argument buffer * @param value [IN] - input value pointer * * description: * user input arguments check ******************************************************************************/ static void parse_option(int *index, int argc, char *argv[], int *value) { if (*index + 1 >= argc) { printf("\n# FAIL: Parameter expected\n"); usage(argv[0]); exit(EXIT_FAILURE); } (*index)++; *value = atoi(argv[*index]); } /****************************************************************************** * function: * parse_option_string(int *index, * int argc, * char *argv[], * char *str * * @param index [IN] - index pointer * @param argc [IN] - input argument count * @param argv [IN] - argument buffer * @param str [IN] - char * pointer to store the string * * description: * user input arguments check ******************************************************************************/ static void parse_option_string(int *index, int argc, char *argv[], char **str) { if (*index + 1 >= argc) { printf("\n# FAIL: Parameter expected\n"); usage(argv[0]); exit(EXIT_FAILURE); } (*index)++; *str = argv[*index]; } /****************************************************************************** * function: * handle_option(int argc, * char *argv[], * int *index) * * @param argc [IN] - input argument count * @param argv [IN] - argument buffer * @param index [IN] - index pointer * * description: * input operation handler ******************************************************************************/ static void handle_option(int argc, char *argv[], int *index) { char *option = argv[*index]; int i, size; if (!strcmp(option, "-n")) parse_option(index, argc, argv, &thread_count); else if (!strcmp(option, "-perf")) enable_perf = 1; #ifdef QAT_OPENSSL_3 else if (!strcmp(option, "-callback")) use_callback_mode = 1; #endif else if (!strcmp(option, "-epoll")) enable_event_driven_polling = 1; else if (!strcmp(option, "-poll")) enable_external_polling = 1; else if (!strcmp(option, "-c")) parse_option(index, argc, argv, &test_count); else if (!strcmp(option, "-af")) cpu_affinity = 1; else if (!strcmp(option, "-nc")) parse_option(index, argc, argv, &core_count); else if (!strcmp(option, "-engine")) { parse_option_string(index, argc, argv, &engine_id); enable_engine = 1; printf("[%s] engine enabled ! \n", engine_id); } else if (!strcmp(option, "-provider")) { parse_option_string(index, argc, argv, &prov_id); enable_provider = 1; printf("[%s] provider enabled ! \n", prov_id); } else if (!strcmp(option, "-p")) print_output = 1; else if (!strcmp(option, "-v")) verify = 1; else if (!strcmp(option, "-sign")) sign_only = 1; else if (!strcmp(option, "-verify")) verify_only = 1; else if (!strcmp(option, "-encrypt")) encrypt_only = 1; else if (!strcmp(option, "-decrypt")) decrypt_only = 1; else if (!strcmp(option, "dh")) test_alg = TEST_DH; else if (!strcmp(option, "prf")) test_alg = TEST_PRF; else if (!strcmp(option, "sm3")) test_alg = TEST_SM3; else if (!strcmp(option, "sm4-cbc")) test_alg = TEST_SM4_CBC; else if (!strcmp(option, "sm4-gcm")) test_alg = TEST_SM4_GCM; else if (!strcmp(option, "sm4-ccm")) test_alg = TEST_SM4_CCM; else if (!strcmp(option, "hkdf")) test_alg = TEST_HKDF; else if (!strcmp(option, "chachapoly")) { test_alg = TEST_CHACHA20_POLY1305; test_size = 4096; } else if (!strcmp(option, "sm2")){ test_alg = TEST_SM2; curve = P_CURVE_SM2; } else if (!strncmp(option, "rsa", strlen("rsa"))) { size = sizeof(rsa_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, rsa_choices[i].name)) { test_size = rsa_choices[i].test_size; test_alg = rsa_choices[i].test_alg; break; } } else if (!strncmp(option, "dsa", strlen("dsa"))) { size = sizeof(dsa_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, dsa_choices[i].name)) { test_size = dsa_choices[i].test_size; test_alg = dsa_choices[i].test_alg; break; } } else if (!strncmp(option, "dh", strlen("dh"))) { size = sizeof(dh_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, dh_choices[i].name)) { test_size = dh_choices[i].test_size; test_alg = dh_choices[i].test_alg; break; } } else if (!strncmp(option, "ecdh", strlen("ecdh"))) { size = sizeof(ecdh_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, ecdh_choices[i].name)) { printf ("name %s\n", ecdh_choices[i].name); curve = ecdh_choices[i].curve_name; test_alg = ecdh_choices[i].test_alg; break; } } else if (!strncmp(option, "ecdsa", strlen("ecdsa"))) { size = sizeof(ecdsa_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, ecdsa_choices[i].name)) { curve = ecdsa_choices[i].curve_name; test_alg = ecdsa_choices[i].test_alg; break; } } else if (!strncmp(option, "aes", strlen("aes"))) { size = sizeof(aes_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, aes_choices[i].name)) { test_alg = aes_choices[i].test_alg; break; } } else if (!strncmp(option, "sha3", strlen("sha3"))) { size = sizeof(sha3_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, sha3_choices[i].name)) { test_alg = sha3_choices[i].test_alg; test_size = 4096; break; } } else if (!strncmp(option, "sha2", strlen("sha2"))) { size = sizeof(sha2_choices) / sizeof(option_data); for (i = 0; i < size; i++) if (!strcmp(option, sha2_choices[i].name)) { test_alg = sha2_choices[i].test_alg; test_size = 4096; break; } } else if (!strcmp(option, "-f")) parse_option(index, argc, argv, &kdf); else if (!strcmp(option, "-x")) explicit_engine = 1; else if (!strcmp(option, "-z")) zero_copy = 1; else if (!strcmp(option, "-u")) cpu_core_info = 1; else if (!strcmp(option, "-tls_version")) parse_option_string(index, argc, argv, &tls_version); else if(!strcmp(option, "-ne")) enable_negative = 1; else if (!strcmp(option, "-di")) parse_option_string(index, argc, argv, &digest_kdf); else if (!strcmp(option, "-async_jobs")) { parse_option(index, argc, argv, &async_jobs); if (async_jobs <= 0) { printf("\n# FAIL: Invalid number of async_jobs.\n"); usage(argv[0]); exit(EXIT_FAILURE); } enable_async = 1; } else if (!strcmp(option, "-prf_op")) { parse_option(index, argc, argv, &prf_op); if (prf_op < 0 || prf_op > 4) { printf("\n# FAIL: Invalid prf_op number.\n"); usage(argv[0]); exit(EXIT_FAILURE); } } else if (!strcmp(option, "-hkdf_op")) { parse_option(index, argc, argv, &hkdf_op); if (hkdf_op < 0 || hkdf_op > 2) { printf("\n# FAIL: Invalid hkdf_op number.\n"); usage(argv[0]); exit(EXIT_FAILURE); } } else if (!strcmp(option, "-sw_fallback")) sw_fallback = 1; else if (!strcmp(option, "-h")) usage(argv[0]); else if (!strcmp(option, "-sw_algo")) { parse_option_string(index, argc, argv, &sw_algo_bitmap); } else if (!strcmp(option, "-hw_algo")) { parse_option_string(index, argc, argv, &hw_algo_bitmap); } else { printf("\n# FAIL: Invalid option '%s'\n", option); usage(argv[0]); exit(EXIT_FAILURE); } if (verify) { test_count = 1; core_count = 1; thread_count = 1; } } /****************************************************************************** * function: * *thread_worker(void *arg) * * @param arg [IN] - thread structure info * * description: * thread worker setups. the threads will launch at the same time after * all of them in ready condition. ******************************************************************************/ static void *thread_worker(void *arg) { THREAD_INFO *info = (THREAD_INFO *) arg; if (enable_engine && !enable_external_polling){ ENGINE_ctrl_cmd(engine,"SET_INSTANCE_FOR_THREAD",info->id,NULL,NULL,0); } /* mutex lock for thread count */ pthread_mutex_lock(&mutex); ready_thread_count++; pthread_cond_broadcast(&ready_cond); pthread_mutex_unlock(&mutex); /* waiting for thread clearance */ pthread_mutex_lock(&mutex); while (!cleared_to_start) pthread_cond_wait(&start_cond, &mutex); pthread_mutex_unlock(&mutex); tests_run(info->test_params, info->id); /* update active threads */ pthread_mutex_lock(&mutex); active_thread_count--; pthread_cond_broadcast(&stop_cond); pthread_mutex_unlock(&mutex); return NULL; } /****************************************************************************** * function: * performance_test(void) * * description: * performers test application running on user definition . ******************************************************************************/ static void performance_test(void) { int i, j; int coreID = 0; int sts = 1; qat_cpuset cpuset; struct timeval start_time; struct timeval stop_time; int elapsed = 0; unsigned long long rdtsc_start = 0; unsigned long long rdtsc_end = 0; int bytes_to_bits = 8; int crypto_ops_per_test = 1; float throughput = 0.0; char name[20]; THREAD_INFO *info = NULL; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&ready_cond, NULL); pthread_cond_init(&start_cond, NULL); pthread_cond_init(&stop_cond, NULL); for (i = 0; i < thread_count; i++) { info = &tinfo[i]; info->id = i; info->count = (test_count / thread_count) / async_jobs; info->test_params = OPENSSL_malloc(sizeof(TEST_PARAMS)); if (info->test_params == NULL) { WARN("# FAIL: Unable to allocate info->test_params\n"); exit(EXIT_FAILURE); } memset(info->test_params, 0, sizeof(TEST_PARAMS)); info->test_params->engine_id = engine_id; info->test_params->count = &info->count; info->test_params->type = test_alg; info->test_params->size = test_size; info->test_params->e = engine; info->test_params->print_output = print_output; info->test_params->verify = verify; info->test_params->performance = enable_perf; info->test_params->enable_external_polling = enable_external_polling; info->test_params->enable_event_driven_polling = enable_event_driven_polling; info->test_params->enable_async = enable_async; #ifdef QAT_OPENSSL_3 info->test_params->use_callback_mode = use_callback_mode; #endif info->test_params->enable_negative = enable_negative; info->test_params->curve = curve; info->test_params->kdf = kdf; info->test_params->tls_version = tls_version; info->test_params->digest_kdf = digest_kdf; info->test_params->explicit_engine = explicit_engine; info->test_params->sign_only = sign_only; info->test_params->verify_only = verify_only; info->test_params->encrypt_only = encrypt_only; info->test_params->decrypt_only = decrypt_only; info->test_params->async_jobs = async_jobs; info->test_params->prf_op = prf_op; info->test_params->hkdf_op = hkdf_op; info->test_params->jobs = OPENSSL_malloc(sizeof(ASYNC_JOB*)*async_jobs); if (info->test_params->jobs == NULL) { WARN("# FAIL: Unable to allocate info->test_params->jobs\n"); exit(EXIT_FAILURE); } info->test_params->awcs = OPENSSL_malloc( sizeof(ASYNC_WAIT_CTX*)*async_jobs); if (info->test_params->awcs == NULL) { WARN("# FAIL: Unable to allocate info->test_params->awcs\n"); exit(EXIT_FAILURE); } memset(info->test_params->jobs, 0, sizeof(ASYNC_JOB*)*async_jobs); memset(info->test_params->awcs, 0, sizeof(ASYNC_WAIT_CTX*)*async_jobs); for (j =0; j < async_jobs; j++) { info->test_params->awcs[j] = ASYNC_WAIT_CTX_new(); if (info->test_params->awcs[j] == NULL) { WARN("# FAIL: Unable to allocate info->test_params->awcs[%d]\n", j); exit(EXIT_FAILURE); } } pthread_create(&tinfo[i].th, NULL, thread_worker, (void *)&tinfo[i]); sprintf(name, "worker-%d", i); /* cpu affinity setup */ if (cpu_affinity == 1) { CPU_ZERO(&cpuset); /* assigning thread to different cores */ coreID = (i % core_count); CPU_SET(coreID, &cpuset); sts = pthread_setaffinity_np(info->th, sizeof(qat_cpuset), &cpuset); if (sts != 0) { WARN("# FAIL: pthread_setaffinity_np error, status = %d \n", sts); exit(EXIT_FAILURE); } sts = pthread_getaffinity_np(info->th, sizeof(qat_cpuset), &cpuset); if (sts != 0) { WARN("# FAIL: pthread_getaffinity_np error, status = %d \n", sts); exit(EXIT_FAILURE); } if (CPU_ISSET(coreID, &cpuset)) printf("Thread %d assigned on CPU core %d\n", i, coreID); } } /* set all threads to ready condition */ pthread_mutex_lock(&mutex); while (ready_thread_count < thread_count) pthread_cond_wait(&ready_cond, &mutex); pthread_mutex_unlock(&mutex); printf("Beginning test ....\n"); /* all threads start at the same time */ #ifdef __FreeBSD__ read_stat_systemctl(1); #else read_stat(1); #endif gettimeofday(&start_time, NULL); rdtsc_start = rdtsc(); pthread_mutex_lock(&mutex); cleared_to_start = 1; pthread_cond_broadcast(&start_cond); pthread_mutex_unlock(&mutex); /* wait for other threads stop */ pthread_mutex_lock(&mutex); while (active_thread_count > 0) pthread_cond_wait(&stop_cond, &mutex); pthread_mutex_unlock(&mutex); for (i = 0; i < thread_count; i++) { if (pthread_join(tinfo[i].th, NULL)) printf("Could not join thread id - %d !\n", i); } rdtsc_end = rdtsc(); gettimeofday(&stop_time, NULL); #ifdef __FreeBSD__ read_stat_systemctl(0); #else read_stat(0); #endif printf("All threads complete\n\n"); /* generate report */ elapsed = (stop_time.tv_sec - start_time.tv_sec) * 1000000 + (stop_time.tv_usec - start_time.tv_usec); /* Cipher tests contain 2 performOp calls. */ crypto_ops_per_test = 2; /* Cast test_size * test_count to avoid int overflow */ throughput = ((float)test_size * (float)test_count * (bytes_to_bits * crypto_ops_per_test) / (float)elapsed); printf("Elapsed time = %.3f msec\n", (float)elapsed / 1000); printf("Operations = %d\n", test_count); printf("Time per op = %.3f usec (%d ops/sec)\n", (float)elapsed / test_count, (int)((float)test_count * 1000000.0 / (float)elapsed)); printf("Elapsed cycles = %llu\n", rdtsc_end - rdtsc_start); printf("Throughput = %.2f (Mbps)\n", throughput); if (enable_engine){ ENGINE_ctrl_cmd(engine, "GET_NUM_OP_RETRIES", 0, &qatPerformOpRetries,NULL,0); printf("Retries = %d\n", qatPerformOpRetries); } printf("\nCSV summary:\n"); printf("Algorithm," "Test_type," "Using_engine," "Core_affinity," "Elapsed_usec," "Cores," "Threads," "Count," "Data_size," "Mbps," "CPU_time," "User_time," "Kernel_time\n"); int cpu_time = 0; int cpu_user = 0; int cpu_kernel = 0; #ifdef __FreeBSD__ cpu_time = (cpu_time_total.user + cpu_time_total.nice + cpu_time_total.sys + cpu_time_total.intr) * 10000 / core_count; #else cpu_time = (cpu_time_total.user + cpu_time_total.nice + cpu_time_total.sys + cpu_time_total.io + cpu_time_total.irq + cpu_time_total.softirq) * 10000 / core_count; #endif cpu_user = cpu_time_total.user * 10000 / core_count; cpu_kernel = cpu_time_total.sys * 10000 / core_count; printf("csv,%s,%d,%s,%s,%d,%d,%d,%d,%d,%.2f,%d,%d,%d\n", test_name(test_alg), test_alg, (enable_engine) ? "Yes" : "No", cpu_affinity ? "Yes" : "No", elapsed, core_count, thread_count, test_count, test_size, throughput, cpu_time * 100 / elapsed, cpu_user * 100 / elapsed, cpu_kernel * 100 / elapsed); for (i = 0; i < thread_count; i++) { info = &tinfo[i]; for (j =0; j < async_jobs; j++) ASYNC_WAIT_CTX_free(info->test_params->awcs[j]); if (info->test_params->awcs) OPENSSL_free(info->test_params->awcs); if (info->test_params->jobs) OPENSSL_free(info->test_params->jobs); if (info->test_params) OPENSSL_free(info->test_params); } } /****************************************************************************** * function: * functional_test(void) * * description: * Default testing application, a single thread test running through all the * test cases with testing function definition values ******************************************************************************/ static void functional_test(void) { int i; int count = 1; TEST_PARAMS args; args.engine_id = engine_id; args.count = &test_count; args.type = test_alg; args.size = test_size; args.e = engine; args.print_output = print_output; args.verify = verify; args.performance = enable_perf; args.enable_external_polling = enable_external_polling; args.enable_event_driven_polling = enable_event_driven_polling; args.enable_async = enable_async; #ifdef QAT_OPENSSL_3 args.use_callback_mode = use_callback_mode; #endif args.enable_negative = enable_negative; args.curve = curve; args.kdf = kdf; args.tls_version = tls_version; args.digest_kdf = digest_kdf; args.explicit_engine = explicit_engine; args.sign_only = sign_only; args.verify_only = verify_only; args.encrypt_only = encrypt_only; args.decrypt_only = decrypt_only; args.async_jobs = async_jobs; args.prf_op = prf_op; args.hkdf_op = hkdf_op; args.sw_fallback = sw_fallback; args.jobs = OPENSSL_malloc(sizeof(ASYNC_JOB*)*async_jobs); if (args.jobs == NULL) { WARN("# FAIL: Unable to allocate args.jobs\n"); exit(EXIT_FAILURE); } args.awcs = OPENSSL_malloc(sizeof(ASYNC_WAIT_CTX*)*async_jobs); if (args.awcs == NULL) { WARN("# FAIL: Unable to allocate args.awcs\n"); exit(EXIT_FAILURE); } memset(args.jobs, 0, sizeof(ASYNC_JOB*)*async_jobs); memset(args.awcs, 0, sizeof(ASYNC_WAIT_CTX*)*async_jobs); for (i =0; i < async_jobs; i++) { args.awcs[i] = ASYNC_WAIT_CTX_new(); if (args.awcs[i] == NULL) { WARN("# FAIL: Unable to allocate args.awcs[%d]\n", i); exit(EXIT_FAILURE); } } if (test_alg == 0) { args.size = DEFAULT_KEY_SIZE; args.verify = 1; args.count = &count; args.enable_negative = enable_negative; args.curve = P_CURVE_256; args.kdf = kdf; args.explicit_engine = explicit_engine; args.sign_only = 1; printf("\nResults for functional test cases: force variables:- \nverify = %d, count = %d, size = %d\n", args.verify, *(args.count), args.size); /* Default case, only run tests supported by both QAT_HW and QAT_SW */ for (i = 1; i <= TEST_ECX; i++) { args.type = i; tests_run(&args, 0); } } else if (test_alg == TEST_TYPE_MAX - 1) { args.count = &test_count; tests_run(&args, 0); } else { tests_run(&args, 0); } for (i =0; i < async_jobs; i++) ASYNC_WAIT_CTX_free(args.awcs[i]); OPENSSL_free(args.awcs); OPENSSL_free(args.jobs); } /****************************************************************************** * function: * main(int argc, * char *argv[]) * * @param argc [IN] - input argument count * @param argv [IN] - argument buffer * * description: * main function is used to setups QAT engine setups and define the testing * type. ******************************************************************************/ int main(int argc, char *argv[]) { int i = 0; tls_version = default_tls_string; digest_kdf = default_digest_string; QAT_DEBUG_LOG_INIT(); for (i = 1; i < argc; i++) { /* * allow rsa, dsa, dh, aes, prf, hkdf, sha-3 , chachapoly & ecx options * without '-' prefix */ if ((argv[i][0] != '-') && (argv[i][0] != 'r') && (argv[i][0] != 'd') && (argv[i][0] != 'a') && (argv[i][0] != 'e') && (argv[i][0] != 'p') && (argv[i][0] != 'h') && (argv[i][0] != 's') && (argv[i][0] != 'c')) break; handle_option(argc, argv, &i); } /* The thread count should not be great than the test count */ if (thread_count > test_count ) { thread_count = test_count; printf("\nWARNING - Thread Count cannot exceed the Test Count"); printf("\nThread Count adjusted to: %d\n\n", thread_count); } if (i < argc) { printf("# FAIL: This program does not take arguments, please use -h for usage.\n"); exit(EXIT_FAILURE); } active_thread_count = thread_count; ready_thread_count = 0; /* Zero Copy Mode is currently disabled */ if (zero_copy) { printf("Zero copy mode is currently disabled! Running in standard mode\n"); zero_copy = 0; } /* Load engine for workers */ if (enable_engine) { ENGINE_load_builtin_engines(); engine = tests_initialise_engine(engine_id, enable_external_polling, enable_event_driven_polling, enable_async, zero_copy, sw_fallback); if (!engine) { printf("# FAIL: ENGINE load error, exit! \n"); exit(EXIT_FAILURE); } } #ifdef QAT_OPENSSL_PROVIDER else if(enable_provider) { provider = tests_initialise_provider(prov_id); if (!provider) { fprintf(stderr, "# FAIL: Provider load error, exit! \n"); exit(EXIT_FAILURE); } } #endif else printf("Engine disabled! using software implementation\n"); printf("\nQAT Engine Test Application\n"); printf("\n\tCopyright (C) 2021-2025 Intel Corporation\n"); printf("\nTest Parameters:\n\n"); printf("\tTest Type: %s\n", enable_perf ? "Performance" : "Functional"); printf("\tTest Alg: %d (%s", test_alg, test_name(test_alg)); if (sign_only) printf(" sign"); if (verify_only) printf(" verify"); if (encrypt_only) printf(" encrypt"); if (decrypt_only) printf(" decrypt"); printf(")\n"); printf("\tTest Count: %d\n", test_count); printf("\tThread Count: %d\n", thread_count); printf("\tMessage Size: %d\n", test_size); printf("\tPrint Output: %s\n", print_output ? "Yes" : "No"); printf("\tCPU Core Affinity: %s\n", cpu_affinity ? "Yes" : "No"); printf("\tNumber of Cores: %d\n", core_count); printf("\tAsynchronous: %s\n", enable_async ? "Yes" : "No"); #ifdef QAT_OPENSSL_3 printf("\tUse asynch callback: %s\n", use_callback_mode ? "Yes" : "No"); #endif printf("\tExternal Polling: %s\n", enable_external_polling ? "Yes" : "No"); printf("\tEvent Driven Polling: %s\n", enable_event_driven_polling ? "Yes" : "No"); printf("\tEngine Enabled: %s\n", enable_engine ? "Yes" : "No"); printf("\tProvider Enabled: %s\n", enable_provider ? "Yes" : "No"); printf("\tForce Explicit Engine:%s\n", explicit_engine ? "Yes" : "No"); printf("\tNegative Scenario: %s\n", enable_negative ? "Yes" : "No"); printf("\tPRF TLS Version: %s\n", tls_version); if (strcmp(tls_version, "TLSv1_2") == 0) printf("\tKDF Digest: %s\n", digest_kdf); if (prf_op != -1) printf("\tPRF Operation: %d\n", prf_op); if (hkdf_op != -1) printf("\tHKDF Operation: %d\n", hkdf_op); printf("\tSW Fallback: %s\n", sw_fallback ? "Yes" : "No"); printf("\n"); if (!enable_perf) functional_test(); else performance_test(); if (engine) tests_cleanup_engine(engine, engine_id, enable_async, enable_external_polling, enable_event_driven_polling, sw_fallback); #ifdef QAT_OPENSSL_PROVIDER if (provider) tests_cleanup_provider(provider); #endif return 0; } qatengine-1.9.0/test/tests.c000066400000000000000000000654131500416242000157640ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #ifdef QAT_OPENSSL_PROVIDER #include #endif #include #define _GNU_SOURCE #define __USE_GNU #include #include "tests.h" #include "../qat_utils.h" # include # ifndef __FreeBSD__ # include # endif # define MAX_EVENTS 32 # define MAX_CRYPTO_INSTANCES 64 # define QAT_ENGINE_ID "qatengine" # define QAT_ENGINE_ID_LENGTH 9 typedef struct { int eng_fd; int (*eng_poll_handler_ptr) (ENGINE *eng, int *poll_status); } ENG_POLL_EVENT; #ifndef __FreeBSD__ static int efd = 0; struct epoll_event event[MAX_CRYPTO_INSTANCES]; static int no_of_inst = 0; #endif static int qat_keep_polling = 0; pthread_t *testapp_polling_threads; pthread_t *testapp_heartbeat_threads; int insecure_algorithms_enabled = 0; char *sw_algo_bitmap = NULL; char *hw_algo_bitmap = NULL; static int eng_poll_handler(ENGINE *eng, int *poll_status) { /* Poll for 0 means process all packets on the instance */ if (!ENGINE_ctrl_cmd(eng, "POLL", 0, &poll_status, NULL, 0)) { WARN("# FAIL: POLL not supported or failed\n"); return 0; } return 1; } static int eng_heartbeat_handler(ENGINE *eng, int *poll_status) { if (!ENGINE_ctrl_cmd(eng, "HEARTBEAT_POLL", 0, &poll_status, NULL, 0)) { WARN("# FAIL: HEARTBEAT_POLL not supported or failed\n"); return 0; } return 1; } #ifndef __FreeBSD__ /****************************************************************************** * function: * qat_epoll_engine(ENGINE* eng, struct epoll_event *events, int *poll_status, * int timeout) * * description: * In epoll for completion of async event. ******************************************************************************/ int qat_epoll_engine(ENGINE* eng, struct epoll_event *events, int *poll_status, int timeout) { int n = 0, i = 0; ENG_POLL_EVENT *eng_poll_event; n = epoll_wait(efd, events, MAX_EVENTS, timeout); for (i = 0; i < n; ++i) { if ((events[i].data.ptr) && (events[i].events & EPOLLIN)) { eng_poll_event = (ENG_POLL_EVENT *) events[i].data.ptr; if (!(eng_poll_event->eng_poll_handler_ptr(eng, poll_status))) { WARN("# FAIL: CTRL command not supported or failed\n"); return 0; } } } return 1; } static void *ePoll_loop(void *engine) { int poll_status = 0; ENGINE* eng = (ENGINE*)engine; int poll_interval = 1000; struct epoll_event *events = calloc(MAX_EVENTS, sizeof(struct epoll_event)); if (events == NULL) { WARN("# FAIL: Error allocating events\n"); return NULL; } while (qat_keep_polling) qat_epoll_engine(eng, events, &poll_status, poll_interval); free(events); return NULL; } #endif static void *poll_loop(void *engine) { int poll_status = 0; struct timespec reqTime = { 0 }; struct timespec remTime = { 0 }; unsigned int retry_count = 0; /* to prevent too much time drift */ while (qat_keep_polling) { reqTime.tv_nsec = 10000; eng_poll_handler(engine, &poll_status); retry_count = 0; do { retry_count++; nanosleep(&reqTime, &remTime); reqTime.tv_sec = remTime.tv_sec; reqTime.tv_nsec = remTime.tv_nsec; if ((errno < 0) && (EINTR != errno)) { WARN("# FAIL: nanosleep system call failed: errno %i\n", errno); break; } } while ((retry_count <= 4) && (EINTR == errno)); } return NULL; } static void *heartbeat_poll_loop(void *engine) { int poll_status = 0; struct timespec reqTime = { 0 }; struct timespec remTime = { 0 }; unsigned int retry_count = 0; /* to prevent too much time drift */ while (qat_keep_polling) { reqTime.tv_sec = 1; eng_heartbeat_handler(engine, &poll_status); retry_count = 0; do { retry_count++; nanosleep(&reqTime, &remTime); reqTime.tv_sec = remTime.tv_sec; reqTime.tv_nsec = remTime.tv_nsec; if ((errno < 0) && (EINTR != errno)) { WARN("# FAIL: nanosleep system call failed: errno %i\n", errno); break; } } while ((retry_count <= 4) && (EINTR == errno)); } return NULL; } #ifdef QAT_OPENSSL_3 static int test_callback(void *arg) { struct async_args_callback *args = (struct async_args_callback *)arg; DEBUG("test_callback start for async_job %d - job_ready = %d\n", args->i, args->job_ready); args->job_ready = 1; DEBUG("test_callback finish for async_job %d - job_ready = %d\n", args->i, args->job_ready); return 1; } #endif int start_async_job(TEST_PARAMS *args, int (*func)(void *)) { int ret = 0; int poll_status = 0; int jobs_inprogress = 0; int i = 0; OSSL_ASYNC_FD job_fd = 0; OSSL_ASYNC_FD max_fd = 0; int select_result = 0; size_t numfds; fd_set waitfdset; struct timeval select_timeout; FD_ZERO(&waitfdset); select_timeout.tv_sec = 0; select_timeout.tv_usec = 0; #ifdef QAT_OPENSSL_3 struct async_args_callback **ptr_async_args_callback = NULL; #endif #ifndef __FreeBSD__ struct epoll_event *events = calloc(MAX_EVENTS, sizeof(struct epoll_event)); if (events == NULL) { WARN("# FAIL: Error allocating memory events.\n"); return ret; } #endif DEBUG("start_async_job() - start\n"); #ifdef QAT_OPENSSL_3 if (args->use_callback_mode == 1) { ptr_async_args_callback = (struct async_args_callback **)OPENSSL_zalloc( sizeof(struct async_args_callback *)* args->async_jobs); if (ptr_async_args_callback == NULL) { WARN("# FAIL: Error allocating memory for ptr_async_args_callback.\n"); return ret; } for (i = 0; i < args->async_jobs; i++) { ptr_async_args_callback[i] = (struct async_args_callback *)OPENSSL_zalloc( sizeof(struct async_args_callback)); if (ptr_async_args_callback[i] == NULL) { WARN("# FAIL: Error allocating memory for ptr_async_args_callback array elements).\n"); return ret; } } } #endif for (i = 0; i < args->async_jobs; i++) { #ifdef QAT_OPENSSL_3 if (args->use_callback_mode == 1) { ptr_async_args_callback[i]->i = i; if (ASYNC_WAIT_CTX_set_callback(args->awcs[i], test_callback, (void *)ptr_async_args_callback[i]) != 1) { WARN("# FAIL: Error setting callback.\n"); return ret; } } #endif switch (ASYNC_start_job(&args->jobs[i], args->awcs[i], &ret, func, args, sizeof(TEST_PARAMS))) { case ASYNC_ERR: case ASYNC_NO_JOBS: DEBUG("ASYNC_ERR \n"); break; case ASYNC_PAUSE: ++jobs_inprogress; DEBUG("ASYNC_PAUSE \n"); break; case ASYNC_FINISH: DEBUG("ASYNC_FINISH \n"); break; } } while (jobs_inprogress > 0) { #ifdef QAT_OPENSSL_3 if (args->use_callback_mode != 1) { /* Not callback mode so use fd's */ #endif for (i = 0; i < args->async_jobs && jobs_inprogress > 0; i++) { if (args->jobs[i] == NULL) continue; if (!ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], NULL, &numfds) || numfds > 1) { WARN("# FAIL: Too Many FD's in Use\n"); break; } ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], &job_fd, &numfds); FD_SET(job_fd, &waitfdset); if (job_fd > max_fd) max_fd = job_fd; } if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) { WARN("# FAIL: Too many FD's in use in the system already\n"); break; } select_result = select(max_fd + 1, &waitfdset, NULL, NULL, &select_timeout); if (select_result == -1 && errno == EINTR) continue; if (select_result == -1) { WARN("# FAIL: Select Failure \n"); break; } if (select_result == 0) { if (args->e) { if (strncmp(args->engine_id, QAT_ENGINE_ID, QAT_ENGINE_ID_LENGTH) == 0) { if (args->enable_external_polling) { #ifndef __FreeBSD__ if (args->enable_event_driven_polling) { qat_epoll_engine(args->e, events, &poll_status, 0); } else eng_poll_handler(args->e, &poll_status); #else eng_poll_handler(args->e, &poll_status); #endif } } } continue; } #ifdef QAT_OPENSSL_3 } #endif for (i = 0; i < args->async_jobs; i++) { if (args->jobs[i] == NULL) continue; #ifdef QAT_OPENSSL_3 if (args->use_callback_mode != 1) { /* Not callback mode so use fd's */ #endif if (!ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], NULL, &numfds) || numfds > 1) { WARN("# FAIL: Too Many FD's in Use\n"); break; } ASYNC_WAIT_CTX_get_all_fds(args->awcs[i], &job_fd, &numfds); if (numfds == 1 && !FD_ISSET(job_fd, &waitfdset)) continue; #ifdef QAT_OPENSSL_3 } else { /* in callback mode */ if (ptr_async_args_callback[i]->job_ready == 0) continue; } if (args->use_callback_mode == 1) { /* reset the jobs_ready flag */ DEBUG("Resetting job_ready flag for async_job %d\n", i); ptr_async_args_callback[i]->job_ready = 0; } #endif switch (ASYNC_start_job(&args->jobs[i], args->awcs[i], &ret, func, args, sizeof(TEST_PARAMS))) { case ASYNC_PAUSE: break; case ASYNC_FINISH: --jobs_inprogress; args->jobs[i] = NULL; break; case ASYNC_NO_JOBS: case ASYNC_ERR: --jobs_inprogress; args->jobs[i] = NULL; break; } } if (args->e) { if (strncmp(args->engine_id, QAT_ENGINE_ID, QAT_ENGINE_ID_LENGTH) == 0) { if (args->enable_external_polling) { #ifndef __FreeBSD__ if (args->enable_event_driven_polling) qat_epoll_engine(args->e, events, &poll_status, 0); else eng_poll_handler(args->e, &poll_status); #else eng_poll_handler(args->e, &poll_status); #endif } } } } /* while (jobs_inprogress > 0) */ #ifndef __FreeBSD__ free(events); #endif #ifdef QAT_OPENSSL_3 if (ptr_async_args_callback != NULL) { for (i = 0; i < args->async_jobs; i++) { if (ptr_async_args_callback[i] != NULL) OPENSSL_free(ptr_async_args_callback[i]); } OPENSSL_free(ptr_async_args_callback); } #endif DEBUG("start_async_job() returning ret = %d\n", ret); return ret; } #ifdef QAT_OPENSSL_PROVIDER void tests_cleanup_provider(OSSL_PROVIDER *prov) { OSSL_PROVIDER_unload(prov); OPENSSL_cleanup(); DEBUG("QAT Provider Freed ! \n"); } OSSL_PROVIDER *tests_initialise_provider(const char *prov_id) { /* loading qatprovider */ OSSL_LIB_CTX *libctx = NULL; OSSL_PROVIDER *prov; OSSL_PROVIDER *deflt; DEBUG("Loading Provider ! \n"); prov = OSSL_PROVIDER_load(libctx, prov_id); OSSL_PROVIDER_set_default_search_path(libctx, prov_id); if (!prov) { fprintf(stderr,"# FAIL: Provider load failed, using default Provider!\n"); goto err; } deflt = OSSL_PROVIDER_load(NULL, "default"); if (!deflt) { fprintf(stderr,"# FAIL: default provider load failed\n"); goto err; } return prov; err: OSSL_LIB_CTX_free(libctx); OSSL_PROVIDER_unload(prov); return NULL; } #endif /****************************************************************************** * function: * tests_initialise_engine(char *engine_id, int enable_external_polling, * int enable_event_driven_polling, * int enable_async, int zero_copy, int sw_fallback) * * description: * QAT engine initialise functions, load up the QAT engine and set as the * default engine in OpenSSL. ******************************************************************************/ ENGINE *tests_initialise_engine(char *engine_id, int enable_external_polling, int enable_event_driven_polling, int enable_async, int zero_copy, int sw_fallback) { /* loading qat engine */ ENGINE *e = NULL; #ifndef __FreeBSD__ int instance_no = 0; #endif DEBUG("Loading Engine ! \n"); e = ENGINE_by_id(engine_id); if (!e) { WARN("# FAIL: Engine load failed, using default engine !\n"); return NULL; } if (strncmp(engine_id, QAT_ENGINE_ID, QAT_ENGINE_ID_LENGTH) == 0) { if (hw_algo_bitmap) { if (!ENGINE_ctrl_cmd(e, "HW_ALGO_BITMAP", 0, hw_algo_bitmap, NULL, 0)) { WARN("# FAIL: Unable to set hw algorithm mask\n"); goto err; } } if (sw_algo_bitmap) { if (!ENGINE_ctrl_cmd(e, "SW_ALGO_BITMAP", 0, sw_algo_bitmap, NULL, 0)) { WARN("# FAIL: Unable to set sw algorithm mask\n"); goto err; } } if (enable_event_driven_polling) { if (!ENGINE_ctrl_cmd(e, "ENABLE_EVENT_DRIVEN_POLLING_MODE", 0, NULL, NULL, 0)) { WARN("# FAIL: Unable to enable event driven polling mode on engine\n"); goto err; } } if (enable_external_polling) { if (!ENGINE_ctrl_cmd(e, "ENABLE_EXTERNAL_POLLING", 0, NULL, NULL, 0)) { WARN("# FAIL: Unable to enable polling on engine\n"); goto err; } } if (sw_fallback) { if (!ENGINE_ctrl_cmd(e, "ENABLE_SW_FALLBACK", 0, NULL, NULL, 0)) { WARN("# FAIL: Unable to enable sw fallback on engine\n"); goto err; } } } if (!ENGINE_init(e)) { WARN("# FAIL: Engine initialise failed ! using default engine\n"); goto err; } /* * Set QAT engine as the default engine for all except ciphers. * The Cipher test cases utilise both engine and SW implementation. * Setting Engine as default leaves no way of accessing the SW ones. */ ENGINE_set_default(e, (ENGINE_METHOD_ALL & ~(ENGINE_METHOD_CIPHERS))); if (strncmp(engine_id, QAT_ENGINE_ID, QAT_ENGINE_ID_LENGTH) == 0) { #ifndef __FreeBSD__ if (enable_external_polling && enable_event_driven_polling) { ENG_POLL_EVENT *eng_poll_event; int crypto_fd = 0; efd = epoll_create1(0); if (-1 == efd) { WARN("# FAIL: Error creating epoll fd\n"); goto err; } if (!ENGINE_ctrl_cmd(e, "GET_NUM_CRYPTO_INSTANCES", 0, &no_of_inst, NULL, 0)) { WARN("# FAIL: Retrieving the total number of instances failed\n"); goto err; } if (no_of_inst == 0) { WARN("# FAIL: No instances are available\n"); goto err; } for (instance_no = 0; instance_no < no_of_inst; instance_no++) { if (!ENGINE_ctrl_cmd(e, "GET_EXTERNAL_POLLING_FD", instance_no, &crypto_fd, NULL, 0)) { WARN("# FAIL: Unable to get polling fd for engine\n"); goto err; } eng_poll_event = malloc(sizeof(ENG_POLL_EVENT)); if (NULL == eng_poll_event) { WARN("# FAIL: Failed to malloc eng_poll_event in tests_initialise_engine()\n"); goto err; } eng_poll_event->eng_poll_handler_ptr = eng_poll_handler; eng_poll_event->eng_fd = crypto_fd; event[instance_no].events = EPOLLIN; event[instance_no].data.ptr = (void *)eng_poll_event; if (-1 == epoll_ctl(efd, EPOLL_CTL_ADD, crypto_fd, &event[instance_no])) { WARN("# FAIL: Error adding fd to epoll\n"); if (eng_poll_event) free(eng_poll_event); goto err; } eng_poll_event = NULL; } } #endif if (!enable_async && enable_external_polling) { qat_keep_polling = 1; testapp_polling_threads = (pthread_t *) OPENSSL_malloc(sizeof(pthread_t)); #ifndef __FreeBSD__ pthread_create(&testapp_polling_threads[0], NULL, enable_event_driven_polling ? ePoll_loop : poll_loop, (void *)e); #else pthread_create(&testapp_polling_threads[0], NULL, poll_loop, (void *)e); #endif } if (sw_fallback && enable_external_polling) { qat_keep_polling = 1; testapp_heartbeat_threads = (pthread_t *) OPENSSL_malloc(sizeof(pthread_t)); pthread_create(&testapp_heartbeat_threads[0], NULL, heartbeat_poll_loop, (void *)e); } } return e; err: ENGINE_free(e); return NULL; } /****************************************************************************** * function: * tests_cleanup_engine (ENGINE *e) * * @param e [IN] - OpenSSL engine pointer * * description: * QAT engine clean up function. ******************************************************************************/ void tests_cleanup_engine(ENGINE * e, char *engine_id, int enable_async, int enable_external_polling, int enable_event_driven_polling, int sw_fallback) { #ifndef __FreeBSD__ int i = 0; int crypto_fd = 0; ENG_POLL_EVENT *eng_poll_event; #endif if (strncmp(engine_id, QAT_ENGINE_ID, QAT_ENGINE_ID_LENGTH) == 0) { if (!enable_async && enable_external_polling) { qat_keep_polling = 0; pthread_join(testapp_polling_threads[0], NULL); if (testapp_polling_threads) OPENSSL_free(testapp_polling_threads); #ifndef __FreeBSD__ if (enable_event_driven_polling) { for (i = 0; i < no_of_inst; i++) { eng_poll_event = (ENG_POLL_EVENT *)event[i].data.ptr; crypto_fd = eng_poll_event->eng_fd; if (-1 == epoll_ctl(efd, EPOLL_CTL_DEL, crypto_fd, &event[i])) { WARN("# FAIL: Error removing fd from epoll\n"); } if (eng_poll_event) free(eng_poll_event); } } #endif } if (sw_fallback && enable_external_polling) { qat_keep_polling = 0; pthread_join(testapp_heartbeat_threads[0], NULL); if (testapp_heartbeat_threads) OPENSSL_free(testapp_heartbeat_threads); } } if (e) { /* Release the functional reference from ENGINE_init() */ ENGINE_finish(e); /* Release the structural reference from ENGINE_by_id() */ ENGINE_free(e); } DEBUG("QAT Engine Freed ! \n"); } /****************************************************************************** * function: * tests_hexdump (const char *title, * const unsigned char *s, * int l) * * @param title [IN] - hex dump title * @param s [IN] - input pointer * @param l [IN] - length of input * * description: * hex dump function. ******************************************************************************/ void tests_hexdump(const char *title, const unsigned char *s, int l) { int i = 0; printf("%s", title); for (i = 0; i < l; i++) { if ((i % 8) == 0) printf("\n "); printf("0x%02X, ", s[i]); } printf("\n\n"); } /****************************************************************************** * function: * tests_run (TEST_PARAMS *args, int id) * * @param args [IN] - the test parameters * * description: * select which test to run based on user input ******************************************************************************/ void tests_run(TEST_PARAMS *args, int id) { if (args->performance) { printf("\n|-----------------------------------------------------|\n"); printf("|----------Thread ID %d, running in progress-----------|\n", id); printf("|-----------------------------------------------------|\n"); } switch (args->type) { #if defined(QAT_SW) || defined(QAT_HW) /* * RSA sign, verify, encrypt and decrypt tests, input message length 124 * bytes */ case TEST_RSA: tests_run_rsa(args); break; case TEST_ECDH: /* ECDH test application */ tests_run_ecdh(args); break; case TEST_ECDSA: /* ECDSA test application */ tests_run_ecdsa(args); break; #ifndef OPENSSL_NO_SM2_SM3 case TEST_SM2: tests_run_sm2(args); /* SM2 test application */ break; case TEST_SM3: /* SM3 test application */ tests_run_sm3(args); break; #endif case TEST_AES128_GCM: tests_run_aes128_gcm(args); break; case TEST_AES256_GCM: tests_run_aes256_gcm(args); break; case TEST_AES128_CCM: tests_run_aes128_ccm(args); break; case TEST_AES192_CCM: tests_run_aes192_ccm(args); break; case TEST_AES256_CCM: tests_run_aes256_ccm(args); break; case TEST_ECX: /* X25519 & X448 test application */ tests_run_ecx(args); break; # if defined(ENABLE_QAT_SW_SM4_CBC) || defined(ENABLE_QAT_HW_SM4_CBC) case TEST_SM4_CBC: /* SM4_CBC test application */ tests_run_sm4_cbc(args); break; # endif # ifdef ENABLE_QAT_SW_SM4_GCM case TEST_SM4_GCM: /* SM4_GCM test application */ tests_run_sm4_gcm(args); break; # endif /* ENABLE_QAT_SW_SM4_GCM */ # ifdef ENABLE_QAT_SW_SM4_CCM case TEST_SM4_CCM: /* SM4_CCM test application */ tests_run_sm4_ccm(args); break; # endif #endif #ifdef QAT_HW /* DSA sign & verify tests, input message length 124 bytes */ case TEST_DSA: tests_run_dsa(args); break; /* DH tests, input message length 124 bytes */ case TEST_DH: tests_run_dh(args); break; case TEST_AES128_CBC_HMAC_SHA1: case TEST_AES256_CBC_HMAC_SHA1: case TEST_AES128_CBC_HMAC_SHA256: case TEST_AES256_CBC_HMAC_SHA256: tests_run_aes_cbc_hmac_sha(args); break; case TEST_PRF: /* PRF test application */ tests_run_prf(args); break; case TEST_HKDF: /* HKDF test application */ tests_run_hkdf(args); break; /* SHA3 tests */ case TEST_SHA3_224: case TEST_SHA3_256: case TEST_SHA3_384: case TEST_SHA3_512: tests_run_sha3(args); break; case TEST_CHACHA20_POLY1305: tests_run_chacha20_poly1305(args); break; #endif #ifdef QAT_SW /* SHA2 tests */ case TEST_SHA2_224: case TEST_SHA2_256: case TEST_SHA2_384: case TEST_SHA2_512: tests_run_sha2(args); break; #endif default: printf("# FAIL: Test type %d not supported\n", args->type); exit(EXIT_FAILURE); } if (args->performance) { printf("\n|-----------------------------------------------------|\n"); printf("|----------Thread ID %3d finished---------------------|\n", id); printf("|-----------------------------------------------------|\n"); } } qatengine-1.9.0/test/tests.h000066400000000000000000000141121500416242000157570ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #ifndef __TESTS_H #define __TESTS_H #include #ifdef QAT_OPENSSL_PROVIDER #include #endif extern int insecure_algorithms_enabled; enum { R_RSA_512, R_RSA_1024, R_RSA_2048, R_RSA_3072, R_RSA_4096, R_RSA_8192, R_RSA_7680, R_RSA_15360, RSA_NUM }; struct test_params_t { char *engine_id; int *count; int type; int size; ENGINE * e; int print_output; int verify; int performance; int enable_external_polling; int enable_event_driven_polling; int enable_async; const char *prov_id; #ifdef QAT_OPENSSL_PROVIDER OSSL_PROVIDER *prov; #endif EVP_PKEY_CTX *rsa_sign_ctx[RSA_NUM]; EVP_PKEY_CTX *rsa_verify_ctx[RSA_NUM]; EVP_PKEY_CTX *enc_ctx[RSA_NUM]; EVP_PKEY_CTX *dec_ctx[RSA_NUM]; #ifdef QAT_OPENSSL_3 int use_callback_mode; #endif int enable_negative; int curve; int kdf; char *tls_version; char *digest_kdf; int prf_op; int hkdf_op; int explicit_engine; int sign_only; int verify_only; int encrypt_only; int decrypt_only; int rsa_all; int padding; int async_jobs; ASYNC_JOB **jobs; ASYNC_WAIT_CTX **awcs; void *additional_args; int q_size; int sw_fallback; }; typedef struct test_params_t TEST_PARAMS; #ifdef QAT_OPENSSL_3 struct async_args_callback { int job_ready; int i; }; #endif ENGINE * tests_initialise_engine(char *engine_id, int enable_external_polling, int enable_event_driven_polling, int enable_async, int zero_copy, int sw_fallback); void tests_cleanup_engine(ENGINE *e, char *engine_id, int enable_async, int enable_external_polling, int enable_event_driven_polling, int sw_fallback); #ifdef QAT_OPENSSL_PROVIDER OSSL_PROVIDER *tests_initialise_provider(const char *prov_id); void tests_cleanup_provider(OSSL_PROVIDER *prov); #endif void tests_hexdump(const char *title, const unsigned char *s,int l); void tests_run(TEST_PARAMS *args, int id); void tests_run_rsa(TEST_PARAMS *args); void tests_run_dsa(TEST_PARAMS *args); void tests_run_dh(TEST_PARAMS *args); void tests_run_aes_cbc_hmac_sha(TEST_PARAMS *args); void tests_run_ecdh(TEST_PARAMS *args); void tests_run_ecdsa(TEST_PARAMS *args); void tests_run_prf(TEST_PARAMS *args); void tests_run_hkdf(TEST_PARAMS *args); void tests_run_ecx(TEST_PARAMS *args); void tests_run_aes128_gcm(TEST_PARAMS *args); void tests_run_aes256_gcm(TEST_PARAMS *args); void tests_run_aes128_ccm(TEST_PARAMS *args); void tests_run_aes192_ccm(TEST_PARAMS *args); void tests_run_aes256_ccm(TEST_PARAMS *args); void tests_run_sha3(TEST_PARAMS *args); void tests_run_sm3(TEST_PARAMS *args); void tests_run_chacha20_poly1305(TEST_PARAMS *args); void tests_run_sm4_cbc(TEST_PARAMS *args); void tests_run_sm4_gcm(TEST_PARAMS *args); void tests_run_sm4_ccm(TEST_PARAMS *args); void tests_run_sha2(TEST_PARAMS *args); void tests_run_sm2(TEST_PARAMS *args); char *ecdh_curve_name(int type); char *test_name(int test); int start_async_job(TEST_PARAMS *args, int (*func)(void *)); enum test_algorithms { TEST_RSA = 1, TEST_ECDH, TEST_ECDSA, TEST_ECX, TEST_DSA, TEST_DH, TEST_AES128_CBC_HMAC_SHA1, TEST_AES256_CBC_HMAC_SHA1, TEST_AES128_CBC_HMAC_SHA256, TEST_AES256_CBC_HMAC_SHA256, TEST_PRF, TEST_HKDF, TEST_AES128_GCM, TEST_AES256_GCM, TEST_AES128_CCM, TEST_AES192_CCM, TEST_AES256_CCM, TEST_SHA3_224, TEST_SHA3_256, TEST_SHA3_384, TEST_SHA3_512, TEST_CHACHA20_POLY1305, TEST_SM2, TEST_SM3, TEST_SM4_CBC, TEST_SM4_GCM, TEST_SM4_CCM, TEST_TYPE_MAX, TEST_SHA2_224, TEST_SHA2_256, TEST_SHA2_384, TEST_SHA2_512, }; enum curve_name { P_CURVE_192 = 1, P_CURVE_224, P_CURVE_256, P_CURVE_384, P_CURVE_521, K_CURVE_163, K_CURVE_233, K_CURVE_283, K_CURVE_409, K_CURVE_571, B_CURVE_163, B_CURVE_233, B_CURVE_283, B_CURVE_409, B_CURVE_571, P_CURVE_SM2, X_CURVE_25519, X_CURVE_448, CURVE_TYPE_MAX, }; enum key_name { KEY_2048_224 = 1, KEY_2048_256, KEY_TYPE_MAX }; #define SSL_MAX_DIGEST 6 enum ssl_version { SSLv3 = 1, TLSv1, TLSv1_1, TLSv1_2 }; #endif qatengine-1.9.0/test/tests_aes128_ccm.c000066400000000000000000000533011500416242000176620ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define AES_BLOCKSIZE 16 #define QAT_AES_CCM_TAG_MAX_LEN 16 #define INPUT_TEXT_SIZE 4096 static const unsigned char key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD }; /****************************************************************************** * function: * run_aesccm128_tls (void *args) * * @param args [IN] - the test parameters * * TLS: The API is used as in the TLS stack of OpenSSL. * The operations must be performed inplace and * the AAD must be added using the function ctrl. * * The ciphertext in the TLS case has the following format: * * +-------------+-----------------------------+-------+ * | explicit IV | ciphertext | tag | * +-------------+-----------------------------+-------+ * 8 size 16 *******************************************************************************/ static int run_aesccm128_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* For TLS enc: include the length of the explicit IV */ unsigned char length_byte1_tls_enc = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN) >> 8; unsigned char length_byte2_tls_enc = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN) | 16 >> 8; unsigned char tls_enc_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_enc, length_byte2_tls_enc }; /* For TLS dec: include the length of the explicit IV + TAG */ unsigned char length_byte1_tls_dec = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN) >> 8; unsigned char length_byte2_tls_dec = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN) | 16 >> 8; unsigned char tls_dec_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_dec, length_byte2_tls_dec }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_128_ccm); if (!c) { INFO("AES-128-CCM disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-CCM 128: input message", input, size); /* Create a new context for the TLS encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); exit(EXIT_FAILURE); } /* * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), NULL, NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, EVP_CCM_TLS_TAG_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IV_FIXED, EVP_CCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* set 16-byte of key to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), e, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_enc_virt_hdr), tls_enc_virt_hdr); if (ret != EVP_CCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* * In TLS case the explicit IV must be prepended to the plaintext * and there must be space to save the tag at the end of the buffer. */ plaintext_len += EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } memcpy(plaintext, iv + EVP_CCM_TLS_FIXED_IV_LEN, EVP_CCM_TLS_EXPLICIT_IV_LEN); memcpy(plaintext + EVP_CCM_TLS_EXPLICIT_IV_LEN, input, size); /* TLS case works only inplace */ ciphertext = plaintext; /* TLS Decrypt operation */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, plaintext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; if (print_output) tests_hexdump("AES-CCM 128 ciphertext:", ciphertext, ciphertext_len); /* The tag is contained in the last EVP_CCM_TLS_TAG_LEN Bytes of the payload */ memcpy(tag, ciphertext + EVP_CCM_TLS_EXPLICIT_IV_LEN + size, EVP_CCM_TLS_TAG_LEN); EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for TLS decrypt */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); exit(EXIT_FAILURE); } /* Initialise the context for decryption with 16-byte key and 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), NULL, NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IV_FIXED, EVP_CCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* set 16-byte of key to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), e, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_dec_virt_hdr), tls_dec_virt_hdr); if (ret != EVP_CCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* TLS case works only inplace */ dec_cipher = ciphertext; /* TLS Decrypt operation */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &dec_cipher_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-CCM 128 tag:", tag, EVP_CCM_TLS_TAG_LEN); /* In TLS case the first part of the output can be skipped */ dec_cipher += EVP_CCM_TLS_EXPLICIT_IV_LEN; if (print_output) tests_hexdump("AES-CCM 128 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, input, size)) { INFO("# FAIL verify for TLS AES128 CCM\n"); ret = 0; tests_hexdump("AES128CCM actual :", dec_cipher, size); tests_hexdump("AES128CCM expected:", plaintext, size); } else INFO("# PASS verify for TLS AES128 CCM\n"); } err: if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = NULL; } if (dec_ctx != NULL) { EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; } return ret; } /****************************************************************************** * function: * run_aesccm128_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * --------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * *****************************************************************************/ static int run_aesccm128_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; int ret = 0, i = 0; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_128_ccm); if (!c) { INFO("AES-128-CCM cipher disabled in QAT_Engine\n"); e = NULL; } } #endif /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-CCM: input message", input, size); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed while creating ctx\n", __func__); goto err; } /* Initialize encryption context for aes-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_aes_128_ccm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; } /* Set IV length to the aes-ccm context. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting IVLEN: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, EVP_CCM_TLS_TAG_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } #ifndef QAT_OPENSSL_PROVIDER /* set 16-byte of key to the aes-ccm context. */ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } #endif /* set 12-byte of iv to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; } plaintext = OPENSSL_malloc(size + (AES_BLOCKSIZE * 4)); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } ciphertext = plaintext; memcpy(plaintext, input, size); /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, size); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("AES-CCM ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for aes-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_aes_128_ccm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-ccm decryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } dec_cipher = ciphertext; /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len += tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-CCM enc tag:", tag, EVP_CCM_TLS_TAG_LEN); if (print_output) tests_hexdump("AES-CCM decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, size)) { INFO("# FAIL verify for AES CCM update\n"); ret = 0; tests_hexdump("AES-CCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("AES-CCM expected:", plaintext, size); } else INFO("# PASS verify for AES-CCM update\n"); } err: if (plaintext) OPENSSL_free(plaintext); if (input) OPENSSL_free(input); if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = NULL; } if (dec_ctx != NULL) { EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; } return ret; } void tests_run_aes128_ccm(TEST_PARAMS * args) { args->additional_args = NULL; if (args->enable_async) { start_async_job(args, run_aesccm128_update); start_async_job(args, run_aesccm128_tls); } else { run_aesccm128_update(args); run_aesccm128_tls(args); } } qatengine-1.9.0/test/tests_aes128_gcm.c000066400000000000000000000514221500416242000176700ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define AES128_BLOCKSIZE 16 /* 16 bytes key */ static const unsigned char key[] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x99, 0xaa, 0x3e, 0x68, /* fixed IV - 4 bytes */ 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84 /* explicit IV - 8 bytes */ }; /****************************************************************************** * function: * run_aesgcm128_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * ---------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * * This doesn't impact the TLS case because Update and Final are considered * a single operation like in the QAT engine. *****************************************************************************/ static int run_aesgcm128_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* 16 bytes additional authentication data. * AAD is not to be encrypted. It is passed along with the plaintext * and ciphertext to the recipient. */ const unsigned char aad[] = { 0x61, 0x31, 0xFF, 0x29, 0xCE, 0x13, 0x75, 0xBD, 0x72, 0xD2, 0x3A, 0x11, 0x55, 0x42, 0xBB, 0xFF }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_GCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e !=NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_128_gcm); if (!c) { INFO("AES-128-GCM cipher disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* Set input data */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-GCM 128: input message", input, size); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); goto err; } /* Initialize encryption context for aes-gcm-128 */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_aes_128_gcm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-gcm-128 encryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, e, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Pass AAD to the encryption context before encrypting the input plaintext. */ ret = EVP_EncryptUpdate(ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } plaintext = OPENSSL_malloc(size + (AES128_BLOCKSIZE * 4)); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } ciphertext = plaintext; memcpy(plaintext, input, size); /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, size); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("AES-GCM 128 ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for aes-gcm-128 */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_aes_128_gcm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_gcm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-gcm-128 decryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, e, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* AAD is passed to EVP_DecryptUpdate() with output buffer set to NULL */ ret = EVP_DecryptUpdate(dec_ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } dec_cipher = ciphertext; /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len = tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-GCM 128 tag:", tag, EVP_GCM_TLS_TAG_LEN); if (print_output) tests_hexdump("AES-GCM 128 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, size)) { INFO("# FAIL verify for AES128 GCM update\n"); ret = 0; tests_hexdump("AES128GCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("AES128GCM expected:", plaintext, size); } else INFO("# PASS verify for AES128 GCM update\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (input) OPENSSL_free(input); if (plaintext) OPENSSL_free(plaintext); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } /****************************************************************************** * function: * run_aesgcm128_tls (void *args) * * @param args [IN] - the test parameters * * TLS: The API is used as in the TLS stack of OpenSSL. * The operations must be performed inplace and * the AAD must be added using the function ctrl. * * The ciphertext in the TLS case has the following format: * * +-------------+-----------------------------+-------+ * | explicit IV | ciphertext | tag | * +-------------+-----------------------------+-------+ * 8 size 16 *******************************************************************************/ static int run_aesgcm128_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; ENGINE *e = temp_args->e; int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* For TLS enc: include the length of the explicit IV */ unsigned char length_byte1_tls_enc = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN) >> 8; unsigned char length_byte2_tls_enc = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN) |16 >> 8; unsigned char tls_enc_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_enc, length_byte2_tls_enc }; /* For TLS dec: include the length of the explicit IV + TAG */ unsigned char length_byte1_tls_dec = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN) >> 8; unsigned char length_byte2_tls_dec = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN) |16 >> 8; unsigned char tls_dec_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_dec, length_byte2_tls_dec }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_GCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_128_gcm); if (!c) { INFO("AES-128-GCM disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-GCM 128: input message", input, size); /* Create a new context for the TLS encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); exit(EXIT_FAILURE); } /* * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), e, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Specify the fixed part of the IV. * When arg_len == -1 the explicit part of the IV is copied * and not filled with random bytes */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_enc_virt_hdr), tls_enc_virt_hdr); if (ret != EVP_GCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* * In TLS case the explicit IV must be prepended to the plaintext * and there must be space to save the tag at the end of the buffer. */ plaintext_len += EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } memcpy(plaintext, iv + EVP_GCM_TLS_FIXED_IV_LEN, EVP_GCM_TLS_EXPLICIT_IV_LEN); memcpy(plaintext + EVP_GCM_TLS_EXPLICIT_IV_LEN, input, size); /* TLS case works only inplace */ ciphertext = plaintext; /* TLS Decrypt operation */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, plaintext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; if (print_output) tests_hexdump("AES-GCM 128 ciphertext:", ciphertext, ciphertext_len); /* The tag is contained in the last EVP_GCM_TLS_TAG_LEN Bytes of the payload */ memcpy(tag, ciphertext + EVP_GCM_TLS_EXPLICIT_IV_LEN + size, EVP_GCM_TLS_TAG_LEN); EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for TLS decrypt */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); exit(EXIT_FAILURE); } /* Initialise the context for decryption with 16-byte key and 12-byte IV. */ ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_gcm(), e, key, iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_IV_FIXED, EVP_GCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_dec_virt_hdr), tls_dec_virt_hdr); if (ret != EVP_GCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* TLS case works only inplace */ dec_cipher = ciphertext; /* TLS Decrypt operation */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &dec_cipher_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-GCM 128 tag:", tag, EVP_GCM_TLS_TAG_LEN); /* In TLS case the first part of the output can be skipped */ dec_cipher += EVP_GCM_TLS_EXPLICIT_IV_LEN; if (print_output) tests_hexdump("AES-GCM 128 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, input, size)) { INFO("# FAIL verify for TLS AES128 GCM\n"); ret = 0; tests_hexdump("AES128GCM actual :", dec_cipher, size); tests_hexdump("AES128GCM expected:", plaintext, size); } else INFO("# PASS verify for TLS AES128 GCM\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } void tests_run_aes128_gcm(TEST_PARAMS *args) { args->additional_args = NULL; if (args->enable_async) { start_async_job(args, run_aesgcm128_update); start_async_job(args, run_aesgcm128_tls); } else { run_aesgcm128_update(args); run_aesgcm128_tls(args); } } qatengine-1.9.0/test/tests_aes192_ccm.c000066400000000000000000000533651500416242000176750ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define AES_BLOCKSIZE 16 #define QAT_AES_CCM_TAG_MAX_LEN 16 #define INPUT_TEXT_SIZE 4096 static const unsigned char key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD }; /****************************************************************************** * function: * run_aesccm192_tls (void *args) * * @param args [IN] - the test parameters * * TLS: The API is used as in the TLS stack of OpenSSL. * The operations must be performed inplace and * the AAD must be added using the function ctrl. * * The ciphertext in the TLS case has the following format: * * +-------------+-----------------------------+-------+ * | explicit IV | ciphertext | tag | * +-------------+-----------------------------+-------+ * 8 size 16 *******************************************************************************/ static int run_aesccm192_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* For TLS enc: include the length of the explicit IV */ unsigned char length_byte1_tls_enc = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN) >> 8; unsigned char length_byte2_tls_enc = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN) | 16 >> 8; unsigned char tls_enc_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_enc, length_byte2_tls_enc }; /* For TLS dec: include the length of the explicit IV + TAG */ unsigned char length_byte1_tls_dec = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN) >> 8; unsigned char length_byte2_tls_dec = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN) | 16 >> 8; unsigned char tls_dec_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_dec, length_byte2_tls_dec }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_192_ccm); if (!c) { INFO("AES-192-CCM disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-CCM 192: input message", input, size); /* Create a new context for the TLS encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); exit(EXIT_FAILURE); } /* * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, EVP_CCM_TLS_TAG_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IV_FIXED, EVP_CCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* set 24-byte of key to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), e, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_enc_virt_hdr), tls_enc_virt_hdr); if (ret != EVP_CCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* * In TLS case the explicit IV must be prepended to the plaintext * and there must be space to save the tag at the end of the buffer. */ plaintext_len += EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } memcpy(plaintext, iv + EVP_CCM_TLS_FIXED_IV_LEN, EVP_CCM_TLS_EXPLICIT_IV_LEN); memcpy(plaintext + EVP_CCM_TLS_EXPLICIT_IV_LEN, input, size); /* TLS case works only inplace */ ciphertext = plaintext; /* TLS Decrypt operation */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, plaintext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; if (print_output) tests_hexdump("AES-CCM 192 ciphertext:", ciphertext, ciphertext_len); /* The tag is contained in the last EVP_CCM_TLS_TAG_LEN Bytes of the payload */ memcpy(tag, ciphertext + EVP_CCM_TLS_EXPLICIT_IV_LEN + size, EVP_CCM_TLS_TAG_LEN); EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for TLS decrypt */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); exit(EXIT_FAILURE); } /* Initialise the context for decryption with 24-byte key and 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), NULL, NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IV_FIXED, EVP_CCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* set 24-byte of key to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), e, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_dec_virt_hdr), tls_dec_virt_hdr); if (ret != EVP_CCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* TLS case works only inplace */ dec_cipher = ciphertext; /* TLS Decrypt operation */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &dec_cipher_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-CCM 192 tag:", tag, EVP_CCM_TLS_TAG_LEN); /* In TLS case the first part of the output can be skipped */ dec_cipher += EVP_CCM_TLS_EXPLICIT_IV_LEN; if (print_output) tests_hexdump("AES-CCM 192 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, input, size)) { INFO("# FAIL verify for TLS AES192 CCM\n"); ret = 0; tests_hexdump("AES192CCM actual :", dec_cipher, size); tests_hexdump("AES192CCM expected:", plaintext, size); } else INFO("# PASS verify for TLS AES192 CCM\n"); } err: if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = NULL; } if (dec_ctx != NULL) { EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; } return ret; } /****************************************************************************** * function: * run_aesccm192_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * --------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * *****************************************************************************/ static int run_aesccm192_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; int ret = 0, i = 0; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_192_ccm); if (!c) { INFO("AES-192-CCM cipher disabled in QAT_Engine\n"); e = NULL; } } #endif /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-CCM: input message", input, size); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed while creating ctx\n", __func__); goto err; } /* Initialize encryption context for aes-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_aes_192_ccm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; } /* Set IV length to the aes-ccm context. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting IVLEN: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, EVP_CCM_TLS_TAG_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } #ifndef QAT_OPENSSL_PROVIDER /* set 24-byte of key to the aes-ccm context. */ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } #endif /* set 12-byte of iv to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; } plaintext = OPENSSL_malloc(size + (AES_BLOCKSIZE * 4)); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } ciphertext = plaintext; memcpy(plaintext, input, size); /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, size); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("AES-CCM ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for aes-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_aes_192_ccm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_192_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-ccm decryption context with 24-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } dec_cipher = ciphertext; /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len += tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-CCM enc tag:", tag, EVP_CCM_TLS_TAG_LEN); if (print_output) tests_hexdump("AES-CCM decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, size)) { INFO("# FAIL verify for AES CCM update\n"); ret = 0; tests_hexdump("AES-CCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("AES-CCM expected:", plaintext, size); } else INFO("# PASS verify for AES-CCM update\n"); } err: if (plaintext) OPENSSL_free(plaintext); if (input) OPENSSL_free(input); if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = NULL; } if (dec_ctx != NULL) { EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; } return ret; } void tests_run_aes192_ccm(TEST_PARAMS * args) { args->additional_args = NULL; if (args->enable_async) { start_async_job(args, run_aesccm192_update); start_async_job(args, run_aesccm192_tls); } else { run_aesccm192_update(args); run_aesccm192_tls(args); } } qatengine-1.9.0/test/tests_aes256_ccm.c000066400000000000000000000534511500416242000176720ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define AES_BLOCKSIZE 16 #define QAT_AES_CCM_TAG_MAX_LEN 16 #define INPUT_TEXT_SIZE 4096 static const unsigned char key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD }; /****************************************************************************** * function: * run_aesccm256_tls (void *args) * * @param args [IN] - the test parameters * * TLS: The API is used as in the TLS stack of OpenSSL. * The operations must be performed inplace and * the AAD must be added using the function ctrl. * * The ciphertext in the TLS case has the following format: * * +-------------+-----------------------------+-------+ * | explicit IV | ciphertext | tag | * +-------------+-----------------------------+-------+ * 8 size 16 *******************************************************************************/ static int run_aesccm256_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* For TLS enc: include the length of the explicit IV */ unsigned char length_byte1_tls_enc = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN) >> 8; unsigned char length_byte2_tls_enc = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN) | 16 >> 8; unsigned char tls_enc_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_enc, length_byte2_tls_enc }; /* For TLS dec: include the length of the explicit IV + TAG */ unsigned char length_byte1_tls_dec = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN) >> 8; unsigned char length_byte2_tls_dec = (size + EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN) | 16 >> 8; unsigned char tls_dec_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_dec, length_byte2_tls_dec }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_256_ccm); if (!c) { INFO("AES-256-CCM disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-CCM 256: input message", input, size); /* Create a new context for the TLS encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); exit(EXIT_FAILURE); } /* * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, EVP_CCM_TLS_TAG_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IV_FIXED, EVP_CCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* set 32-byte of key to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), e, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_enc_virt_hdr), tls_enc_virt_hdr); if (ret != EVP_CCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* * In TLS case the explicit IV must be prepended to the plaintext * and there must be space to save the tag at the end of the buffer. */ plaintext_len += EVP_CCM_TLS_EXPLICIT_IV_LEN + EVP_CCM_TLS_TAG_LEN; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } memcpy(plaintext, iv + EVP_CCM_TLS_FIXED_IV_LEN, EVP_CCM_TLS_EXPLICIT_IV_LEN); memcpy(plaintext + EVP_CCM_TLS_EXPLICIT_IV_LEN, input, size); /* TLS case works only inplace */ ciphertext = plaintext; /* TLS Decrypt operation */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, plaintext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; if (print_output) tests_hexdump("AES-CCM 256 ciphertext:", ciphertext, ciphertext_len); /* The tag is contained in the last EVP_CCM_TLS_TAG_LEN Bytes of the payload */ memcpy(tag, ciphertext + EVP_CCM_TLS_EXPLICIT_IV_LEN + size, EVP_CCM_TLS_TAG_LEN); EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for TLS decrypt */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); exit(EXIT_FAILURE); } /* Initialise the context for decryption with 32-byte key and 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), NULL, NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IV_FIXED, EVP_CCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* set 32-byte of key to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), e, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed for setting key: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_dec_virt_hdr), tls_dec_virt_hdr); if (ret != EVP_CCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* TLS case works only inplace */ dec_cipher = ciphertext; /* TLS Decrypt operation */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &dec_cipher_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-CCM 256 tag:", tag, EVP_CCM_TLS_TAG_LEN); /* In TLS case the first part of the output can be skipped */ dec_cipher += EVP_CCM_TLS_EXPLICIT_IV_LEN; if (print_output) tests_hexdump("AES-CCM 256 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, input, size)) { INFO("# FAIL verify for TLS AES256 CCM\n"); ret = 0; tests_hexdump("AES256CCM actual :", dec_cipher, size); tests_hexdump("AES256CCM expected:", plaintext, size); } else INFO("# PASS verify for TLS AES256 CCM\n"); } err: if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = NULL; } if (dec_ctx != NULL) { EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; } return ret; } /****************************************************************************** * function: * run_aesccm256_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * --------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * *****************************************************************************/ static int run_aesccm256_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = INPUT_TEXT_SIZE; int print_output = temp_args->print_output; int verify = temp_args->verify; int ret = 0, i = 0; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_256_ccm); if (!c) { INFO("AES-256-CCM cipher disabled in QAT_Engine\n"); e = NULL; } } #endif /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-CCM: input message", input, size); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed while creating ctx\n", __func__); goto err; } /* Initialize encryption context for aes-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_aes_256_ccm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; } /* Set IV length to the aes-ccm context. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting IVLEN: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, EVP_CCM_TLS_TAG_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } #ifndef QAT_OPENSSL_PROVIDER /* set 32-byte of key to the aes-ccm context. */ ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } #endif /* set 12-byte of iv to the aes-ccm context. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; } plaintext = OPENSSL_malloc(size + (AES_BLOCKSIZE * 4)); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } ciphertext = plaintext; memcpy(plaintext, input, size); /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, size); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("AES-CCM ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for aes-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_aes_256_ccm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-ccm decryption context with 32-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } dec_cipher = ciphertext; /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len += tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-CCM enc tag:", tag, EVP_CCM_TLS_TAG_LEN); if (print_output) tests_hexdump("AES-CCM decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, size)) { INFO("# FAIL verify for AES CCM update\n"); ret = 0; tests_hexdump("AES-CCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("AES-CCM expected:", plaintext, size); } else INFO("# PASS verify for AES-CCM update\n"); } err: if (plaintext) OPENSSL_free(plaintext); if (input) OPENSSL_free(input); if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx); ctx = NULL; } if (dec_ctx != NULL) { EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; } return ret; } void tests_run_aes256_ccm(TEST_PARAMS * args) { args->additional_args = NULL; if (args->enable_async) { start_async_job(args, run_aesccm256_update); start_async_job(args, run_aesccm256_tls); } else { run_aesccm256_update(args); run_aesccm256_tls(args); } } qatengine-1.9.0/test/tests_aes256_gcm.c000066400000000000000000000517661500416242000177050ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define AES256_BLOCKSIZE 16 /* 32 bytes key */ static const unsigned char key[] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x99, 0xaa, 0x3e, 0x68, /* fixed IV - 4 bytes */ 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84 /* explicit IV - 8 bytes */ }; /****************************************************************************** * function: * run_aesgcm256_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * ---------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * * This doesn't impact the TLS case because Update and Final are considered * a single operation like in the QAT engine. *****************************************************************************/ static int run_aesgcm256_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* * 16 bytes additional authentication data. * AAD is not to be encrypted. It is passed along with the plaintext * and ciphertext to the recipient. */ const unsigned char aad[] = { 0x61, 0x31, 0xFF, 0x29, 0xCE, 0x13, 0x75, 0xBD, 0x72, 0xD2, 0x3A, 0x11, 0x55, 0x42, 0xBB, 0xFF }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_GCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_256_gcm); if (!c) { INFO("AES-256-GCM disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* Set input data */ for(i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-GCM 256: input message", input, size); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); goto err; } /* Initialize encryption context for aes-gcm-256 */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_aes_256_gcm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-gcm-256 encryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, e, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Pass AAD to the encryption context before encrypting the input plaintext. */ ret = EVP_EncryptUpdate(ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } plaintext = OPENSSL_malloc(size + (AES256_BLOCKSIZE * 4)); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } ciphertext = plaintext; memcpy(plaintext, input, size); /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, size); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* * Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("AES-GCM 256 ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for aes-gcm-256 */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_aes_256_gcm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_gcm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* * Initialise the aes-gcm-256 decryption context with 32-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, e, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* AAD is passed to EVP_DecryptUpdate() with output buffer set to NULL */ ret = EVP_DecryptUpdate(dec_ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } dec_cipher = ciphertext; /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len = tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-GCM 256 tag:", tag, EVP_GCM_TLS_TAG_LEN); if (print_output) tests_hexdump("AES-GCM 256 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, size)) { INFO("# FAIL verify for AES256 GCM update\n"); ret = 0; tests_hexdump("AES256GCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("AES256GCM expected:", plaintext, size); } else INFO("# PASS verify for AES256 GCM update\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } /****************************************************************************** * function: * run_aesgcm256_tls (void *args) * * @param args [IN] - the test parameters * * TLS: The API is used as in the TLS stack of OpenSSL. * The operations must be performed inplace and * the AAD must be added using the function ctrl. * * The ciphertext in the TLS case has the following format: * * +-------------+-----------------------------+-------+ * | explicit IV | ciphertext | tag | * +-------------+-----------------------------+-------+ * 8 size 16 *******************************************************************************/ static int run_aesgcm256_tls(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; ENGINE *e = temp_args->e; int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* For TLS enc: include the length of the explicit IV */ unsigned char length_byte1_tls_enc = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN) >> 8; unsigned char length_byte2_tls_enc = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN) |16 >> 8; unsigned char tls_enc_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_enc, length_byte2_tls_enc }; /* For TLS dec: include the length of the explicit IV + TAG */ unsigned char length_byte1_tls_dec = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN) >> 8; unsigned char length_byte2_tls_dec = (size + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN) |16 >> 8; unsigned char tls_dec_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_dec, length_byte2_tls_dec }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[EVP_GCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (e != NULL) { const EVP_CIPHER *c = ENGINE_get_cipher(e, NID_aes_256_gcm); if (!c) { INFO("AES-256-GCM disabled in QAT_Engine\n"); e = NULL; } } #endif if (input == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* * Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("AES-GCM 256: input message", input, size); /* Create a new context for the TLS encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); exit(EXIT_FAILURE); } /* * IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), e, key, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Specify the fixed part of the IV. * When arg_len == -1 the explicit part of the IV is copied * and not filled with random bytes */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_enc_virt_hdr), tls_enc_virt_hdr); if (ret != EVP_GCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* * In TLS case the explicit IV must be prepended to the plaintext * and there must be space to save the tag at the end of the buffer. */ plaintext_len += EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc for plaintext failed ! \n", __func__); goto err; } memcpy(plaintext, iv + EVP_GCM_TLS_FIXED_IV_LEN, EVP_GCM_TLS_EXPLICIT_IV_LEN); memcpy(plaintext + EVP_GCM_TLS_EXPLICIT_IV_LEN, input, size); /* TLS case works only inplace */ ciphertext = plaintext; /* TLS Decrypt operation */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, plaintext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; if (print_output) tests_hexdump("AES-GCM 256 ciphertext:", ciphertext, ciphertext_len); /* * The tag is contained in the last EVP_GCM_TLS_TAG_LEN Bytes of the * payload */ memcpy(tag, ciphertext + EVP_GCM_TLS_EXPLICIT_IV_LEN + size, EVP_GCM_TLS_TAG_LEN); EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for TLS decrypt */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); exit(EXIT_FAILURE); } /* Initialise the context for decryption with 16-byte key and 12-byte IV. */ ret = EVP_DecryptInit_ex(dec_ctx, EVP_aes_256_gcm(), e, key, iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Specify the fixed part of the IV */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_IV_FIXED, EVP_GCM_TLS_FIXED_IV_LEN, (void *)iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting IV: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_dec_virt_hdr), tls_dec_virt_hdr); if (ret != EVP_GCM_TLS_TAG_LEN) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* TLS case works only inplace */ dec_cipher = ciphertext; /* TLS Decrypt operation */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &dec_cipher_len, ciphertext, ciphertext_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("AES-GCM 256 tag:", tag, EVP_GCM_TLS_TAG_LEN); /* In TLS case the first part of the output can be skipped */ dec_cipher += EVP_GCM_TLS_EXPLICIT_IV_LEN; if (print_output) tests_hexdump("AES-GCM 256 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, input, size)) { INFO("# FAIL verify for TLS AES256 GCM\n"); ret = 0; tests_hexdump("AES256GCM actual :", dec_cipher, size); tests_hexdump("AES256GCM expected:", plaintext, size); } else INFO("# PASS verify for TLS AES256 GCM\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } void tests_run_aes256_gcm(TEST_PARAMS *args) { args->additional_args = NULL; if (args->enable_async) { start_async_job(args, run_aesgcm256_update); start_async_job(args, run_aesgcm256_tls); } else { run_aesgcm256_update(args); run_aesgcm256_tls(args); } } qatengine-1.9.0/test/tests_aes_cbc_hmac_sha.c000066400000000000000000001151351500416242000212430ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define ENC 1 #define DEC 0 #define USE_ENGINE 1 #define USE_SW 0 #define NON_TLS 0 #define EVP_FAIL -1 #define TLS_HDR_MODIFY_SEQ 0x01 #define NO_HMAC_KEY 0x02 #define NO_AAD 0x04 #define DEF_CFG 0x00 #define ENCRYPT_BUFF_ERROR 0 #define ENCRYPT_BUFF_IDENTICAL 1 #define ENCRYPT_BUFF_DIFFERENT 2 #define AES_CBC_BLOCK_SIZE 64 #define NUM_ENCRYPTION_ITERATIONS 6 #define FAIL_MSG(fmt, args...) WARN( "# FAIL " fmt, ##args) #define FAIL_MSG_END(fmt, args...) INFO( "# FAIL " fmt, ##args) #define PASS_MSG(fmt, args...) INFO( "# PASS " fmt, ##args) /* 32 bytes key */ static const unsigned char _key32[] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; /* 16 bytes key */ static const unsigned char _key16[] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; /* 16 bytes initial vector */ static unsigned char _ivec[] = { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 }; static unsigned char _hmac_key[] = { 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC }; /* TLS Version used to Test Chained Cipher. * 0 indicates NON-TLS use case. */ typedef struct _tls_v { int v; /* version */ const char *v_str; /* string format */ } tls_v; static const tls_v test_tls[] = { {TLS1_VERSION, "TLS1.0"}, {TLS1_1_VERSION, "TLS1.1"}, {TLS1_2_VERSION, "TLS1.2"}, {NON_TLS, "Non-TLS"} }; typedef struct _chained_alg_info { int testtype; /* Indicates the Chained cipher algorithm */ const EVP_CIPHER *(*pfunc) (void); /* function to get cipher object */ const unsigned char *key; /* Key to use for cipher op */ const char *name; /* Name to use in console messages */ } chained_alg_info; static const chained_alg_info alg_i[] = { {TEST_AES128_CBC_HMAC_SHA1, EVP_aes_128_cbc_hmac_sha1, _key16, "AES-128-CBC-HMAC-SHA1"}, {TEST_AES256_CBC_HMAC_SHA1, EVP_aes_256_cbc_hmac_sha1, _key32, "AES-256-CBC-HMAC-SHA1"}, {TEST_AES128_CBC_HMAC_SHA256, EVP_aes_128_cbc_hmac_sha256, _key16, "AES-128-CBC-HMAC-SHA256"}, {TEST_AES256_CBC_HMAC_SHA256, EVP_aes_256_cbc_hmac_sha256, _key32, "AES-256-CBC-HMAC-SHA256"} }; /* Structure to pass test information to functions */ typedef struct _test_info_ { int bufsz; int count; ENGINE *e; chained_alg_info *c; tls_v *tls; int sw_fallback; } test_info; /* get_alg_info: * for a given testtype, returns the related info structure. */ static const chained_alg_info *get_alg_info(int testtype) { const int num = sizeof(alg_i) / sizeof(chained_alg_info); int i; for (i = 0; i < num; i++) { if (alg_i[i].testtype == testtype) return &alg_i[i]; } return NULL; } /* * set_pkt_threshold: * Set the small packet threshold value for given cipher. * Buffers with size greater than the threshold value are * offloaded to QAT engine for processing. */ static inline int set_pkt_threshold(ENGINE *e, const char* cipher, int thr) { char thr_str[128]; int ret = 0; snprintf(thr_str, 128, "%s:%d", cipher, thr); ret = ENGINE_ctrl_cmd(e, "SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD", 0, (void *)thr_str, NULL, 0); if (ret != 1) PASS_MSG("threshold %d for cipher %s not supported\n", thr, cipher); return ret; } /* * compute_buff_size: * Depending on the version of TLS protocol, compute the * size of buffer needed for the packet. * Also finds the number of bytes used by IV */ int compute_buff_size(int size, unsigned int *ivlen, int pad, int tls_v, EVP_CIPHER_CTX *ctx) { *ivlen = 0; int len = 0; switch (tls_v) { case NON_TLS: /* Non-TLS case: Align size to block size */ len = (size + (EVP_CIPHER_CTX_block_size(ctx) - 1)) & ~(EVP_CIPHER_CTX_block_size(ctx) - 1); break; case TLS1_1_VERSION: case TLS1_2_VERSION: /* For TLS Versions >= 1.1, Add room for iv in buffers */ *ivlen = EVP_CIPHER_CTX_iv_length(ctx); case TLS1_VERSION: /* * increase the size by amount of DIGEST len and padding * plus ivlen */ len = size + (pad + *ivlen); break; default: len = 0; *ivlen = 0; } return len; } /* * setup_ctx: * Setup cipher context ready to be used in a cipher operation. * It also sets up additional information required i.e. tls headers. */ static EVP_CIPHER_CTX *setup_ctx(const test_info *t, int enc, int e, int *pad, int cfg) { int padlen = 0; EVP_CIPHER_CTX *ctx = NULL; unsigned int size = t->bufsz; unsigned char tls_hdr[] = { 0x00, 0x00, 0x00, 0x00, /* TLS Seq */ 0x00, 0x00, 0x00, 0x00, /* of 8Bytes */ /* Record Type, Major, Minor, Len-MSB, Len-LSB */ 0x16, 0x03, 0x00, 0x00, 0x00 }; if (pad != NULL) *pad = 0; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return NULL; #ifdef QAT_OPENSSL_PROVIDER EVP_CIPHER *sw_cipher = EVP_CIPHER_fetch(NULL, t->c->name, e == USE_SW ? "provider=default" : ""); if (sw_cipher == NULL) goto err; if (!EVP_CipherInit_ex2(ctx, sw_cipher, t->c->key, t->tls->v >= TLS1_1_VERSION && enc == 0 ? NULL : _ivec, enc, NULL)){ EVP_CIPHER_free(sw_cipher); goto err; } #else if (EVP_CipherInit_ex(ctx, t->c->pfunc(), e == USE_ENGINE ? t->e : NULL, t->c->key, t->tls->v >= TLS1_1_VERSION && enc == 0 ? NULL : _ivec, enc) != 1) goto err; #endif /* call the EVP API to set up the HMAC key */ if (!(cfg & NO_HMAC_KEY)) EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(_hmac_key), _hmac_key); if (!(cfg & NO_AAD) && t->tls->v != 0) { /* * For tls >= 1.1, iv is prepenned to the payload. * Encoded size in header passed to control message * includes this length as well. */ if (t->tls->v >= TLS1_1_VERSION) size += EVP_CIPHER_CTX_iv_length(ctx); /* Set up TLS Header */ tls_hdr[10] = t->tls->v & 0xff; tls_hdr[11] = (size & 0xff00) >> 8; tls_hdr[12] = size & 0x00ff; /* * Change a byte in sequence number for * second header so it is different from first. */ if (cfg & TLS_HDR_MODIFY_SEQ) tls_hdr[1] = 0xA3; /* get the TLS record padding size */ padlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_hdr), (void *)tls_hdr); } if (pad != NULL) *pad = padlen; return ctx; err: EVP_CIPHER_CTX_free(ctx); return NULL; } /* * perform_op: * performs the following operations: * 1. Allocate buffers for input and output. * 2. Populate input buffer with sample data. * 3. Perform cipher operation (populates output buffer) * 4. Convey result, numbytes operated and allocated buffers */ static int perform_op(EVP_CIPHER_CTX *ctx, unsigned char **in, unsigned char **out, unsigned int size, int *nbytes, int tls) { int s, i; int ret = 0; unsigned int ivlen = 0; unsigned char *inb = NULL; unsigned char *outb = NULL; int enc = EVP_CIPHER_CTX_encrypting(ctx); if (in == NULL || out == NULL || nbytes == NULL) return 0; *nbytes = 0; if (tls >= TLS1_1_VERSION) ivlen = EVP_CIPHER_CTX_iv_length(ctx); /* Allocate and fill src buffer if encrypting */ if (enc == 1 && *in == NULL) { *in = inb = OPENSSL_malloc(size + AES_CBC_BLOCK_SIZE); if (inb == NULL) return 0; /* In case of TLS < 1.1, this a zero byte copy */ memcpy(inb, _ivec, ivlen); /* setup input message values */ for (i = ivlen; i < size; i++) inb[i] = i % 16; } else { /* Decrypt the src buffer contents */ inb = *in; } if (*out == NULL) { *out = outb = inb; if (outb == NULL) goto err; } else { outb = *out; } /* perform the operation */ s = EVP_CipherUpdate(ctx, outb, nbytes, inb, size); if (s != 1) { ret = EVP_FAIL; goto err; } return 1; err: return ret; } /* * encrypt_buff : * For a given TLS version, allocate and encrypt * buffer. Return pointers to buffers along with * number of bytes encrypted and ivlen used. */ static int encrypt_buff(const test_info *t, int impl, unsigned char **buf, unsigned char **encbuf, int *num_encbytes, unsigned int *ivlen) { int ret = 0; int pad = 0; int size = t->bufsz; char msgstr[128]; EVP_CIPHER_CTX *ctx = NULL; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: %s encrypt %s] ", t->c->name, impl == USE_ENGINE ? "ENG" : "SW", t->tls->v_str); /* setup ctx for encryption */ if (t->tls->v == NON_TLS) ctx = setup_ctx(t, ENC, impl, &pad, DEF_CFG | NO_HMAC_KEY); else ctx = setup_ctx(t, ENC, impl, &pad, DEF_CFG); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } /* Compute the size of the buffer needed for this TLS use case */ size = compute_buff_size(size, ivlen, pad, t->tls->v, ctx); ret = perform_op(ctx, buf, encbuf, size, num_encbytes, t->tls->v); if (ret == 1 && *num_encbytes != size) printf("%s: nbytes %d != outl %d\n", msgstr, *num_encbytes, size); EVP_CIPHER_CTX_free(ctx); return ret; } /* * decrypt_buff : * Given a pointer to encrypted buffer encbuf, decrypt using * implementation as specified by impl. */ static int decrypt_buff(const test_info *t, int impl, unsigned char **encbuf, unsigned char **decbuf, int len) { int ret = 0; int num_decbytes = 0; char msgstr[128]; EVP_CIPHER_CTX *ctx = NULL; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: %s decrypt %s] ", t->c->name, impl == USE_ENGINE ? "ENG" : "SW", t->tls->v_str); /* initialise ctx for decryption */ if (t->tls->v == NON_TLS) ctx = setup_ctx(t, DEC, impl, NULL, DEF_CFG | NO_HMAC_KEY); else ctx = setup_ctx(t, DEC, impl, NULL, DEF_CFG); if (ctx == NULL) { FAIL_MSG("%s failed to setup dec context\n", msgstr); return -1; } ret = perform_op(ctx, encbuf, decbuf, len, &num_decbytes, t->tls->v); EVP_CIPHER_CTX_free(ctx); return ret; } /* * encrypt_and_compare : * Encrypt a test buffer using engine and openssl sw * implementation. Compare the output and return * ENCRYPT_BUFF_ERROR : Error * ENCRYPT_BUFF_IDENTICAL : ENC buffers are byte identical * ENCRYPT_BUFF_DIFFERENT : ENC buffers not byte identical * for first ivlen bytes and engine * enc buffer has explicit IV as plain text. */ static int encrypt_and_compare(const test_info *t, int *buflen) { int ret = ENCRYPT_BUFF_ERROR; unsigned char *textbuf = NULL; unsigned char *eng_buf = NULL; unsigned char *sw_buf = NULL; int eng_opbytes, sw_opbytes; unsigned int ivlen = 0; if ( t == NULL || buflen == NULL) return ret; *buflen = 0; if (encrypt_buff(t, USE_ENGINE, &textbuf, &eng_buf, &eng_opbytes, &ivlen) != 1) { FAIL_MSG("%s:%s failed to perform Encryption using Engine!\n", __func__, t->tls->v_str); goto err; } if (encrypt_buff(t, USE_SW, &textbuf, &sw_buf, &sw_opbytes, &ivlen) != 1) { FAIL_MSG("%s:%s failed to perform Encryption using SW!\n", __func__, t->tls->v_str); goto err; } if (eng_opbytes != sw_opbytes) { FAIL_MSG("%s: %s Num Encrypted bytes Engine[%d] != SW[%d]\n", __func__, t->tls->v_str, eng_opbytes, sw_opbytes); goto err; } *buflen = eng_opbytes; /* * OpenSSL SW implementation encrypts the Explicit IV and PAYLOAD * using the IV placed in CTX which may or maynot be explicit IV. * whereas QAT engine encrypts the PAYLOAD alone using the * Explicit IV. Hence the encrypted bytes differ. * This is true for TLS >= 1.1 */ if (!memcmp(eng_buf, sw_buf, eng_opbytes)) { /* the buffers are byte identical for entire length */ ret = ENCRYPT_BUFF_IDENTICAL; } else if (memcmp(eng_buf, sw_buf, ivlen) && !memcmp(eng_buf, _ivec, ivlen)) { /* * first ivlen bytes are different i.e. Openssl SW enc buffer encrypts the * explicit IV whereas QAT engine sends the explicit IV in clear text */ ret = ENCRYPT_BUFF_DIFFERENT; } else { /* * explicit IV encoded is byte identical but encrypted payload is * different. This is an error condition. */ FAIL_MSG("[%s:%s:%s]verify failed for ENGINE and SW Encrypt", __func__, t->tls->v_str, t->c->name); tests_hexdump("AES*-CBC-HMAC-SHA* ENGINE :", eng_buf, eng_opbytes); tests_hexdump("AES*-CBC-HMAC-SHA* SW:", sw_buf, eng_opbytes); ret = ENCRYPT_BUFF_ERROR; } err: OPENSSL_free(textbuf); return ret; } /* * test_crypto_op : * test chained ciphers crypto operation. * depending on the enc_imp/dec_imp, use either a engine or * software implementation to perform encryption/decryption. * if DEC_imp(ENC_imp(text)) = text, then report success else * fail. */ static int test_crypto_op(const test_info *t, int enc_imp, int dec_imp) { int ret = 0; unsigned int ivlen = 0; int num_encbytes; unsigned char *textbuf = NULL; unsigned char *encbuf = NULL; unsigned char *decbuf = NULL; char msgstr[128]; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: %s encrypt %s decrypt for %s] ", t->c->name, enc_imp == USE_ENGINE ? "ENG" : "SW", dec_imp == USE_ENGINE ? "ENG" : "SW", t->tls->v_str); /* Get an encrypted buffer along with it's plain text */ ret = encrypt_buff(t, enc_imp, &textbuf, &encbuf, &num_encbytes, &ivlen); if (ret != 1) { FAIL_MSG("%s failed to perform Encryption!\n", msgstr); goto err; } /* Decrypt the encrypted buffer above and get decrpyted contents */ ret = decrypt_buff(t, dec_imp, &encbuf, &decbuf, num_encbytes); if (ret != 1) { FAIL_MSG("%s failed to perform Decryption!\n", msgstr); goto err; } /* Compare and verify the decrypt and encrypt message. */ if (memcmp(decbuf + ivlen, textbuf + ivlen, t->bufsz)) { FAIL_MSG("verify failed for %s", msgstr); tests_hexdump("AES*-CBC-HMAC-SHA* actual :", decbuf + ivlen, t->bufsz); tests_hexdump("AES*-CBC-HMAC-SHA* expected:", textbuf + ivlen, t->bufsz); goto err; } ret = 1; err: OPENSSL_free(textbuf); return ret; } /* * test_no_hmac_key : * Do not set HMAC key and test behaviour of cipher operation. */ int test_no_hmac_key_set(const test_info *t) { int ret = 0; int pad = 0; int size = t->bufsz; char msgstr[128]; unsigned int ivlen; int num_encbytes; unsigned char *buf = NULL; unsigned char *encbuf = NULL; EVP_CIPHER_CTX *ctx = NULL; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: ENG Test %s with NO HMAC key set] ", t->c->name, t->tls->v_str); /* setup ctx for encryption */ ctx = setup_ctx(t, ENC, USE_ENGINE, &pad, DEF_CFG | NO_HMAC_KEY); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } /* Compute the size of the buffer needed for this TLS use case */ size = compute_buff_size(size, &ivlen, pad, t->tls->v, ctx); /* Encrypt operation should be successful */ ret = perform_op(ctx, &buf, &encbuf, size, &num_encbytes, t->tls->v); if (ret != 1) { FAIL_MSG("%s failed to perform Encryption!\n", msgstr); goto err; } if (ret == 1 && num_encbytes != size) FAIL_MSG("%s: nbytes %d != outl %d\n", msgstr, num_encbytes, size); err: EVP_CIPHER_CTX_free(ctx); OPENSSL_free(buf); return ret; } /* * test_multi_op : * Perform the cipher operation multiple times with the same ctx. */ int test_multi_op(const test_info *t) { int ret = 0; int pad = 0; unsigned int ivlen = 0; int size = t->bufsz; char msgstr[128]; int i = 0; EVP_CIPHER_CTX *ctx = NULL; unsigned char *buf[NUM_ENCRYPTION_ITERATIONS] = { NULL }; unsigned char *ebuf[NUM_ENCRYPTION_ITERATIONS] = { NULL }; int num_encbytes[NUM_ENCRYPTION_ITERATIONS] = { 0 }; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: multi op %s] ", t->c->name, t->tls->v_str); ctx = setup_ctx(t, ENC, USE_SW, &pad, DEF_CFG); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } /* Compute the size of the buffer needed for this TLS use case */ size = compute_buff_size(size, &ivlen, pad, t->tls->v, ctx); for (i = 0; i < NUM_ENCRYPTION_ITERATIONS; i++) { ret = perform_op(ctx, &buf[i], &ebuf[i], size, &num_encbytes[i], t->tls->v); if (ret != 1) { FAIL_MSG("%s: Failed to encrypt %d time", msgstr, i); goto err; } if (ret == 1 && num_encbytes[i] != size) printf("%s[%d time]: nbytes %d != outl %d\n", msgstr, i, num_encbytes[i], size); } err: EVP_CIPHER_CTX_free(ctx); for (i = 0; i < NUM_ENCRYPTION_ITERATIONS; i++) { OPENSSL_free(buf[i]); } return ret; } int test_performance_encrypt(const test_info *t) { int ret = 0; int pad = 0; unsigned int ivlen = 0; int size = t->bufsz; char msgstr[128]; int i = 0; EVP_CIPHER_CTX *ctx = NULL; unsigned char *buf = NULL; unsigned char *ebuf = NULL; int num_encbytes = 0; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: perf enc %s] ", t->c->name, t->tls->v_str); ctx = setup_ctx(t, ENC, USE_ENGINE, &pad, DEF_CFG); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } /* Compute the size of the buffer needed for this TLS use case */ size = compute_buff_size(size, &ivlen, pad, t->tls->v, ctx); for (i = 0; i < t->count; i++) { ret = perform_op(ctx, &buf, &ebuf, size, &num_encbytes, t->tls->v); if (ret != 1) { FAIL_MSG("%s: Failed to encrypt %d time", msgstr, i); goto err; } if (ret == 1 && num_encbytes != size) printf("%s[%d time]: nbytes %d != outl %d\n", msgstr, i, num_encbytes, size); } err: EVP_CIPHER_CTX_free(ctx); OPENSSL_free(buf); OPENSSL_free(ebuf); return ret; } /* * test_encrpted_buffer : * Encrypty buffer using ENGINE and Openssl SW * implementation and check if they are byte identical. */ int test_encrypted_buffer(const test_info *t) { int ret = 0; int buflen = 0; ret = encrypt_and_compare(t, &buflen); if (ret == ENCRYPT_BUFF_ERROR) { FAIL_MSG("Failed to perform encrypt and compare operation for %s:%s\n", t->tls->v_str, t->c->name); return ret; } if (t->tls->v < TLS1_1_VERSION && ret != ENCRYPT_BUFF_IDENTICAL) { /* * There is no explicit IV, so the encrypted buffers should * byte match. */ FAIL_MSG("verify failed ENGINE and SW Encrypt" " does match for %s for %s\n", t->tls->v_str, t->c->name); } else { ret = 1; } return ret; } /* * test_auth_header : * TLS header is used in calculation of HMAC code. * Any change in header should result in AUTH failure. * This function tests this by using changing headers * between encryption and decryption. */ static int test_auth_header(const test_info *t, int impl) { int ret = 0; unsigned int ivlen = 0; int num_encbytes, num_decbytes; unsigned char *textbuf = NULL; unsigned char *encbuf = NULL; unsigned char *decbuf = NULL; EVP_CIPHER_CTX *ctx = NULL; char msgstr[128]; snprintf(msgstr, 128, "[%s:%s:%s] ", __func__, t->tls->v_str, impl == USE_ENGINE ? "ENG" : "SW"); /* * There is no AUTH info for NON_TLS use case. * Pass by default */ if (t->tls->v == NON_TLS) return 1; /* Get an encrypted buffer along with it's plain text */ ret = encrypt_buff(t, impl, &textbuf, &encbuf, &num_encbytes, &ivlen); if (ret != 1) { FAIL_MSG("%s failed to perform Encryption!\n", msgstr); goto err; } /* * Setup ctx for decryption and use control message to setup * a different TLS header than for encryption */ ctx = setup_ctx(t, DEC, impl, NULL, TLS_HDR_MODIFY_SEQ); if (ctx == NULL) { FAIL_MSG("%s failed to setup dec context\n", msgstr); goto err; } /* * Perform decryption, followed by authentication which should * fail. */ ret = perform_op(ctx, &encbuf, &decbuf, num_encbytes, &num_decbytes, t->tls->v); if (ret != EVP_FAIL) { FAIL_MSG("%s Decrypt+Auth did not fail\n", msgstr); ret = 0; goto err; } ret = 1; err: EVP_CIPHER_CTX_free(ctx); OPENSSL_free(textbuf); return ret; } static int test_auth_pkt(const test_info *t, int impl) { int ret = 0; unsigned int ivlen = 0; int num_encbytes; unsigned char *textbuf = NULL; unsigned char *encbuf = NULL; unsigned char *decbuf = NULL; char msgstr[128]; /* * There is no AUTH info for NON_TLS use case. * Pass by default */ if (t->tls->v == NON_TLS) return 1; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s: %s encrypt SW decrypt for %s] ", __func__, impl == USE_ENGINE ? "ENG" : "SW", t->tls->v_str); /* Get an encrypted buffer along with it's plain text */ ret = encrypt_buff(t, USE_SW, &textbuf, &encbuf, &num_encbytes, &ivlen); if (ret != 1) { FAIL_MSG("%s failed to perform Encryption!\n", msgstr); goto err; } /* * Change bytes in the encrypted buffer. The bytes tampered with * should be past the IVLEN. * Flipping bits in the encrypted buffer to simulate corruption. */ encbuf[ivlen + 10] = ~encbuf[ivlen + 10]; /* Decrypt the encrypted buffer above and get decrpyted contents */ ret = decrypt_buff(t, impl, &encbuf, &decbuf, num_encbytes); if (ret != EVP_FAIL) { FAIL_MSG("%s Dec+Auth did not fail\n", msgstr); goto err; } ret = 1; err: OPENSSL_free(textbuf); return ret; } #ifndef QAT_OPENSSL_PROVIDER static int test_pipeline_setup(const test_info *t) { #define NUMPIPES 10 EVP_CIPHER_CTX *ctx = NULL; int pad = 0; int ret = 0; int outl = 0; int i, j; int size = t->bufsz; unsigned int ivlen = 0; unsigned long flags = 0; unsigned char **ebufs = NULL; unsigned char **ibufs = NULL; unsigned char **dbufs = NULL; size_t *inlens; unsigned char tls_hdr[] = { 0x00, 0x00, 0x00, 0x00, /* TLS Seq */ 0x00, 0x00, 0x00, 0x00, /* of 8Bytes */ /* Record Type, Major, Minor, Len-MSB, Len-LSB */ 0x16, 0x03, 0x00, 0x00, 0x00 }; /* Pipeline supported for version >= 1.1 */ if (t->tls->v < TLS1_1_VERSION) return 1; /* Setup context with engine without adding tls header */ ctx = setup_ctx(t, ENC, USE_ENGINE, &pad, DEF_CFG | NO_AAD); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", __func__); return 0; } flags = EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)); if (!(flags & EVP_CIPH_FLAG_PIPELINE)) { FAIL_MSG("%s PIPELINE flag not set\n", __func__); return 0; } ibufs = OPENSSL_zalloc(sizeof(unsigned char *) * NUMPIPES); ebufs = OPENSSL_zalloc(sizeof(unsigned char *) * NUMPIPES); dbufs = OPENSSL_zalloc(sizeof(unsigned char *) * NUMPIPES); inlens = OPENSSL_zalloc(sizeof(size_t) * NUMPIPES); if (ibufs == NULL || ebufs == NULL || dbufs == NULL || inlens == NULL) { FAIL_MSG("%s Failed to allocate memory for buffer arrays\n", __func__); goto err; } if ((EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS, NUMPIPES, (void *)ebufs) != 1) || (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_PIPELINE_INPUT_BUFS, NUMPIPES, (void *)ibufs) != 1) || (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_PIPELINE_INPUT_LENS, NUMPIPES, (void *)inlens) != 1) || 0) { FAIL_MSG(" %s Failed to set buffer for Pipeline\n", __func__); goto err; } /* Not supplied all the aad data this test should fail */ if (EVP_CipherUpdate(ctx, ebufs[0], &outl, ibufs[0], 128) != 0) { FAIL_MSG("%s Cipher operation completed without all aad!\n", __func__); goto err; } /* Setup aad data */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); for (i = 0; i < NUMPIPES; i++) { /* * Set the fields for each iteration as the pointer * may be modified by the control message if EVP software * implementation is used. */ tls_hdr[10] = t->tls->v & 0xff; tls_hdr[11] = ((size + ivlen) & 0xff00) >> 8; tls_hdr[12] = (size + ivlen) & 0x00ff; pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_hdr), (void *)tls_hdr); inlens[i] = compute_buff_size(size, &ivlen, pad, t->tls->v, ctx); ibufs[i] = OPENSSL_zalloc(inlens[i]); ebufs[i] = OPENSSL_zalloc(inlens[i]); dbufs[i] = NULL; if (ibufs[i] == NULL || ebufs[i] == NULL) { FAIL_MSG("%s Failed to allocate memory for buffers\n", __func__); goto err; } /* Setup Input buffers */ memcpy(ibufs[i], _ivec, ivlen); for (j = ivlen; j < size + ivlen; j++) ibufs[i][j] = ((i << 4) | (j % 16)); } if (EVP_CipherUpdate(ctx, NULL, &outl, NULL, 128) != 1) { FAIL_MSG("%s Encryption failed for Pipeline\n", __func__); goto err; } /* Decrypt each pipe encrypted buffer through software and compare */ for (i = 0; i < NUMPIPES; i++) { ret = decrypt_buff(t, USE_SW, &ebufs[i], &dbufs[i], inlens[i]); if (ret != 1) { FAIL_MSG("%s SW Decryption failed for pipe %d\n", __func__, i); goto err; } /* Compare and verify the decrypt and encrypt message. */ if (memcmp(dbufs[i] + ivlen, ibufs[i] + ivlen, size)) { FAIL_MSG("verify failed for pipe %d\n", i); tests_hexdump("AES*-CBC-HMAC-SHA* actual :", dbufs[i] + ivlen, size); tests_hexdump("AES*-CBC-HMAC-SHA* expected:", ibufs[i] + ivlen, size); goto err; } } ret = 1; err: EVP_CIPHER_CTX_free(ctx); OPENSSL_free(ibufs); OPENSSL_free(ebufs); OPENSSL_free(dbufs); OPENSSL_free(inlens); return ret; } /* * test_small_pkt_offload: * Small pkt offload test relies on the fact the Openssl SW * implementation and Qat engine implementation encrypts TLS1.1 * and TLS1.2 packets differently. This is used to detect which * implementation was used after the threshold was set. */ static int test_small_pkt_offload(const test_info *t) { int ret = 0; char msgstr[128]; # if defined(QAT_WARN) || defined(QAT_DEBUG) int run = 0; #endif int buflen = 0; int status = 0; /* str to append to message to distinguish test runs */ snprintf(msgstr, 128, "[%s %s:%s] ", __func__, t->c->name, t->tls->v_str); /* * Test is used only for version TLS1.1 and TLS1.2 * that use explicit IV. */ if (t->tls->v < TLS1_1_VERSION) return 1; /* * The threshold value is matched against the buffer length to decide * whether to offload the packet to engine or sw. The buffer length is * greater than the payload length as it also includes space for iv, hmac * and padding. * set threshold to the buflen. */ ret = set_pkt_threshold(t->e, t->c->name, buflen); if (ret != 1) goto end; /* * As buffers greater than threshold size are offloaded to Qat engine, * the engine will use the software implementation for all buffers less than * or equal to threshold. As a result, encrypting via engine or through * software will create byte identical encrypted buffers. */ ret = encrypt_and_compare(t, &buflen); /* check if SW and Engine implementation byte identical */ if (ret != ENCRYPT_BUFF_IDENTICAL) { FAIL_MSG("%s Encrypted buffers not identical status:%d run:%d\n", msgstr, ret, ++run); goto end; } /* * If negative values are send for threshold, the engine cntrl sets the * threshold back to zero. All buffers are then offloaded to qat. */ ret = set_pkt_threshold(t->e, t->c->name, -312); if (ret != 1) goto end; /* * The upper limit for threshold values is 16384. If a value greater than * upper limit is provided, the threshold is set to 16384. No buffers are * then offloaded to the engine as the maximum size of TLS payload is 16384. */ ret = set_pkt_threshold(t->e, t->c->name, 17000); if (ret != 1) goto end; ret = encrypt_and_compare(t, &buflen); if (ret != ENCRYPT_BUFF_IDENTICAL) { FAIL_MSG("%s Encrypted buffers not identical status:%d run:%d\n", msgstr, ret, ++run); goto end; } status = 1; end: /* Set the threshold back to 0 */ set_pkt_threshold(t->e, t->c->name, 0); return status; } #endif /* * run_aes_cbc_hmac_sha : * For each version of supported TLS protocol, * run various tests. */ static int run_aes_cbc_hmac_sha(void *pointer) { int ntls = sizeof(test_tls) / sizeof(tls_v); int i, cnt; int ret = 1; test_info ti; char msg[128]; TEST_PARAMS *args = (TEST_PARAMS *) pointer; ti.bufsz = args->size; ti.count = *(args->count); if ((ti.c = (chained_alg_info *) get_alg_info(args->type)) == NULL) { FAIL_MSG("Unknown Test Type %d ti.c %p\n", args->type, ti.c); return 0; } /* * If temp_args->explicit_engine is not set then set the * engine to NULL to allow fallback to software if * that engine under test does not support this operation. * This relies on the engine we are testing being * set as the default engine. */ ti.e = args->e; if (ti.e) { EVP_CIPHER *cipher = (EVP_CIPHER *)ENGINE_get_cipher(ti.e, NID_aes_256_cbc_hmac_sha256); /* Set Engine to NULL if this algorithm is disabled in configuration or disabled by the co-existence algorithm bitmap. */ if (cipher == NULL || cipher == EVP_aes_256_cbc_hmac_sha256()) ti.e = NULL; } /* * For the qat engine, offload all packet sizes to engine * by setting the threshold sizes to 0 for the cipher under test. */ if (ti.e != NULL) { ret = set_pkt_threshold(ti.e, ti.c->name, 0); /* Set engine to NULL as threshold will fail if NID not supported*/ if (ret != 1) { return 0; } } if (args->performance) { if(!strcmp(args->tls_version, "TLSv1")) ti.tls = (tls_v *)&test_tls[0]; else if(!strcmp(args->tls_version, "TLSv1_1")) ti.tls = (tls_v *)&test_tls[1]; else if(!strcmp(args->tls_version, "TLSv1_2")) ti.tls = (tls_v *)&test_tls[2]; else ti.tls = (tls_v *)&test_tls[3]; return test_performance_encrypt(&ti); } /* If the inner run fails, abandon test */ for (cnt = 0; ret && cnt < *(args->count); cnt++) { for (i = 0; i < ntls; i++) { ti.tls = (tls_v *)&test_tls[i]; #ifdef QAT_OPENSSL_PROVIDER # ifdef QAT_INSECURE_ALGO insecure_algorithms_enabled = 1; # endif if ( /* * Running the test with SW implementation to check if * the test logic is correct. */ (test_crypto_op(&ti, USE_SW, USE_SW) != 1) || (test_auth_header(&ti, USE_SW) != 1) || (test_auth_pkt(&ti, USE_SW) != 1) || ( /* * Perform these tests only if engine is present. * * When QAT insecure algorithms are disabled, AES128_CBC_HMAC_SHA256 * implementation uses only OpenSSL. * * USE_SW refers OpenSSL implementation. * USE_ENGINE refers QAT_Engine implementation. */ (insecure_algorithms_enabled || args->type != TEST_AES128_CBC_HMAC_SHA256) && ( (test_encrypted_buffer(&ti) != 1) || (test_no_hmac_key_set(&ti) != 1) || (test_crypto_op(&ti, USE_ENGINE, USE_SW) != 1) || (test_crypto_op(&ti, USE_SW, USE_ENGINE) != 1) || (test_crypto_op(&ti, USE_ENGINE, USE_ENGINE) != 1) || (test_auth_header(&ti, USE_ENGINE) != 1) || (test_auth_pkt(&ti, USE_ENGINE) != 1) ) ) || (test_multi_op(&ti) != 1) /* * 1. cipher pipeline feature is not support in * qatprovider due to limitation. * 2. small package offloading is support in qat- * provider, but there's no relevant API to set * threshold in OpenSSL 3.0, so this testcase is * also deactiaved. */ ) { #else if ( /* * Running the test with SW implementation to check if * the test logic is correct. */ (test_crypto_op(&ti, USE_SW, USE_SW) != 1) || (test_auth_header(&ti, USE_SW) != 1) || (test_auth_pkt(&ti, USE_SW) != 1) || ((ti.e != NULL) && ( /* * Perform these tests only if engine * is present. */ (test_encrypted_buffer(&ti) != 1) || (test_no_hmac_key_set(&ti) != 1) || (test_crypto_op(&ti, USE_ENGINE, USE_SW) != 1) || (test_crypto_op(&ti, USE_SW, USE_ENGINE) != 1) || (test_crypto_op(&ti, USE_ENGINE, USE_ENGINE) != 1) || (test_auth_header(&ti, USE_ENGINE) != 1) || (test_auth_pkt(&ti, USE_ENGINE) != 1) || (test_multi_op(&ti) != 1) || (test_small_pkt_offload(&ti) != 1) ) ) ) if (!args->sw_fallback) if ((ti.e != NULL) && (test_pipeline_setup(&ti) != 1)) { #endif ret = 0; break; } } } if (args->verify) { snprintf(msg, 128, " [%d out %d test run passed.]\n", cnt, *args->count); if (ret == 0) FAIL_MSG_END("verify failed %s%s", ti.c->name, cnt > 1 ? msg : "\n"); else PASS_MSG("verify %s%s", ti.c->name, cnt > 1 ? msg : "\n"); } /* Restore value to default */ if (ti.e != NULL) { ret = set_pkt_threshold(ti.e, ti.c->name, 2048); if (ret != 1) return 0; } return ret; } /* * tests_run_aes_cbc_hmac_sha: * Start Chained Cipher tests. */ void tests_run_aes_cbc_hmac_sha(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_aes_cbc_hmac_sha(args); else start_async_job(args, run_aes_cbc_hmac_sha); } qatengine-1.9.0/test/tests_chacha20_poly1305.c000066400000000000000000000444671500416242000207770ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define USE_ENGINE 1 #define USE_SW 0 #define POLY1305_DIGEST_SIZE 16 #define FAIL_MSG(fmt, args...) fprintf(stderr, "# FAIL " fmt, ##args) #define PASS_MSG(fmt, args...) fprintf(stderr, "# PASS " fmt, ##args) /* 256-bit cipher key */ static const unsigned char _key32[] = { 0xa5, 0x10, 0xca, 0x7c, 0x35, 0xc4, 0x52, 0x84, 0x82, 0xa8, 0x0c, 0x13, 0x17, 0xaf, 0x19, 0xa7, 0x80, 0x5f, 0xcf, 0xba, 0x5c, 0xbb, 0x6f, 0x9b, 0x8e, 0xa4, 0x36, 0xa6, 0x16, 0xbb, 0xcd, 0x7f }; /* 96-bit IV */ static unsigned char _ivec[] = { 0x2a, 0xf3, 0x01, 0x27, 0x05, 0x68, 0x03, 0x7a, 0x8b, 0xaf, 0x40, 0x9a }; static int run_chachapoly_update(void *args, int enc, int dec) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; ENGINE *enc_e = enc == USE_ENGINE ? temp_args->e : NULL; ENGINE *dec_e = dec == USE_ENGINE ? temp_args->e : NULL; int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; /* 16 bytes additional authentication data. * AAD is not to be encrypted. It is passed along with the plaintext * and ciphertext to the recipient. */ const unsigned char aad[] = { 0x61, 0x31, 0xFF, 0x29, 0xCE, 0x13, 0x75, 0xBD, 0x72, 0xD2, 0x3A, 0x11, 0x55, 0x42, 0xBB, 0xFF }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[POLY1305_DIGEST_SIZE] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; if (input == NULL) { fprintf(stderr,"# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* Set input data */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("CHACHAPOLY: input message", input, size); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); goto err; } /* Initialize encryption context for aes-gcm-128 */ ret = EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), enc_e, NULL, NULL); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(_ivec), NULL); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* Initialise the aes-gcm-128 encryption context with 16-byte key and 12-byte IV. */ ret = EVP_EncryptInit_ex(ctx, NULL, enc_e, _key32, _ivec); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Pass AAD to the encryption context before encrypting the input plaintext. */ ret = EVP_EncryptUpdate(ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } plaintext_len += POLY1305_DIGEST_SIZE; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { INFO("# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } ciphertext = plaintext; memcpy(plaintext, input, size); /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, size); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("CHACHAPOLY ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, POLY1305_DIGEST_SIZE, tag); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for aes-gcm-128 */ ret = EVP_DecryptInit_ex(dec_ctx, EVP_chacha20_poly1305(), dec_e, NULL, NULL); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(_ivec), NULL); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* Initialise the aes-gcm-128 decryption context with 16-byte key and 12-byte IV. */ ret = EVP_DecryptInit_ex(dec_ctx, NULL, dec_e, _key32, _ivec); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_SET_TAG, POLY1305_DIGEST_SIZE, tag); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* AAD is passed to EVP_DecryptUpdate() with output buffer set to NULL */ ret = EVP_DecryptUpdate(dec_ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } dec_cipher = ciphertext; /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, ciphertext, ciphertext_len); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len = tmpout_len; ret = EVP_DecryptFinal_ex(dec_ctx, dec_cipher + tmpout_len, &tmpout_len); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } dec_cipher_len += tmpout_len; if (print_output) tests_hexdump("CHACHAPOLY tag:", tag, POLY1305_DIGEST_SIZE); if (print_output) tests_hexdump("CHACHAPOLY decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, size)) { fprintf(stderr,"# FAIL verify for CHACHAPOLY update\n"); ret = 0; tests_hexdump("CHACHAPOLY actual :", dec_cipher, dec_cipher_len); tests_hexdump("CHACHAPOLY expected:", plaintext, size); } else fprintf(stderr,"# PASS verify for CHACHAPOLY update\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (input) OPENSSL_free(input); if (plaintext) OPENSSL_free(plaintext); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } static int run_chachapoly_tls(void *args, int enc, int dec) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; ENGINE *enc_e = enc == USE_ENGINE ? temp_args->e : NULL; ENGINE *dec_e = dec == USE_ENGINE ? temp_args->e : NULL; int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int i; int ret = 0; unsigned char length_byte1_tls_enc = size >> 8; unsigned char length_byte2_tls_enc = size |16 >> 8; unsigned char tls_enc_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_enc, length_byte2_tls_enc }; unsigned char length_byte1_tls_dec = (size + POLY1305_DIGEST_SIZE) >> 8; unsigned char length_byte2_tls_dec = (size + POLY1305_DIGEST_SIZE) |16 >> 8; unsigned char tls_dec_virt_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x03, 0x01, length_byte1_tls_dec, length_byte2_tls_dec }; unsigned char *input = OPENSSL_malloc(size); unsigned char *plaintext = NULL; unsigned char *ciphertext = NULL; unsigned char tag[POLY1305_DIGEST_SIZE] = { 0 }; unsigned char *dec_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int dec_cipher_len = 0; int plaintext_len = size; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; if (input == NULL) { fprintf(stderr,"# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } /* Set the plaintext input data. * This is a copy of the plaintext that will be used to check the * decrypted message. Original plaintext is destroyed in TLS case. */ for (i = 0; i < size; i++) input[i] = i % 16; if (print_output) tests_hexdump("CHACHA20-POLY1305: input message", input, size); /* Create a new context for the TLS encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); exit(EXIT_FAILURE); } /* IV used in the initialization of the cipher: in TLS case it is set * using ctrl() instead of EncryptInit_ex(). */ ret = EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), enc_e, _key32, _ivec); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_enc_virt_hdr), tls_enc_virt_hdr); if (ret != POLY1305_DIGEST_SIZE) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* In TLS case the explicit IV must be prepended to the plaintext * and there must be space to save the tag at the end of the buffer. */ plaintext_len += POLY1305_DIGEST_SIZE; plaintext = OPENSSL_malloc(plaintext_len); if (plaintext == NULL) { fprintf(stderr,"# FAIL: [%s] --- malloc failed for plaintext! \n", __func__); goto err; } memcpy(plaintext, input, size); /* TLS case works only inplace */ ciphertext = plaintext; /* TLS Decrypt operation */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, plaintext_len); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; if (print_output) tests_hexdump("CHACHA20-POLY1305 ciphertext:", ciphertext, ciphertext_len); /* The tag is contained in the last POLY1305_DIGEST_SIZE Bytes of the payload */ memcpy(tag, ciphertext + size, POLY1305_DIGEST_SIZE); EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; /*----------------------- Decryption ------------------------ */ /* Create context for TLS decrypt */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); exit(EXIT_FAILURE); } /* Initialise the context for decryption with 16-byte key and 12-byte IV. */ ret = EVP_DecryptInit_ex(dec_ctx, EVP_chacha20_poly1305(), dec_e, _key32, _ivec); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Provide the AAD as in the TLS stack of OpenSSL */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_TLS1_AAD, sizeof(tls_dec_virt_hdr), tls_dec_virt_hdr); if (ret != POLY1305_DIGEST_SIZE) { fprintf(stderr,"# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for setting aad: ret %d\n", __func__, ret); goto err; } /* TLS case works only inplace */ dec_cipher = ciphertext; /* TLS Decrypt operation */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &dec_cipher_len, ciphertext, ciphertext_len); if (ret != 1) { fprintf(stderr,"# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("CHACHA20-POLY1305 tag:", tag, POLY1305_DIGEST_SIZE); if (print_output) tests_hexdump("CHACHA20-POLY1305 decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, input, size)) { fprintf(stderr,"# FAIL verify for TLS CHACHA20-POLY1305\n"); ret = 0; tests_hexdump("CHACHA20-POLY1305 actual :", dec_cipher, size); tests_hexdump("CHACHA20-POLY1305 expected:", plaintext, size); } else fprintf(stderr,"# PASS verify for TLS CHACHA20-POLY1305\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (input != NULL) OPENSSL_free(input); if (plaintext != NULL) OPENSSL_free(plaintext); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } static int test_chachapoly_update(void *args) { run_chachapoly_update(args, USE_ENGINE, USE_ENGINE); run_chachapoly_update(args, USE_ENGINE, USE_SW); run_chachapoly_update(args, USE_SW, USE_ENGINE); run_chachapoly_update(args, USE_SW, USE_SW); return 1; } static int test_chachapoly_tls(void *args) { run_chachapoly_tls(args, USE_ENGINE, USE_ENGINE); run_chachapoly_tls(args, USE_ENGINE, USE_SW); run_chachapoly_tls(args, USE_SW, USE_ENGINE); run_chachapoly_tls(args, USE_SW, USE_SW); return 1; } void tests_run_chacha20_poly1305(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) { test_chachapoly_update(args); test_chachapoly_tls(args); } else { start_async_job(args, test_chachapoly_update); start_async_job(args, test_chachapoly_tls); } } qatengine-1.9.0/test/tests_dh.c000066400000000000000000000631211500416242000164310ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #ifndef QAT_OPENSSL_PROVIDER static const unsigned char BNp_512[] = { 0xFA, 0xF7, 0x2D, 0x97, 0x66, 0x5C, 0x47, 0x66, 0xB9, 0xBB, 0x3C, 0x33, 0x75, 0xCC, 0x54, 0xE0, 0x71, 0x12, 0x1F, 0x90, 0xB4, 0xAA, 0x94, 0x4C, 0xB8, 0x8E, 0x4B, 0xEE, 0x64, 0xF9, 0xD3, 0xF8, 0x71, 0xDF, 0xB9, 0xA7, 0x05, 0x55, 0xDF, 0xCE, 0x39, 0x19, 0x3D, 0x1B, 0xEB, 0xD5, 0xFA, 0x63, 0x01, 0x52, 0x2E, 0x01, 0x7B, 0x05, 0x33, 0x5F, 0xF5, 0x81, 0x6A, 0xF9, 0xC8, 0x65, 0xC7, 0x65 }; static const unsigned char BNp_1024[] = { 0xC1, 0xF1, 0x54, 0x26, 0x9C, 0x53, 0xC7, 0x22, 0x29, 0xBC, 0x03, 0x29, 0x00, 0x73, 0x61, 0xA7, 0x20, 0x7A, 0x1E, 0x75, 0x6C, 0x01, 0xCA, 0x8D, 0xE8, 0x9B, 0x4E, 0x1C, 0xC7, 0x59, 0x14, 0x35, 0x63, 0x29, 0x56, 0x09, 0x57, 0xD8, 0x01, 0x2F, 0xAD, 0x8F, 0x16, 0x78, 0x78, 0x9D, 0xA1, 0x03, 0x74, 0x5F, 0xAC, 0x7A, 0x37, 0x76, 0x12, 0x50, 0xF4, 0xBB, 0x4C, 0xCE, 0xD8, 0xF7, 0x87, 0x31, 0xD9, 0x45, 0xFC, 0xB6, 0xBF, 0xD5, 0x08, 0xFB, 0xA9, 0xBC, 0xA4, 0xA8, 0x65, 0x77, 0x69, 0xA4, 0x89, 0xD4, 0xB4, 0x40, 0x58, 0xCC, 0xF8, 0x62, 0x1A, 0x3E, 0x7B, 0x7A, 0x0E, 0x01, 0xA5, 0x8B, 0x1D, 0x5B, 0xED, 0xB1, 0x0D, 0x4A, 0x44, 0x70, 0x3B, 0xE7, 0x93, 0x4A, 0xC8, 0xFB, 0xAE, 0x81, 0x77, 0xC0, 0x23, 0x7D, 0xBB, 0x96, 0x72, 0xF7, 0x42, 0xFF, 0x80, 0xD6, 0x87, 0xE5, 0x97, 0xCB }; static const unsigned char BNp_2048[]= { 0xFC, 0x90, 0x16, 0xE9, 0x4B, 0xE4, 0x28, 0x49, 0xC2, 0xDF, 0x6E, 0xFC, 0xF4, 0xB1, 0xC5, 0xBC, 0x48, 0xD1, 0xEC, 0x3C, 0xE6, 0xEA, 0xDC, 0x8E, 0x5B, 0x51, 0x8A, 0x48, 0xCF, 0xC9, 0xB1, 0xAC, 0x29, 0x30, 0x45, 0x22, 0x07, 0x71, 0x6C, 0x05, 0x2D, 0xE8, 0xEE, 0x46, 0x16, 0xC3, 0x8B, 0xFE, 0x65, 0xF5, 0xDA, 0x68, 0x76, 0x4F, 0x0D, 0x05, 0x15, 0x9B, 0x21, 0xF6, 0x1C, 0x92, 0xCD, 0xFE, 0xBE, 0x2F, 0xD0, 0x79, 0xA5, 0x6C, 0x23, 0xC6, 0x00, 0xC9, 0xBB, 0xD1, 0x63, 0xCD, 0x06, 0x21, 0xD1, 0xD3, 0x55, 0x2F, 0x1E, 0x38, 0x5A, 0xCC, 0x49, 0x85, 0x13, 0xFE, 0xA0, 0x55, 0x1F, 0x51, 0xE3, 0xE3, 0xA2, 0x3F, 0x00, 0x04, 0xAB, 0xB4, 0xF3, 0x5A, 0x53, 0x82, 0xD0, 0xD5, 0xD7, 0x5A, 0x11, 0xE5, 0xE3, 0xDB, 0x57, 0xA8, 0xB3, 0xB8, 0x70, 0xF8, 0x6E, 0xEC, 0xC0, 0x46, 0x82, 0xEC, 0x98, 0xBD, 0xE0, 0xD2, 0xB2, 0x5E, 0x44, 0x51, 0x41, 0x18, 0x66, 0x93, 0xF1, 0xA5, 0xF3, 0x86, 0xC9, 0x9D, 0xEC, 0x80, 0x78, 0x0B, 0x7E, 0x13, 0xF9, 0xDF, 0x78, 0x0E, 0x0D, 0x23, 0xBB, 0x6A, 0xF2, 0x9C, 0xBF, 0x2F, 0xD3, 0xF1, 0xFA, 0xC4, 0xA1, 0xEB, 0xF3, 0x53, 0xBD, 0x4C, 0xDF, 0x8C, 0xBB, 0x4A, 0x41, 0x90, 0x54, 0x72, 0x8B, 0x8D, 0xAA, 0xAF, 0x3B, 0x2C, 0x52, 0x6F, 0x27, 0x0E, 0xDD, 0x82, 0xF8, 0xC8, 0x72, 0xDB, 0xE1, 0x6A, 0x81, 0x5D, 0xA4, 0xE2, 0x45, 0xA6, 0xA6, 0x7D, 0x7B, 0x82, 0x08, 0x8B, 0x03, 0xD2, 0x70, 0xD3, 0x9B, 0x9B, 0x05, 0x6D, 0x63, 0x1F, 0x37, 0x32, 0xCF, 0xAE, 0xA9, 0x4B, 0xAD, 0x50, 0xB0, 0xF1, 0xA1, 0x75, 0x4B, 0xF9, 0xEF, 0x38, 0x18, 0x94, 0x2C, 0x30, 0x26, 0x0D, 0x63, 0x70, 0x24, 0xED, 0x7D, 0x2F, 0xDD, 0x96, 0xD2, 0x7E, 0xD1, 0xD7 }; static const unsigned char BNp_4096[]= { 0xBF, 0x01, 0x78, 0x3A, 0x05, 0xC6, 0x8E, 0xFA, 0x4E, 0x42, 0x93, 0xFC, 0x2F, 0x80, 0x26, 0x09, 0xC5, 0x59, 0x7A, 0xC6, 0x5E, 0x15, 0xD8, 0xBF, 0x46, 0x0F, 0xAB, 0x10, 0xD9, 0x01, 0x3A, 0x76, 0x32, 0xCE, 0xB6, 0x8D, 0x7D, 0x10, 0x7E, 0xA3, 0xE1, 0x12, 0x9F, 0xCF, 0x64, 0x54, 0xB9, 0x38, 0x96, 0x0D, 0x2B, 0xDC, 0xE8, 0x1D, 0x6E, 0x34, 0x45, 0xAE, 0x4E, 0x49, 0x36, 0x5C, 0x33, 0x1E, 0x1E, 0xE4, 0xB5, 0x76, 0x87, 0x19, 0x82, 0x4B, 0xDA, 0xC6, 0x0F, 0x5B, 0x28, 0x8A, 0x82, 0xB7, 0x2D, 0x3A, 0xDC, 0x0C, 0x68, 0x0B, 0xA5, 0xE6, 0x69, 0xCC, 0x9F, 0x87, 0x19, 0xFE, 0x65, 0xDE, 0xFE, 0x6A, 0xDD, 0xE2, 0x68, 0x08, 0x2B, 0x79, 0x4D, 0xA7, 0x23, 0x7C, 0x96, 0x92, 0x8B, 0x3A, 0x6E, 0x36, 0x64, 0xD0, 0x91, 0x01, 0xDC, 0x7B, 0x7B, 0x44, 0x2A, 0xAD, 0xA2, 0x26, 0x6D, 0x3A, 0xD5, 0xF6, 0xEA, 0x56, 0x58, 0x4D, 0xA7, 0x4E, 0xC7, 0x8C, 0x4B, 0x61, 0x9C, 0x9F, 0x1F, 0xFD, 0x65, 0xC2, 0xA8, 0xAC, 0x94, 0x8A, 0xF8, 0x65, 0x73, 0x08, 0x5A, 0x27, 0x6E, 0x0B, 0xE3, 0xAF, 0xB5, 0x19, 0xEA, 0x22, 0xFA, 0x91, 0x5A, 0x65, 0xD1, 0x5A, 0x28, 0x4C, 0xF3, 0x06, 0xAA, 0x37, 0xDD, 0xB7, 0x19, 0x38, 0xCD, 0x5B, 0xED, 0x0D, 0x9C, 0x59, 0xED, 0x02, 0x44, 0x3C, 0x02, 0xC2, 0xEC, 0xAF, 0xCF, 0x62, 0xC8, 0xD4, 0x36, 0x78, 0x68, 0x43, 0x86, 0x6F, 0x3F, 0xFD, 0x58, 0x4D, 0x15, 0x86, 0xCB, 0xF3, 0x3E, 0xE0, 0xEF, 0x2F, 0xD5, 0x5E, 0x3A, 0x81, 0xAB, 0x6D, 0x85, 0xD2, 0x8E, 0x6D, 0x84, 0x35, 0xC8, 0xFD, 0x42, 0x3A, 0xCB, 0x9A, 0x5C, 0x25, 0xC6, 0x92, 0x60, 0xAB, 0xED, 0xC3, 0x04, 0x6E, 0xDE, 0x7F, 0xD4, 0x68, 0xC9, 0xAE, 0xB6, 0xC1, 0xF7, 0xCE, 0x28, 0x2C, 0xE7, 0x66, 0xA1, 0xF9, 0x62, 0x50, 0x3C, 0x20, 0x57, 0x1E, 0x7F, 0x74, 0xB8, 0x52, 0x42, 0xB8, 0x70, 0xFF, 0x32, 0x46, 0x8C, 0x34, 0xC5, 0x6A, 0x11, 0x62, 0x1E, 0x03, 0xFB, 0x79, 0x1F, 0x9B, 0xAC, 0xAF, 0xED, 0x9E, 0x98, 0xC8, 0xF9, 0x4F, 0x68, 0x85, 0xD3, 0x3C, 0x07, 0xE9, 0xBB, 0x41, 0x67, 0x0C, 0x79, 0x28, 0x3F, 0xF5, 0x8B, 0x8E, 0xAC, 0xB5, 0x80, 0x40, 0x0C, 0x90, 0x33, 0x68, 0xE3, 0x4F, 0x97, 0xE7, 0x94, 0x22, 0x20, 0x80, 0x01, 0x1A, 0x9F, 0x1F, 0x6F, 0x22, 0x06, 0x05, 0xC7, 0x86, 0x85, 0x1B, 0xF8, 0x7A, 0xB0, 0xF6, 0xFB, 0xA5, 0x59, 0xF8, 0xA5, 0xFB, 0xC1, 0x88, 0xF9, 0x33, 0xF0, 0x38, 0xBB, 0xF0, 0x14, 0x1C, 0xFE, 0xAF, 0x14, 0x9A, 0xCF, 0xBE, 0xF4, 0xF6, 0x9C, 0x73, 0xE4, 0xF4, 0x81, 0x41, 0x30, 0x8C, 0x53, 0xA9, 0x17, 0xA2, 0x8C, 0xF9, 0xA4, 0x0C, 0xFD, 0x29, 0x26, 0x49, 0x70, 0x20, 0xFB, 0xB5, 0x34, 0x5C, 0x04, 0x86, 0x49, 0x4C, 0xFF, 0x8D, 0x45, 0x25, 0xFB, 0x80, 0x37, 0x54, 0xCC, 0x74, 0xCC, 0xBF, 0x39, 0x3B, 0x9A, 0x43, 0xF6, 0x44, 0xEB, 0x0B, 0x88, 0xE8, 0xFF, 0x9F, 0x82, 0xCE, 0x6F, 0x0A, 0x16, 0x7E, 0x5A, 0x50, 0x34, 0x8A, 0x8A, 0x39, 0x19, 0x4D, 0x1B, 0x1F, 0x4E, 0x1D, 0x7A, 0x12, 0x9A, 0x5B, 0x29, 0xD0, 0x3D, 0xAA, 0x2D, 0x4B, 0x59, 0xCA, 0x29, 0xC3, 0x7F, 0xF9, 0xD7, 0x36, 0x74, 0xE7, 0x86, 0x11, 0x83, 0x7C, 0xDD, 0x45, 0xC8, 0x27, 0x39, 0xC1, 0x9D, 0x2A, 0xDB, 0x57, 0xA4, 0x5B, 0x8F, 0x50, 0x4A, 0x3D, 0xFD, 0x98, 0x45, 0xE6, 0x33, 0x50, 0xA1, 0xF4, 0xF7, 0x4D, 0xB7, 0x99, 0x7E, 0x04, 0x3E, 0xC7, 0x9E, 0xF0, 0x4C, 0xA9, 0xB3, 0x25, 0x88, 0xE3, 0x25, 0xCA, 0x2A, 0x6F, 0xDD, 0xD3, 0xE3, 0xBF }; static const unsigned char BNp_8192[]= { 0xd5, 0x02, 0x2e, 0xc7, 0xc1, 0xd7, 0x19, 0xbe, 0x50, 0xea, 0x20, 0xa6, 0x51, 0x0e, 0x6f, 0x2b, 0x92, 0xe4, 0x47, 0x76, 0xca, 0x16, 0xbe, 0x93, 0x4b, 0x8d, 0xb8, 0xeb, 0x28, 0x60, 0xb5, 0x64, 0x42, 0xb2, 0x0b, 0x93, 0x9b, 0x45, 0xc7, 0xcc, 0x58, 0x5e, 0x65, 0x90, 0x98, 0x5e, 0x40, 0xdb, 0xd8, 0x57, 0x7e, 0x2b, 0x6f, 0x48, 0x37, 0xce, 0x4f, 0x95, 0x5b, 0xae, 0x25, 0xb5, 0x2e, 0x1f, 0x4f, 0xc9, 0xf4, 0xd5, 0x71, 0x47, 0x21, 0xfd, 0xf0, 0x4f, 0x93, 0xb0, 0x10, 0x6e, 0x1b, 0x19, 0xd4, 0x23, 0xc7, 0xe7, 0x5c, 0x35, 0x7e, 0x38, 0xfb, 0xf7, 0xa0, 0xc8, 0x08, 0x20, 0x9d, 0x1c, 0x3c, 0xd4, 0x17, 0xcf, 0xe8, 0x0f, 0x94, 0xa4, 0x1f, 0x56, 0x38, 0xfa, 0xc7, 0x5e, 0x43, 0xd1, 0xbe, 0x16, 0xc7, 0xe9, 0xd7, 0x7e, 0xf1, 0x30, 0x2a, 0xe0, 0xa2, 0x3e, 0xdc, 0xf9, 0x6d, 0x14, 0x03, 0xa8, 0x9f, 0x98, 0xf7, 0x1b, 0x96, 0x2f, 0x21, 0xf1, 0x04, 0xa0, 0x18, 0x33, 0x99, 0x14, 0x91, 0x86, 0x29, 0xb4, 0x76, 0xb3, 0x21, 0x23, 0x92, 0x14, 0x1f, 0x71, 0x29, 0x15, 0x51, 0xb0, 0x42, 0xf8, 0xd3, 0xa8, 0xd7, 0xae, 0x6d, 0xf7, 0x03, 0x59, 0x43, 0xf0, 0x2d, 0xd8, 0x9b, 0xdc, 0x76, 0x1b, 0xb4, 0x9f, 0x18, 0xb7, 0x2e, 0xbb, 0x43, 0x1a, 0x1a, 0xe4, 0xac, 0xde, 0x16, 0xfb, 0xc8, 0xdb, 0x27, 0xae, 0xe7, 0x42, 0xae, 0x81, 0x02, 0x9b, 0x1f, 0x53, 0x45, 0xa3, 0x40, 0xa8, 0x62, 0x46, 0x68, 0x89, 0xfc, 0x7f, 0x07, 0x54, 0xb3, 0x30, 0x17, 0xe0, 0x26, 0xde, 0x32, 0xc6, 0x26, 0x1b, 0xf4, 0x10, 0x17, 0xf0, 0xd0, 0xd7, 0xfa, 0x66, 0xaa, 0x13, 0x21, 0x98, 0x64, 0x10, 0xd5, 0xf3, 0x8b, 0x06, 0x4c, 0xa0, 0xa6, 0x49, 0x7f, 0x61, 0x78, 0xea, 0xa8, 0xe5, 0x55, 0xfb, 0x01, 0x5e, 0x06, 0x9d, 0x3b, 0x6d, 0x39, 0x49, 0x3d, 0x9c, 0xc3, 0x6a, 0x67, 0x1e, 0x58, 0xd6, 0xa4, 0x06, 0x3f, 0xf2, 0xa0, 0x84, 0x45, 0xaa, 0xaf, 0x06, 0x0e, 0x9a, 0xa4, 0x8e, 0x57, 0x30, 0xa2, 0x1f, 0xc5, 0xc8, 0x41, 0x9e, 0x7f, 0x7b, 0xfb, 0xa4, 0x2c, 0x66, 0x50, 0x08, 0xff, 0xca, 0x80, 0x09, 0x1b, 0xd3, 0x63, 0xc5, 0x01, 0xe0, 0x9d, 0xbf, 0xf5, 0x17, 0xe6, 0xa4, 0xc7, 0xd5, 0x37, 0x2c, 0x87, 0x11, 0x13, 0x35, 0xeb, 0x67, 0xee, 0xad, 0x75, 0x67, 0x09, 0xbf, 0x0e, 0x98, 0x01, 0xa3, 0xc2, 0x21, 0x94, 0x91, 0xec, 0x88, 0x22, 0xb3, 0x8c, 0xd4, 0x55, 0x73, 0x00, 0x8e, 0xf4, 0xea, 0x65, 0xca, 0x2b, 0x08, 0xc3, 0x8a, 0x85, 0xe5, 0x4b, 0x78, 0x10, 0xe7, 0x4e, 0x29, 0x84, 0x2d, 0x26, 0xf6, 0x7c, 0x3f, 0xe4, 0x82, 0x97, 0xb0, 0x63, 0x2e, 0x58, 0xb0, 0xf9, 0x75, 0xd1, 0x1d, 0x5a, 0x10, 0x65, 0xfb, 0xcc, 0xa4, 0x08, 0x79, 0x80, 0x7e, 0x04, 0xb4, 0x23, 0xe1, 0x31, 0x1e, 0xcb, 0x4c, 0x84, 0x47, 0x80, 0xc4, 0x80, 0x67, 0xb0, 0x00, 0x8c, 0xe9, 0x8b, 0x7f, 0xcc, 0xfe, 0xd4, 0xe8, 0xc6, 0x1a, 0xa0, 0xd8, 0xc2, 0x0d, 0xe7, 0x10, 0x5f, 0xdf, 0xf5, 0xe8, 0xe9, 0x52, 0x08, 0x1f, 0xfe, 0x67, 0xd5, 0x14, 0x18, 0x11, 0x40, 0xba, 0x23, 0x34, 0x53, 0x34, 0x63, 0x75, 0x6a, 0xc4, 0x62, 0x99, 0x2a, 0x63, 0x91, 0xbd, 0xd5, 0x93, 0x39, 0xff, 0x5c, 0x06, 0x90, 0x2c, 0x9a, 0xc2, 0x22, 0x70, 0x1b, 0x85, 0x22, 0xfe, 0x9c, 0x7d, 0xc0, 0x2f, 0x6a, 0xd2, 0xa5, 0x59, 0xd9, 0x7a, 0x60, 0xd2, 0xe0, 0xd2, 0x24, 0xfd, 0x1c, 0xc5, 0x06, 0xe8, 0xf6, 0x6a, 0x67, 0x56, 0x17, 0x81, 0x33, 0xdc, 0x37, 0x5a, 0x1a, 0xc2, 0x18, 0x51, 0xf1, 0x27, 0xca, 0x8d, 0xd3, 0x4f, 0xe3, 0x21, 0x98, 0x26, 0xf4, 0xd9, 0x26, 0xca, 0xb3, 0x2c, 0x46, 0x26, 0x1c, 0x2f, 0xa9, 0x97, 0xe8, 0x25, 0xd7, 0x5d, 0x6e, 0xf1, 0x81, 0x5b, 0x19, 0x49, 0x56, 0xc5, 0x6b, 0xdc, 0x2d, 0x97, 0x20, 0x30, 0x9f, 0x87, 0x68, 0x6e, 0x6f, 0x64, 0xec, 0x08, 0x69, 0x88, 0x3f, 0x53, 0x26, 0x30, 0x80, 0x82, 0xee, 0x0d, 0x00, 0xca, 0x1b, 0x83, 0x98, 0xe6, 0x91, 0x3c, 0x6c, 0x56, 0x7b, 0xf9, 0xeb, 0x0f, 0x92, 0xe4, 0x3d, 0x7c, 0x6c, 0x22, 0x33, 0x61, 0xe2, 0x04, 0x9f, 0x6b, 0x91, 0xac, 0x29, 0x56, 0x2f, 0x91, 0x3c, 0x5a, 0x5b, 0x5b, 0x18, 0x8e, 0x1b, 0xc9, 0xae, 0x50, 0x2a, 0x9d, 0x40, 0x1c, 0x50, 0xa6, 0x87, 0xc4, 0x08, 0xaa, 0x72, 0xae, 0xc0, 0xab, 0x76, 0x5f, 0x1b, 0x27, 0x35, 0x0e, 0x1e, 0x45, 0x59, 0xc3, 0x82, 0xe0, 0x15, 0xc7, 0x88, 0x8e, 0x70, 0x6d, 0x83, 0x0a, 0x1f, 0x22, 0x57, 0x16, 0x85, 0xf3, 0xc0, 0x6f, 0xa5, 0x3a, 0x4f, 0x1c, 0x52, 0xbc, 0x21, 0x3c, 0x48, 0xfc, 0x47, 0x8c, 0xdf, 0x31, 0xfb, 0xdb, 0x85, 0xdd, 0x45, 0xf3, 0x40, 0x52, 0x5d, 0xa0, 0x92, 0x32, 0x20, 0x77, 0x06, 0x0a, 0xb5, 0xe1, 0x1c, 0xea, 0x62, 0xc7, 0x7d, 0xfa, 0x0d, 0x8d, 0x9a, 0x74, 0x61, 0xc2, 0xfc, 0x08, 0xd7, 0x5b, 0x72, 0x37, 0x7e, 0xbd, 0x77, 0xa1, 0x1e, 0xc8, 0xb8, 0x3f, 0x29, 0x53, 0x1c, 0xcc, 0x16, 0x23, 0xd9, 0x90, 0x36, 0xdd, 0xca, 0x15, 0x14, 0xa7, 0x2d, 0xbb, 0xeb, 0xfb, 0xfc, 0xf5, 0x62, 0x12, 0xab, 0x61, 0xba, 0xb3, 0x3b, 0x1b, 0x6e, 0x3f, 0x5c, 0x5a, 0xda, 0x08, 0x5a, 0x34, 0x18, 0xd0, 0x81, 0xbf, 0x7b, 0x77, 0x72, 0x1d, 0x02, 0xd3, 0xe3, 0xe9, 0xa9, 0x71, 0x73, 0x8e, 0x76, 0x14, 0xeb, 0xcf, 0xb6, 0xf3, 0x7f, 0x99, 0xfd, 0x62, 0x9e, 0x43, 0x09, 0xbd, 0x44, 0xee, 0xfc, 0xbf, 0xd0, 0x63, 0x52, 0xa0, 0x8e, 0xe4, 0x98, 0x37, 0xb1, 0x99, 0xb1, 0xab, 0x59, 0xf5, 0x34, 0xa2, 0xa5, 0x08, 0x89, 0x0f, 0x5b, 0x81, 0x8a, 0xc7, 0x35, 0x05, 0xfd, 0x63, 0xfa, 0xb4, 0xb4, 0x15, 0xd0, 0x0a, 0xee, 0xaa, 0x20, 0xf1, 0x49, 0x7f, 0x24, 0xa5, 0x0f, 0xb1, 0x0c, 0x57, 0x19, 0xcd, 0xca, 0xb3, 0x83, 0xfc, 0x9b, 0x29, 0x06, 0x75, 0xc2, 0x34, 0xed, 0x5e, 0x3f, 0x60, 0x34, 0xb2, 0x1e, 0xcf, 0x9e, 0x60, 0xbf, 0x90, 0xb0, 0xfa, 0xa4, 0xfc, 0x88, 0x9b, 0x10, 0x3b, 0x96, 0xa4, 0xaf, 0xfe, 0x79, 0xc4, 0xdd, 0xca, 0x27, 0xbe, 0xed, 0x8c, 0xc8, 0x77, 0x0f, 0x6b, 0x8e, 0xa0, 0x29, 0x48, 0xb9, 0xd2, 0xc1, 0xb1, 0x93, 0x75, 0xe4, 0xb5, 0xcc, 0x10, 0x22, 0x75, 0xad, 0xdd, 0x93, 0x33, 0xbd, 0xbe, 0xdb, 0xb6, 0x2c, 0xdc, 0xaa, 0xda, 0x96, 0x36, 0x89, 0x58, 0xce, 0x12, 0x15, 0xc6, 0xe7, 0x68, 0xd2, 0x34, 0x33, 0x73, 0x69, 0x1c, 0xa8, 0x17, 0x35, 0x26, 0x85, 0x9e, 0x6d, 0xb2, 0xf4, 0x97, 0x3f, 0xbd, 0xce, 0xe7, 0xe4, 0xf8, 0x69, 0x8e, 0xf9, 0x80, 0xce, 0x0c, 0xb2, 0x07, 0x26, 0x75, 0x43, 0x58, 0xca, 0x3b, 0x63, 0x68, 0xe5, 0x9f, 0x98, 0xbc, 0x5e, 0xf6, 0x1e, 0xd5, 0x81, 0x5b, 0xc9, 0x0c, 0x94, 0xd7, 0x0b, 0x13, 0xd9, 0x34, 0x68, 0xbf, 0x73, 0xa2, 0xff, 0x0b, 0x19, 0x66, 0xda, 0x21, 0xa5, 0x38, 0x0a, 0x5a, 0xa2, 0x98, 0xb4, 0x5f, 0x53, 0x04, 0x10, 0x3f, 0x87, 0xdf, 0xf8, 0x11, 0xa8, 0xcd, 0x29, 0xc3, 0x91, 0xb6, 0x03, 0xe1, 0x19, 0x19, 0x2c, 0xc4, 0x98, 0x1a, 0x00, 0xce, 0xaa, 0xd3, 0x60, 0x8c, 0xb3, 0xcd, 0xd5, 0x9b, 0x2d, 0x07, 0x6b, 0x4c, 0x85, 0x50, 0xd0, 0xf7 }; static const unsigned char BNg[] = {0x05}; #endif #ifdef QAT_OPENSSL_PROVIDER #define NID_dh2048 1126 #define NID_dh3072 1127 #define NID_dh4096 1128 #define NID_dh8192 1130 #define MAX_DH_SIZE 1024 static unsigned int get_dh_nid(int size) { switch (size) { case 2048: return NID_dh2048; case 3072: return NID_dh3072; case 4096: return NID_dh4096; case 8192: return NID_dh8192; default: INFO("dh %d size is not supported!\n", size); } return 0; } #endif /****************************************************************************** * function: * run_dh (void *args) * * @param args [IN] - the test parameters * * description: * The function is design to test DH key generation and verify using qat engine. * If the verify flag raised, two DH public keys are generate separately * with and without DH_FLAG_NO_EXP_CONSTTIME flag. And the verification compares * the outputs of each DH_compute_key() after exchange two public keys. * ********************************************************************************/ static int run_dh(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int size = temp_args->size; int ret = 1; #ifndef QAT_OPENSSL_PROVIDER int count = *(temp_args->count); int print_output = temp_args->print_output; int verify = temp_args->verify; DH *dh_a = NULL; DH *dh_b = NULL; BIGNUM *p_a = NULL, *q_a = NULL; BIGNUM *g_a = NULL; const BIGNUM *pub_key_a = NULL, *priv_key_a = NULL; BIGNUM *p_b = NULL, *q_b = NULL; BIGNUM *g_b = NULL; const BIGNUM *pub_key_b = NULL, *priv_key_b = NULL; char buf[12] = {0}; unsigned char *abuf = NULL, *bbuf = NULL; int i = 0, alen = 0, blen = 0, aout = 0, bout = 0; BIO *out = NULL; out = BIO_new(BIO_s_file()); if (out == NULL) goto err; BIO_set_fp(out, stdout, BIO_NOCLOSE); if ((dh_a = DH_new()) == NULL) { WARN("# FAIL DH creating object dh_a.\n"); ret = 0; goto err; } if (size <= 512) p_a = BN_bin2bn(BNp_512, sizeof(BNp_512), NULL); if (size > 512 && size <= 1024) p_a = BN_bin2bn(BNp_1024, sizeof(BNp_1024), NULL); if (size > 1024 && size <= 2048) p_a = BN_bin2bn(BNp_2048, sizeof(BNp_2048), NULL); if (size > 2048 && size <= 4096) p_a = BN_bin2bn(BNp_4096, sizeof(BNp_4096), NULL); if (size > 4096) p_a = BN_bin2bn(BNp_8192, sizeof(BNp_8192), NULL); g_a = BN_bin2bn(BNg, sizeof(BNg), NULL); if (!p_a || !g_a) { WARN("# FAIL DH creating p and g.\n"); ret = 0; if (p_a) BN_free(p_a); if (g_a) BN_free(g_a); goto err; } if (!DH_set0_pqg(dh_a, p_a, q_a, g_a)) { WARN("# FAIL DH setting p and g for key a.\n"); ret = 0; if (p_a) BN_free(p_a); if (g_a) BN_free(g_a); goto err; } dh_b = DH_new(); if (dh_b == NULL) { WARN("# FAIL DH creating object dh_b.\n"); ret = 0; goto err; } /* * we copy over prime and generator values from dh_a, just save time to * generate and validate values */ p_b = BN_dup(p_a); g_b = BN_dup(g_a); if ((p_b == NULL) || (g_b == NULL)) { WARN("# FAIL DH duplicating p and g.\n"); ret = 0; if (p_b) BN_free(p_b); if (g_b) BN_free(g_b); goto err; } if (!DH_set0_pqg(dh_b, p_b, q_b, g_b)) { WARN("# FAIL DH setting p and g for key b.\n"); ret = 0; if (p_b) BN_free(p_b); if (g_b) BN_free(g_b); goto err; } /* * Set dh_a to run with normal modexp and dh_b to use constant time. The * built-in DH implementation now uses constant time modular * exponentiation for secret exponents by default. DH_FLAG_NO_EXP_CONTTIME * flag causes the faster variable sliding window method to be used for * all exponents */ DH_clear_flags(dh_b, DH_FLAG_NO_EXP_CONSTTIME); DH_set_flags(dh_a, DH_FLAG_NO_EXP_CONSTTIME); aout = DH_generate_key(dh_a); if (aout <= 0) { WARN("# FAIL DH generating key a.\n"); ret = 0; goto err; } DH_get0_key(dh_a, &pub_key_a, &priv_key_a); if (print_output) { BIO_puts(out, "pri 1="); BN_print(out, priv_key_a); BIO_puts(out, "\npub 1="); BN_print(out, pub_key_a); BIO_puts(out, "\n"); } bout = DH_generate_key(dh_b); if (bout <= 0) { WARN("# FAIL DH generating key b.\n"); ret = 0; goto err; } DH_get0_key(dh_b, &pub_key_b, &priv_key_b); if (print_output) { BIO_puts(out, "pri 2="); BN_print(out, priv_key_b); BIO_puts(out, "\npub 2="); BN_print(out, pub_key_b); BIO_puts(out, "\n"); } alen = DH_size(dh_a); abuf = (unsigned char *)OPENSSL_malloc(alen); if (abuf == NULL) { WARN("# FAIL DH abuf malloc failed ! \n"); ret = 0; goto err; } for (i = 0; i < count; i++) { aout = DH_compute_key(abuf, pub_key_b, dh_a); if (aout <= 0) { WARN("# FAIL DH compute key a.\n"); ret = 0; goto err; } if (print_output) { BIO_puts(out, "key1 ="); for (i = 0; i < aout; i++) { sprintf(buf, "%02X", abuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); } } if (verify) { blen = DH_size(dh_b); bbuf = (unsigned char *)OPENSSL_malloc(blen); if (bbuf == NULL) { WARN("# FAIL DH bbuf malloc failed ! \n"); ret = 0; goto err; } bout = DH_compute_key(bbuf, pub_key_a, dh_b); if (bout <= 0) { WARN("# FAIL DH compute key b.\n"); ret = 0; goto err; } if (print_output) { BIO_puts(out, "key2 ="); for (i = 0; i < bout; i++) { sprintf(buf, "%02X", bbuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); } if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { INFO("# FAIL verify for DH.\n"); ret = 0; /* Fail */ } else INFO("# PASS verify for DH. \n"); } #endif #ifdef QAT_OPENSSL_PROVIDER EVP_PKEY *pkey_A = NULL; EVP_PKEY *pkey_B = NULL; EVP_PKEY_CTX *dh_ctx = NULL; EVP_PKEY_CTX *test_ctx = NULL; unsigned char *secret_ff_a = NULL; unsigned char *secret_ff_b = NULL; size_t secret_size; size_t test_out; pkey_A = EVP_PKEY_new(); if (!pkey_A){ WARN("# FAIL while initialising EVP_PKEY (out of memory?).\n"); ret = 0; goto err; } pkey_B = EVP_PKEY_new(); if (!pkey_B){ WARN("# FAIL while initialising EVP_PKEY (out of memory?).\n"); ret = 0; goto err; } dh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); if (!dh_ctx){ WARN("# FAIL while allocating EVP_PKEY_CTX.\n"); ret = 0; goto err; } if (EVP_PKEY_keygen_init(dh_ctx) <= 0){ WARN("# FAIL while initialising EVP_PKEY_CTX.\n"); ret = 0; goto err; } if (EVP_PKEY_CTX_set_dh_nid(dh_ctx, get_dh_nid(size)) <= 0){ WARN("# FAIL setting DH key size for keygen.\n"); ret = 0; goto err; } if (EVP_PKEY_keygen(dh_ctx, &pkey_A) <= 0 || EVP_PKEY_keygen(dh_ctx, &pkey_B) <= 0){ WARN("# FAIL FFDH key generation failure.\n"); ret = 0; goto err; } EVP_PKEY_CTX_free(dh_ctx); dh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL); if (dh_ctx == NULL){ WARN("# FAIL while allocating EVP_PKEY_CTX.\n"); ret = 0; goto err; } if (EVP_PKEY_derive_init(dh_ctx) <= 0){ WARN("# FAIL FFDH derivation context init failure.\n"); ret = 0; goto err; } if (EVP_PKEY_derive_set_peer(dh_ctx, pkey_B) <= 0){ WARN("# FAIL Assigning peer key for derivation failed.\n"); ret = 0; goto err; } if (EVP_PKEY_derive(dh_ctx, NULL, &secret_size) <= 0){ WARN("# FAIL Checking size of shared secret failed.\n"); ret = 0; goto err; } if (secret_size > MAX_DH_SIZE){ WARN("# FAIL Assertion failure: shared secret too large.\n"); ret = 0; goto err; } secret_ff_a = OPENSSL_malloc(MAX_DH_SIZE); if (secret_ff_a == NULL){ WARN("# FAIL Secret buf a malloc failed!\n"); ret = 0; goto err; } secret_ff_b = OPENSSL_malloc(MAX_DH_SIZE); if (secret_ff_b == NULL){ WARN("# FAIL Secret buf b malloc failed!\n"); ret = 0; goto err; } if (EVP_PKEY_derive(dh_ctx, secret_ff_a, &secret_size) <= 0){ WARN("# FAIL Shared secret derive failure.\n"); ret = 0; goto err; } /* Now check from side B */ test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL); if (!test_ctx){ WARN("# FAIL while allocating EVP_PKEY_CTX.\n"); ret = 0; goto err; } if (!EVP_PKEY_derive_init(test_ctx) || !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) || !EVP_PKEY_derive(test_ctx, NULL, &test_out) || !EVP_PKEY_derive(test_ctx, secret_ff_b, &test_out) || test_out != secret_size){ WARN("# FAIL DH computation failure.\n"); ret = 0; goto err; } /* compare the computed secrets */ if (CRYPTO_memcmp(secret_ff_a, secret_ff_b, secret_size)){ WARN("# FAIL DH computations don't match.\n"); ret = 0; goto err; } INFO("# PASS verify for DH. \n"); #endif err: #ifndef ENABLE_QAT_FIPS if (ret != 1) ERR_print_errors_fp(stderr); #endif #ifdef QAT_OPENSSL_PROVIDER EVP_PKEY_free(pkey_A); pkey_A = NULL; EVP_PKEY_free(pkey_B); pkey_B = NULL; EVP_PKEY_CTX_free(test_ctx); test_ctx = NULL; OPENSSL_free(secret_ff_a); secret_ff_a = NULL; OPENSSL_free(secret_ff_b); secret_ff_b = NULL; #endif #ifndef QAT_OPENSSL_PROVIDER if (abuf != NULL) OPENSSL_free(abuf); if (bbuf != NULL) OPENSSL_free(bbuf); if (dh_b != NULL) DH_free(dh_b); if (dh_a != NULL) DH_free(dh_a); BIO_free(out); #endif return ret; } /****************************************************************************** * function: * tests_run_dh (TEST_PARAMS *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ void tests_run_dh(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_dh(args); else start_async_job(args, run_dh); } qatengine-1.9.0/test/tests_dsa.c000066400000000000000000001052411500416242000166050ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #ifdef QAT_OPENSSL_PROVIDER # include #endif #include "tests.h" #include "../qat_utils.h" static unsigned char BN_p[] = { 0xD7, 0x57, 0x26, 0x2C, 0x45, 0x84, 0xC4, 0x4C, 0x21, 0x1F, 0x18, 0xBD, 0x96, 0xE5, 0xF0, 0x61, 0xC4, 0xF0, 0xA4, 0x23, 0xF7, 0xFE, 0x6B, 0x6B, 0x85, 0xB3, 0x4C, 0xEF, 0x72, 0xCE, 0x14, 0xA0, 0xD3, 0xA5, 0x22, 0x2F, 0xE0, 0x8C, 0xEC, 0xE6, 0x5B, 0xE6, 0xC2, 0x65, 0x85, 0x48, 0x89, 0xDC, 0x1E, 0xDB, 0xD1, 0x3E, 0xC8, 0xB2, 0x74, 0xDA, 0x9F, 0x75, 0xBA, 0x26, 0xCC, 0xB9, 0x87, 0x72, 0x36, 0x02, 0x78, 0x7E, 0x92, 0x2B, 0xA8, 0x44, 0x21, 0xF2, 0x2C, 0x3C, 0x89, 0xCB, 0x9B, 0x06, 0xFD, 0x60, 0xFE, 0x01, 0x94, 0x1D, 0xDD, 0x77, 0xFE, 0x6B, 0x12, 0x89, 0x3D, 0xA7, 0x6E, 0xEB, 0xC1, 0xD1, 0x28, 0xD9, 0x7F, 0x06, 0x78, 0xD7, 0x72, 0x2B, 0x53, 0x41, 0xC8, 0x50, 0x6F, 0x35, 0x82, 0x14, 0xB1, 0x6A, 0x2F, 0xAC, 0x4B, 0x36, 0x89, 0x50, 0x38, 0x78, 0x11, 0xC7, 0xDA, 0x33, }; static unsigned char BN_q[] = { 0xC7, 0x73, 0x21, 0x8C, 0x73, 0x7E, 0xC8, 0xEE, 0x99, 0x3B, 0x4F, 0x2D, 0xED, 0x30, 0xF4, 0x8E, 0xDA, 0xCE, 0x91, 0x5F, }; static unsigned char BN_g[] = { 0x82, 0x26, 0x90, 0x09, 0xE1, 0x4E, 0xC4, 0x74, 0xBA, 0xF2, 0x93, 0x2E, 0x69, 0xD3, 0xB1, 0xF1, 0x85, 0x17, 0xAD, 0x95, 0x94, 0x18, 0x4C, 0xCD, 0xFC, 0xEA, 0xE9, 0x6E, 0xC4, 0xD5, 0xEF, 0x93, 0x13, 0x3E, 0x84, 0xB4, 0x70, 0x93, 0xC5, 0x2B, 0x20, 0xCD, 0x35, 0xD0, 0x24, 0x92, 0xB3, 0x95, 0x9E, 0xC6, 0x49, 0x96, 0x25, 0xBC, 0x4F, 0xA5, 0x08, 0x2E, 0x22, 0xC5, 0xB3, 0x74, 0xE1, 0x6D, 0xD0, 0x01, 0x32, 0xCE, 0x71, 0xB0, 0x20, 0x21, 0x70, 0x91, 0xAC, 0x71, 0x7B, 0x61, 0x23, 0x91, 0xC7, 0x6C, 0x1F, 0xB2, 0xE8, 0x83, 0x17, 0xC1, 0xBD, 0x81, 0x71, 0xD4, 0x1E, 0xCB, 0x83, 0xE2, 0x10, 0xC0, 0x3C, 0xC9, 0xB3, 0x2E, 0x81, 0x05, 0x61, 0xC2, 0x16, 0x21, 0xC7, 0x3D, 0x6D, 0xAA, 0xC0, 0x28, 0xF4, 0xB1, 0x58, 0x5D, 0xA7, 0xF4, 0x25, 0x19, 0x71, 0x8C, 0xC9, 0xB0, 0x9E, 0xEF, }; static unsigned char Pub_key[] = { 0x52, 0x3C, 0x3E, 0x53, 0x41, 0xC3, 0xC8, 0xDF, 0x22, 0x4E, 0x07, 0x0C, 0x99, 0x76, 0xFC, 0x7D, 0xF1, 0x95, 0xD3, 0xC5, 0x1D, 0x67, 0x1A, 0xF2, 0xC9, 0x68, 0xA2, 0xA1, 0x41, 0x35, 0x1F, 0xFC, 0x64, 0x47, 0x65, 0xAD, 0xEB, 0xC4, 0x71, 0xD5, 0x1B, 0xC2, 0xEF, 0x76, 0x21, 0xE9, 0xED, 0x6A, 0xA6, 0xD9, 0xDB, 0x5B, 0xBB, 0x81, 0x43, 0x8F, 0xC0, 0x1E, 0xE6, 0x49, 0x2A, 0xB7, 0xEA, 0x8F, 0xCB, 0x6B, 0x93, 0x1E, 0x94, 0x8C, 0x24, 0x48, 0xE3, 0x80, 0xD3, 0x9B, 0x4F, 0xDC, 0xBF, 0x45, 0xE3, 0xC0, 0xFC, 0xDA, 0x1C, 0x06, 0x74, 0xF9, 0x02, 0x2A, 0x5A, 0xAA, 0x18, 0x58, 0x1D, 0x12, 0x4D, 0x07, 0x0F, 0x00, 0xB4, 0x5E, 0xA3, 0x62, 0xB1, 0xFA, 0xEE, 0x05, 0x04, 0x89, 0x27, 0x5A, 0x68, 0xBF, 0x8B, 0x19, 0x90, 0x84, 0x21, 0xB8, 0xFB, 0x3B, 0x37, 0x04, 0x4D, 0x6B, 0xB6, 0xD2, }; static unsigned char Priv_key[] = { 0x6E, 0xB5, 0x08, 0x61, 0xE5, 0x25, 0xD7, 0xEF, 0x6C, 0x53, 0xBD, 0x77, 0x72, 0x0F, 0x98, 0xE1, 0x60, 0x3D, 0x67, 0x67, }; #ifdef QAT_OPENSSL_PROVIDER static unsigned char dsa1024_priv[] = { 0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8, 0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18, }; static unsigned char dsa1024_pub[] = { 0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63, 0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50, 0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e, 0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5, 0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68, 0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82, 0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04, 0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28, 0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e, 0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97, 0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b }; static unsigned char dsa1024_p[] = { 0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47, 0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D, 0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73, 0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9, 0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5, 0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E, 0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7, 0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95, 0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE, 0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80, 0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49, }; static unsigned char dsa1024_q[] = { 0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C, 0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F, }; static unsigned char dsa1024_g[] = { 0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46, 0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D, 0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88, 0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18, 0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61, 0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F, 0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16, 0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6, 0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5, 0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5, 0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8, }; static unsigned char dsa2048_224_priv[] = { 0x6c, 0xca, 0xee, 0xf6, 0xd7, 0x3b, 0x4e, 0x80, 0xf1, 0x1c, 0x17, 0xb8, 0xe9, 0x62, 0x7c, 0x03, 0x66, 0x35, 0xba, 0xc3, 0x94, 0x23, 0x50, 0x5e, 0x40, 0x7e, 0x5c, 0xb7 }; static unsigned char dsa2048_224_pub[] = { 0xa0, 0x12, 0xb3, 0xb1, 0x70, 0xb3, 0x07, 0x22, 0x79, 0x57, 0xb7, 0xca, 0x20, 0x61, 0xa8, 0x16, 0xac, 0x7a, 0x2b, 0x3d, 0x9a, 0xe9, 0x95, 0xa5, 0x11, 0x9c, 0x38, 0x5b, 0x60, 0x3b, 0xf6, 0xf6, 0xc5, 0xde, 0x4d, 0xc5, 0xec, 0xb5, 0xdf, 0xa4, 0xa4, 0x1c, 0x68, 0x66, 0x2e, 0xb2, 0x5b, 0x63, 0x8b, 0x7e, 0x26, 0x20, 0xba, 0x89, 0x8d, 0x07, 0xda, 0x6c, 0x49, 0x91, 0xe7, 0x6c, 0xc0, 0xec, 0xd1, 0xad, 0x34, 0x21, 0x07, 0x70, 0x67, 0xe4, 0x7c, 0x18, 0xf5, 0x8a, 0x92, 0xa7, 0x2a, 0xd4, 0x31, 0x99, 0xec, 0xb7, 0xbd, 0x84, 0xe7, 0xd3, 0xaf, 0xb9, 0x01, 0x9f, 0x0e, 0x9d, 0xd0, 0xfb, 0xaa, 0x48, 0x73, 0x00, 0xb1, 0x30, 0x81, 0xe3, 0x3c, 0x90, 0x28, 0x76, 0x43, 0x6f, 0x7b, 0x03, 0xc3, 0x45, 0x52, 0x84, 0x81, 0xd3, 0x62, 0x81, 0x5e, 0x24, 0xfe, 0x59, 0xda, 0xc5, 0xac, 0x34, 0x66, 0x0d, 0x4c, 0x8a, 0x76, 0xcb, 0x99, 0xa7, 0xc7, 0xde, 0x93, 0xeb, 0x95, 0x6c, 0xd6, 0xbc, 0x88, 0xe5, 0x8d, 0x90, 0x10, 0x34, 0x94, 0x4a, 0x09, 0x4b, 0x01, 0x80, 0x3a, 0x43, 0xc6, 0x72, 0xb9, 0x68, 0x8c, 0x0e, 0x01, 0xd8, 0xf4, 0xfc, 0x91, 0xc6, 0x2a, 0x3f, 0x88, 0x02, 0x1f, 0x7b, 0xd6, 0xa6, 0x51, 0xb1, 0xa8, 0x8f, 0x43, 0xaa, 0x4e, 0xf2, 0x76, 0x53, 0xd1, 0x2b, 0xf8, 0xb7, 0x09, 0x9f, 0xdf, 0x6b, 0x46, 0x10, 0x82, 0xf8, 0xe9, 0x39, 0x10, 0x7b, 0xfd, 0x2f, 0x72, 0x10, 0x08, 0x7d, 0x32, 0x6c, 0x37, 0x52, 0x00, 0xf1, 0xf5, 0x1e, 0x7e, 0x74, 0xa3, 0x41, 0x31, 0x90, 0x1b, 0xcd, 0x08, 0x63, 0x52, 0x1f, 0xf8, 0xd6, 0x76, 0xc4, 0x85, 0x81, 0x86, 0x87, 0x36, 0xc5, 0xe5, 0x1b, 0x16, 0xa4, 0xe3, 0x92, 0x15, 0xea, 0x0b, 0x17, 0xc4, 0x73, 0x59, 0x74, 0xc5, 0x16 }; static unsigned char dsa2048_224_p[] = { 0xa2, 0x9b, 0x88, 0x72, 0xce, 0x8b, 0x84, 0x23, 0xb7, 0xd5, 0xd2, 0x1d, 0x4b, 0x02, 0xf5, 0x7e, 0x03, 0xe9, 0xe6, 0xb8, 0xa2, 0x58, 0xdc, 0x16, 0x61, 0x1b, 0xa0, 0x98, 0xab, 0x54, 0x34, 0x15, 0xe4, 0x15, 0xf1, 0x56, 0x99, 0x7a, 0x3e, 0xe2, 0x36, 0x65, 0x8f, 0xa0, 0x93, 0x26, 0x0d, 0xe3, 0xad, 0x42, 0x2e, 0x05, 0xe0, 0x46, 0xf9, 0xec, 0x29, 0x16, 0x1a, 0x37, 0x5f, 0x0e, 0xb4, 0xef, 0xfc, 0xef, 0x58, 0x28, 0x5c, 0x5d, 0x39, 0xed, 0x42, 0x5d, 0x7a, 0x62, 0xca, 0x12, 0x89, 0x6c, 0x4a, 0x92, 0xcb, 0x19, 0x46, 0xf2, 0x95, 0x2a, 0x48, 0x13, 0x3f, 0x07, 0xda, 0x36, 0x4d, 0x1b, 0xdf, 0x6b, 0x0f, 0x71, 0x39, 0x98, 0x3e, 0x69, 0x3c, 0x80, 0x05, 0x9b, 0x0e, 0xac, 0xd1, 0x47, 0x9b, 0xa9, 0xf2, 0x85, 0x77, 0x54, 0xed, 0xe7, 0x5f, 0x11, 0x2b, 0x07, 0xeb, 0xbf, 0x35, 0x34, 0x8b, 0xbf, 0x3e, 0x01, 0xe0, 0x2f, 0x2d, 0x47, 0x3d, 0xe3, 0x94, 0x53, 0xf9, 0x9d, 0xd2, 0x36, 0x75, 0x41, 0xca, 0xca, 0x3b, 0xa0, 0x11, 0x66, 0x34, 0x3d, 0x7b, 0x5b, 0x58, 0xa3, 0x7b, 0xd1, 0xb7, 0x52, 0x1d, 0xb2, 0xf1, 0x3b, 0x86, 0x70, 0x71, 0x32, 0xfe, 0x09, 0xf4, 0xcd, 0x09, 0xdc, 0x16, 0x18, 0xfa, 0x34, 0x01, 0xeb, 0xf9, 0xcc, 0x7b, 0x19, 0xfa, 0x94, 0xaa, 0x47, 0x20, 0x88, 0x13, 0x3d, 0x6c, 0xb2, 0xd3, 0x5c, 0x11, 0x79, 0xc8, 0xc8, 0xff, 0x36, 0x87, 0x58, 0xd5, 0x07, 0xd9, 0xf9, 0xa1, 0x7d, 0x46, 0xc1, 0x10, 0xfe, 0x31, 0x44, 0xce, 0x9b, 0x02, 0x2b, 0x42, 0xe4, 0x19, 0xeb, 0x4f, 0x53, 0x88, 0x61, 0x3b, 0xfc, 0x3e, 0x26, 0x24, 0x1a, 0x43, 0x2e, 0x87, 0x06, 0xbc, 0x58, 0xef, 0x76, 0x11, 0x72, 0x78, 0xde, 0xab, 0x6c, 0xf6, 0x92, 0x61, 0x82, 0x91, 0xb7 }; static unsigned char dsa2048_224_q[] = { 0xa3, 0xbf, 0xd9, 0xab, 0x78, 0x84, 0x79, 0x4e, 0x38, 0x34, 0x50, 0xd5, 0x89, 0x1d, 0xc1, 0x8b, 0x65, 0x15, 0x7b, 0xdc, 0xfc, 0xda, 0xc5, 0x15, 0x18, 0x90, 0x28, 0x67 }; static unsigned char dsa2048_224_g[] = { 0x68, 0x19, 0x27, 0x88, 0x69, 0xc7, 0xfd, 0x3d, 0x2d, 0x7b, 0x77, 0xf7, 0x7e, 0x81, 0x50, 0xd9, 0xad, 0x43, 0x3b, 0xea, 0x3b, 0xa8, 0x5e, 0xfc, 0x80, 0x41, 0x5a, 0xa3, 0x54, 0x5f, 0x78, 0xf7, 0x22, 0x96, 0xf0, 0x6c, 0xb1, 0x9c, 0xed, 0xa0, 0x6c, 0x94, 0xb0, 0x55, 0x1c, 0xfe, 0x6e, 0x6f, 0x86, 0x3e, 0x31, 0xd1, 0xde, 0x6e, 0xed, 0x7d, 0xab, 0x8b, 0x0c, 0x9d, 0xf2, 0x31, 0xe0, 0x84, 0x34, 0xd1, 0x18, 0x4f, 0x91, 0xd0, 0x33, 0x69, 0x6b, 0xb3, 0x82, 0xf8, 0x45, 0x5e, 0x98, 0x88, 0xf5, 0xd3, 0x1d, 0x47, 0x84, 0xec, 0x40, 0x12, 0x02, 0x46, 0xf4, 0xbe, 0xa6, 0x17, 0x94, 0xbb, 0xa5, 0x86, 0x6f, 0x09, 0x74, 0x64, 0x63, 0xbd, 0xf8, 0xe9, 0xe1, 0x08, 0xcd, 0x95, 0x29, 0xc3, 0xd0, 0xf6, 0xdf, 0x80, 0x31, 0x6e, 0x2e, 0x70, 0xaa, 0xeb, 0x1b, 0x26, 0xcd, 0xb8, 0xad, 0x97, 0xbc, 0x3d, 0x28, 0x7e, 0x0b, 0x8d, 0x61, 0x6c, 0x42, 0xe6, 0x5b, 0x87, 0xdb, 0x20, 0xde, 0xb7, 0x00, 0x5b, 0xc4, 0x16, 0x74, 0x7a, 0x64, 0x70, 0x14, 0x7a, 0x68, 0xa7, 0x82, 0x03, 0x88, 0xeb, 0xf4, 0x4d, 0x52, 0xe0, 0x62, 0x8a, 0xf9, 0xcf, 0x1b, 0x71, 0x66, 0xd0, 0x34, 0x65, 0xf3, 0x5a, 0xcc, 0x31, 0xb6, 0x11, 0x0c, 0x43, 0xda, 0xbc, 0x7c, 0x5d, 0x59, 0x1e, 0x67, 0x1e, 0xaf, 0x7c, 0x25, 0x2c, 0x1c, 0x14, 0x53, 0x36, 0xa1, 0xa4, 0xdd, 0xf1, 0x32, 0x44, 0xd5, 0x5e, 0x83, 0x56, 0x80, 0xca, 0xb2, 0x53, 0x3b, 0x82, 0xdf, 0x2e, 0xfe, 0x55, 0xec, 0x18, 0xc1, 0xe6, 0xcd, 0x00, 0x7b, 0xb0, 0x89, 0x75, 0x8b, 0xb1, 0x7c, 0x2c, 0xbe, 0x14, 0x44, 0x1b, 0xd0, 0x93, 0xae, 0x66, 0xe5, 0x97, 0x6d, 0x53, 0x73, 0x3f, 0x4f, 0xa3, 0x26, 0x97, 0x01, 0xd3, 0x1d, 0x23, 0xd4, 0x67 }; /* dsa 3072 */ static unsigned char dsa3072_priv[] = { 0x1B, 0x28, 0x82, 0xDA, 0x37, 0xAC, 0xE5, 0x05, 0x00, 0x0D, 0x3A, 0x4C, 0x86, 0x54, 0xEE, 0x2B, 0x09, 0xA7, 0x88, 0x1F, 0xB3, 0x99, 0x56, 0x87, 0x77, 0x7F, 0x67, 0xFD, 0x6F, 0x4D, 0x2F, 0xEC }; static unsigned char dsa3072_pub[] = { 0x95, 0x32, 0x25, 0xEB, 0x53, 0x7F, 0x26, 0x52, 0xED, 0xF0, 0xC1, 0x3C, 0x89, 0x87, 0x3E, 0xAD, 0x75, 0xE7, 0x76, 0xB0, 0x52, 0x59, 0x0C, 0x1B, 0x13, 0x8F, 0x36, 0xB1, 0xE7, 0x53, 0x10, 0xA2, 0x4E, 0x9A, 0x6F, 0xA4, 0x84, 0x52, 0x62, 0xDB, 0xDE, 0xAA, 0xA2, 0x06, 0x9D, 0x3C, 0xF5, 0x4E, 0xCA, 0x47, 0x9C, 0x9B, 0x40, 0x73, 0x1E, 0xAA, 0x68, 0x00, 0x89, 0x2B, 0x8F, 0xEA, 0xAE, 0x3C, 0x44, 0xC3, 0x55, 0xDE, 0x11, 0xFC, 0x75, 0x5C, 0x75, 0x5C, 0xBC, 0x66, 0xE9, 0xB4, 0x37, 0x74, 0xFD, 0x55, 0x8D, 0x05, 0x25, 0x5B, 0x7F, 0x34, 0xEC, 0x33, 0x9E, 0x72, 0x1B, 0x9F, 0x9A, 0x93, 0x04, 0x72, 0x90, 0xDF, 0x0C, 0xAA, 0x52, 0x32, 0xC9, 0x9F, 0xC6, 0x21, 0xA3, 0x75, 0xB4, 0xAF, 0xA6, 0x57, 0x6B, 0xFD, 0xB8, 0xDE, 0x78, 0xB3, 0x03, 0x51, 0x11, 0xE5, 0xAE, 0x81, 0x22, 0xEB, 0xDF, 0xFC, 0x21, 0x63, 0x60, 0xD8, 0x4F, 0x92, 0xF1, 0x77, 0x09, 0x9E, 0xCD, 0x82, 0xB1, 0x0B, 0x07, 0x04, 0xAB, 0x19, 0x65, 0x98, 0x9B, 0xC9, 0x2A, 0x74, 0xA8, 0xEF, 0xED, 0x71, 0x2F, 0x9B, 0x50, 0xA2, 0xB8, 0xF3, 0x2B, 0x60, 0x68, 0xE5, 0xC7, 0xCB, 0xA7, 0x15, 0x4E, 0x56, 0x18, 0x6F, 0x2C, 0xDF, 0x39, 0x8B, 0x24, 0x09, 0x04, 0x71, 0x67, 0x6D, 0x88, 0x8F, 0x85, 0xAB, 0xF4, 0x69, 0xE4, 0xCD, 0x66, 0x8D, 0xE6, 0x11, 0xE0, 0x3F, 0x16, 0xA3, 0xC9, 0xC8, 0x19, 0xE3, 0xF5, 0x36, 0x86, 0x3F, 0xB3, 0xD9, 0xBF, 0x94, 0x7E, 0x35, 0xC5, 0x1E, 0xC6, 0x84, 0x6A, 0x44, 0x01, 0x26, 0xA0, 0xFB, 0xA3, 0x7C, 0xE3, 0x3A, 0x99, 0x0C, 0x66, 0x6B, 0x27, 0x37, 0xB7, 0x25, 0x6A, 0x4E, 0x6F, 0x90, 0x43, 0x19, 0x91, 0x2F, 0x82, 0xD0, 0x1A, 0x62, 0x87, 0x30, 0xF7, 0x93, 0x15, 0xEB, 0x4F, 0xFE, 0xF8, 0xB8, 0xB6, 0x2B, 0xCA, 0xF0, 0xEE, 0xA5, 0x65, 0x4B, 0x3B, 0x5A, 0xE8, 0xDC, 0x79, 0xBE, 0xF0, 0xEB, 0x4E, 0x7B, 0xA9, 0xFB, 0xC2, 0x83, 0x91, 0xE9, 0x4D, 0x9F, 0xEE, 0x04, 0x0E, 0xC9, 0x6A, 0xB4, 0x11, 0x7A, 0x18, 0xD1, 0xC0, 0x5C, 0x70, 0xA7, 0x68, 0xFB, 0xAB, 0x41, 0xEF, 0xA8, 0x73, 0x20, 0xAE, 0xCC, 0x5E, 0xB4, 0x73, 0x19, 0xF1, 0x7E, 0x7B, 0x0A, 0x0F, 0x5F, 0x4D, 0x1B, 0xDB, 0xDB, 0x92, 0x98, 0x36, 0x92, 0xFF, 0x17, 0x17, 0xC1, 0xDD, 0x1F, 0x85, 0x27, 0x74, 0xC8, 0xDE, 0x61, 0x72, 0x25, 0xFA, 0xAA, 0x75, 0xAA, 0xD4, 0x53, 0x63, 0x54, 0x77, 0xCA, 0x69, 0xD6, 0x22, 0x3A, 0x18, 0xD7, 0xFD, 0x26, 0x66, 0x91, 0xC2, 0xA1, 0xAB, 0x85, 0x19, 0x3E, 0xF7, 0x1E, 0xAD, 0xB3, 0x5A, 0x87, 0x76, 0x98, 0xF0, 0xAD, 0x0C, 0xE2, 0x70, 0xD2, 0x44, 0x29 }; static unsigned char dsa3072_p[] = { 0xA8, 0x50, 0x7A, 0x44, 0x32, 0xCA, 0x8F, 0xCD, 0xCC, 0x3B, 0xC4, 0x1C, 0xA7, 0x16, 0x30, 0x68, 0x41, 0xAC, 0x8E, 0xE7, 0x39, 0xFB, 0xC5, 0x86, 0xCA, 0x50, 0x66, 0x49, 0x33, 0x36, 0x2D, 0x9D, 0xA9, 0x38, 0x15, 0x85, 0x34, 0xD9, 0x62, 0xAF, 0x31, 0xA6, 0x1C, 0x3A, 0x7B, 0x96, 0x31, 0xF5, 0x47, 0x02, 0x3B, 0x0A, 0xE7, 0x38, 0xED, 0x91, 0x27, 0xEA, 0x40, 0x4A, 0xA5, 0xDA, 0xF7, 0xA1, 0x30, 0x48, 0x8A, 0xB6, 0xD2, 0x5E, 0x06, 0x9A, 0x0F, 0x8D, 0x3E, 0x3A, 0x49, 0xF7, 0x8B, 0xB1, 0x06, 0xA1, 0x61, 0x6B, 0xB2, 0x5C, 0x64, 0x1E, 0x02, 0x80, 0xF2, 0x3E, 0xB8, 0x81, 0xC1, 0x71, 0x0F, 0x31, 0x85, 0xB2, 0x13, 0xCB, 0xBF, 0xC4, 0x75, 0x2D, 0x9D, 0x92, 0x0C, 0x9D, 0xDD, 0x2B, 0xA8, 0x91, 0x7A, 0xEF, 0x64, 0x81, 0xBC, 0x72, 0x59, 0x73, 0xA2, 0x2C, 0xCD, 0x24, 0x31, 0x87, 0xFC, 0x5E, 0xEC, 0xF1, 0x6B, 0x41, 0xA8, 0x40, 0xD7, 0xDE, 0x94, 0x55, 0x7E, 0x75, 0xB2, 0x52, 0xD4, 0xF4, 0x17, 0xCF, 0xFF, 0xE9, 0x52, 0x66, 0x4C, 0x62, 0xE1, 0xB9, 0x18, 0x15, 0x36, 0x02, 0xF7, 0xEC, 0xF3, 0x43, 0x84, 0x93, 0xF8, 0x7E, 0x93, 0xDE, 0x83, 0x39, 0x85, 0x93, 0xE9, 0xF4, 0x8E, 0x66, 0xFD, 0x36, 0xD3, 0x8B, 0x48, 0x44, 0xEB, 0x3F, 0x9C, 0x56, 0xE1, 0x4C, 0x1C, 0x0B, 0x11, 0xAB, 0xA9, 0xAA, 0x80, 0xDC, 0x75, 0x47, 0x3D, 0xF1, 0x1B, 0x1C, 0x00, 0x85, 0xFC, 0x23, 0x49, 0x6D, 0xD0, 0x9D, 0x89, 0x79, 0xA2, 0xBD, 0xF6, 0xB5, 0xB4, 0x9D, 0xDB, 0x05, 0x17, 0xF3, 0xD3, 0x2D, 0x38, 0xCD, 0xB4, 0xA1, 0x42, 0xE5, 0x17, 0xB0, 0xF7, 0x3F, 0xD4, 0x84, 0xD6, 0x36, 0x62, 0x64, 0x9C, 0xD5, 0x0A, 0xBD, 0xB2, 0xD9, 0x50, 0x16, 0xC1, 0x49, 0x17, 0x23, 0xCE, 0xD0, 0xC0, 0x29, 0x76, 0x40, 0xE0, 0x19, 0x8C, 0x75, 0xA2, 0x28, 0x59, 0xC1, 0xC6, 0x63, 0x67, 0xEA, 0x80, 0xF3, 0x16, 0xD1, 0x71, 0x0E, 0x44, 0xF8, 0x00, 0xAE, 0x64, 0xB9, 0x7B, 0x1F, 0x6D, 0xB9, 0x4C, 0x89, 0x36, 0x0C, 0x52, 0x9D, 0xEC, 0xE2, 0x2E, 0x6C, 0x95, 0xC4, 0x7F, 0xFE, 0xCE, 0x54, 0x2C, 0xA7, 0x03, 0xCD, 0x7A, 0xBE, 0xD0, 0x76, 0x41, 0x5D, 0x64, 0xA8, 0xA3, 0x0C, 0x5B, 0x02, 0x68, 0x6F, 0xA0, 0x34, 0xF8, 0x31, 0xF7, 0x4D, 0x8E, 0x3B, 0x66, 0x7F, 0x23, 0xAC, 0x22, 0xD4, 0x84, 0x1A, 0x4C, 0xC2, 0x72, 0xDB, 0x68, 0xFD, 0xAE, 0x60, 0xAC, 0x05, 0xCB, 0xE7, 0x67, 0x05, 0x86, 0x72, 0xF1, 0xB1, 0x33, 0x68, 0xF6, 0x70, 0xDD, 0x99, 0xFE, 0x35, 0x1D, 0x98, 0x00, 0x74, 0x3C, 0xEC, 0x39, 0x6E, 0x3C, 0x91, 0xB3, 0x80, 0x58, 0x19, 0x38, 0xEC, 0xD7, 0xAC, 0x69, 0x53 }; static unsigned char dsa3072_q[] = { 0x95, 0x76, 0xFA, 0x68, 0x5A, 0x13, 0x06, 0x2F, 0xF8, 0xEA, 0x34, 0x4B, 0xCC, 0xF4, 0x14, 0xAA, 0x14, 0x92, 0x73, 0xB6, 0xC7, 0x8D, 0xAF, 0x4D, 0xE4, 0xEA, 0x5E, 0xFB, 0xF3, 0xA6, 0x84, 0xD5 }; static unsigned char dsa3072_g[] = { 0x8B, 0xCA, 0xEB, 0xB9, 0x97, 0x57, 0x85, 0xB4, 0x06, 0x45, 0xC0, 0x5D, 0x94, 0xB0, 0x84, 0x41, 0x72, 0x0B, 0x0A, 0x6F, 0xF6, 0x82, 0x1B, 0x8D, 0xB1, 0xDC, 0xB2, 0xCE, 0x07, 0x2E, 0x3E, 0xBE, 0x07, 0xFB, 0xBC, 0x56, 0x4E, 0x6D, 0x59, 0xCB, 0xE1, 0x07, 0x66, 0xE9, 0x4C, 0xE4, 0x16, 0xCF, 0xE6, 0xFF, 0x80, 0xF0, 0xFD, 0x09, 0xA0, 0x13, 0x0A, 0x24, 0xE6, 0x85, 0x00, 0x14, 0x37, 0x46, 0x18, 0xC2, 0xC3, 0xAD, 0x8B, 0x31, 0x26, 0xF1, 0x86, 0x42, 0x7C, 0xF8, 0x84, 0x00, 0xE9, 0x52, 0x2A, 0x30, 0x8B, 0x4E, 0x44, 0x35, 0xE0, 0xB1, 0xCA, 0xBA, 0xBB, 0x1C, 0xA7, 0xC7, 0x6F, 0x8D, 0x85, 0x24, 0x9D, 0x8B, 0x1F, 0x12, 0x1D, 0xE0, 0x25, 0x0F, 0x8E, 0x82, 0xD8, 0x76, 0x06, 0x96, 0xDC, 0xE0, 0x98, 0xAD, 0x4F, 0xD8, 0x52, 0xE9, 0x54, 0x44, 0x61, 0x2B, 0xC8, 0xFC, 0x2A, 0xAC, 0x4A, 0x01, 0x65, 0xFE, 0x81, 0xCB, 0xE7, 0xDB, 0x93, 0x6A, 0x1A, 0x5F, 0xC5, 0xDB, 0x2C, 0x8F, 0x77, 0x94, 0xCB, 0xFD, 0x8F, 0xEF, 0xF0, 0x77, 0x46, 0xA9, 0xBB, 0xCD, 0x44, 0xE3, 0xB5, 0x98, 0xFA, 0x61, 0x21, 0x7F, 0x6C, 0x8D, 0x4F, 0x4E, 0x4F, 0x1B, 0xFD, 0x4F, 0x2F, 0xFE, 0xB0, 0x7B, 0x99, 0xD6, 0x4A, 0xF6, 0xE1, 0x7E, 0xD5, 0xF2, 0xE2, 0xA0, 0xB4, 0x3B, 0x4E, 0xF3, 0xAE, 0xAC, 0x06, 0xD6, 0x50, 0x1A, 0xBB, 0xE9, 0x52, 0xAB, 0x57, 0x51, 0x3A, 0x35, 0x13, 0xD0, 0x41, 0x9C, 0x22, 0xAA, 0x39, 0x18, 0x46, 0xAD, 0xC7, 0x32, 0x48, 0x0C, 0x2A, 0xF1, 0x87, 0x1F, 0x5B, 0xB4, 0x1F, 0xE2, 0x9A, 0x60, 0x61, 0xA2, 0xFD, 0x5A, 0xCB, 0x03, 0x26, 0xA5, 0x57, 0x7D, 0xE8, 0x08, 0xFA, 0x71, 0x09, 0x4D, 0x0E, 0x29, 0xFF, 0xE4, 0xC0, 0x9A, 0x78, 0x5C, 0xEF, 0x1D, 0x39, 0xAF, 0x28, 0x18, 0xC6, 0x47, 0x4F, 0x64, 0xBD, 0x68, 0x76, 0x95, 0xE1, 0x4B, 0xC9, 0xFB, 0xB6, 0xBF, 0xF0, 0x96, 0xE2, 0xD7, 0x5E, 0x32, 0x66, 0x34, 0x1B, 0xB6, 0x36, 0xA1, 0xDA, 0x33, 0x5A, 0x29, 0xA2, 0x18, 0x96, 0xC5, 0x78, 0x76, 0x53, 0x9D, 0x02, 0xC9, 0x50, 0x49, 0xE7, 0xE6, 0xB7, 0x5C, 0x88, 0xD7, 0x2B, 0x14, 0x01, 0x1D, 0x4B, 0x81, 0xA1, 0x11, 0x8F, 0xB3, 0x45, 0x09, 0xBF, 0x87, 0x09, 0xF4, 0x3C, 0xF7, 0xC6, 0x75, 0x49, 0xBC, 0x0F, 0xE7, 0x3E, 0x8E, 0x84, 0x61, 0x6B, 0xA3, 0x08, 0x69, 0x98, 0x70, 0x3F, 0x75, 0x73, 0x0E, 0x33, 0xCB, 0xBC, 0x21, 0xFD, 0x2A, 0xC6, 0xF2, 0x06, 0x57, 0x00, 0x57, 0xF7, 0x9D, 0x26, 0x7D, 0xAF, 0x59, 0x0B, 0xBD, 0xA0, 0xFB, 0x8B, 0xB0, 0x7F, 0x78, 0xD3, 0xF7, 0x85, 0x26, 0x20, 0x60, 0xB0, 0xC7, 0xF5, 0xB6, 0x70, 0xFE, 0x28, 0xB1 }; /* dsa 2048-256 */ static unsigned char dsa2048_256_priv[] = { 0x69, 0xC7, 0x54, 0x8C, 0x21, 0xD0, 0xDF, 0xEA, 0x6B, 0x9A, 0x51, 0xC9, 0xEA, 0xD4, 0xE2, 0x7C, 0x33, 0xD3, 0xB3, 0xF1, 0x80, 0x31, 0x6E, 0x5B, 0xCA, 0xB9, 0x2C, 0x93, 0x3F, 0x0E, 0x4D, 0xBC }; static unsigned char dsa2048_256_pub[] = { 0x66, 0x70, 0x98, 0xC6, 0x54, 0x42, 0x6C, 0x78, 0xD7, 0xF8, 0x20, 0x1E, 0xAC, 0x6C, 0x20, 0x3E, 0xF0, 0x30, 0xD4, 0x36, 0x05, 0x03, 0x2C, 0x2F, 0x1F, 0xA9, 0x37, 0xE5, 0x23, 0x7D, 0xBD, 0x94, 0x9F, 0x34, 0xA0, 0xA2, 0x56, 0x4F, 0xE1, 0x26, 0xDC, 0x8B, 0x71, 0x5C, 0x51, 0x41, 0x80, 0x2C, 0xE0, 0x97, 0x9C, 0x82, 0x46, 0x46, 0x3C, 0x40, 0xE6, 0xB6, 0xBD, 0xAA, 0x25, 0x13, 0xFA, 0x61, 0x17, 0x28, 0x71, 0x6C, 0x2E, 0x4F, 0xD5, 0x3B, 0xC9, 0x5B, 0x89, 0xE6, 0x99, 0x49, 0xD9, 0x65, 0x12, 0xE8, 0x73, 0xB9, 0xC8, 0xF8, 0xDF, 0xD4, 0x99, 0xCC, 0x31, 0x28, 0x82, 0x56, 0x1A, 0xDE, 0xCB, 0x31, 0xF6, 0x58, 0xE9, 0x34, 0xC0, 0xC1, 0x97, 0xF2, 0xC4, 0xD9, 0x6B, 0x05, 0xCB, 0xAD, 0x67, 0x38, 0x1E, 0x7B, 0x76, 0x88, 0x91, 0xE4, 0xDA, 0x38, 0x43, 0xD2, 0x4D, 0x94, 0xCD, 0xFB, 0x51, 0x26, 0xE9, 0xB8, 0xBF, 0x21, 0xE8, 0x35, 0x8E, 0xE0, 0xE0, 0xA3, 0x0E, 0xF1, 0x3F, 0xD6, 0xA6, 0x64, 0xC0, 0xDC, 0xE3, 0x73, 0x1F, 0x7F, 0xB4, 0x9A, 0x48, 0x45, 0xA4, 0xFD, 0x82, 0x54, 0x68, 0x79, 0x72, 0xA2, 0xD3, 0x82, 0x59, 0x9C, 0x9B, 0xAC, 0x4E, 0x0E, 0xD7, 0x99, 0x81, 0x93, 0x07, 0x89, 0x13, 0x03, 0x25, 0x58, 0x13, 0x49, 0x76, 0x41, 0x0B, 0x89, 0xD2, 0xC1, 0x71, 0xD1, 0x23, 0xAC, 0x35, 0xFD, 0x97, 0x72, 0x19, 0x59, 0x7A, 0xA7, 0xD1, 0x5C, 0x1A, 0x9A, 0x42, 0x8E, 0x59, 0x19, 0x4F, 0x75, 0xC7, 0x21, 0xEB, 0xCB, 0xCF, 0xAE, 0x44, 0x69, 0x6A, 0x49, 0x9A, 0xFA, 0x74, 0xE0, 0x42, 0x99, 0xF1, 0x32, 0x02, 0x66, 0x01, 0x63, 0x8C, 0xB8, 0x7A, 0xB7, 0x91, 0x90, 0xD4, 0xA0, 0x98, 0x63, 0x15, 0xDA, 0x8E, 0xEC, 0x65, 0x61, 0xC9, 0x38, 0x99, 0x6B, 0xEA, 0xDF }; static unsigned char dsa2048_256_p[] = { 0x9D, 0xB6, 0xFB, 0x59, 0x51, 0xB6, 0x6B, 0xB6, 0xFE, 0x1E, 0x14, 0x0F, 0x1D, 0x2C, 0xE5, 0x50, 0x23, 0x74, 0x16, 0x1F, 0xD6, 0x53, 0x8D, 0xF1, 0x64, 0x82, 0x18, 0x64, 0x2F, 0x0B, 0x5C, 0x48, 0xC8, 0xF7, 0xA4, 0x1A, 0xAD, 0xFA, 0x18, 0x73, 0x24, 0xB8, 0x76, 0x74, 0xFA, 0x18, 0x22, 0xB0, 0x0F, 0x1E, 0xCF, 0x81, 0x36, 0x94, 0x3D, 0x7C, 0x55, 0x75, 0x72, 0x64, 0xE5, 0xA1, 0xA4, 0x4F, 0xFE, 0x01, 0x2E, 0x99, 0x36, 0xE0, 0x0C, 0x1D, 0x3E, 0x93, 0x10, 0xB0, 0x1C, 0x7D, 0x17, 0x98, 0x05, 0xD3, 0x05, 0x8B, 0x2A, 0x9F, 0x4B, 0xB6, 0xF9, 0x71, 0x6B, 0xFE, 0x61, 0x17, 0xC6, 0xB5, 0xB3, 0xCC, 0x4D, 0x9B, 0xE3, 0x41, 0x10, 0x4A, 0xD4, 0xA8, 0x0A, 0xD6, 0xC9, 0x4E, 0x00, 0x5F, 0x4B, 0x99, 0x3E, 0x14, 0xF0, 0x91, 0xEB, 0x51, 0x74, 0x3B, 0xF3, 0x30, 0x50, 0xC3, 0x8D, 0xE2, 0x35, 0x56, 0x7E, 0x1B, 0x34, 0xC3, 0xD6, 0xA5, 0xC0, 0xCE, 0xAA, 0x1A, 0x0F, 0x36, 0x82, 0x13, 0xC3, 0xD1, 0x98, 0x43, 0xD0, 0xB4, 0xB0, 0x9D, 0xCB, 0x9F, 0xC7, 0x2D, 0x39, 0xC8, 0xDE, 0x41, 0xF1, 0xBF, 0x14, 0xD4, 0xBB, 0x45, 0x63, 0xCA, 0x28, 0x37, 0x16, 0x21, 0xCA, 0xD3, 0x32, 0x4B, 0x6A, 0x2D, 0x39, 0x21, 0x45, 0xBE, 0xBF, 0xAC, 0x74, 0x88, 0x05, 0x23, 0x6F, 0x5C, 0xA2, 0xFE, 0x92, 0xB8, 0x71, 0xCD, 0x8F, 0x9C, 0x36, 0xD3, 0x29, 0x2B, 0x55, 0x09, 0xCA, 0x8C, 0xAA, 0x77, 0xA2, 0xAD, 0xFC, 0x7B, 0xFD, 0x77, 0xDD, 0xA6, 0xF7, 0x11, 0x25, 0xA7, 0x45, 0x6F, 0xEA, 0x15, 0x3E, 0x43, 0x32, 0x56, 0xA2, 0x26, 0x1C, 0x6A, 0x06, 0xED, 0x36, 0x93, 0x79, 0x7E, 0x79, 0x95, 0xFA, 0xD5, 0xAA, 0xBB, 0xCF, 0xBE, 0x3E, 0xDA, 0x27, 0x41, 0xE3, 0x75, 0x40, 0x4A, 0xE2, 0x5B }; static unsigned char dsa2048_256_q[] = { 0xF2, 0xC3, 0x11, 0x93, 0x74, 0xCE, 0x76, 0xC9, 0x35, 0x69, 0x90, 0xB4, 0x65, 0x37, 0x4A, 0x17, 0xF2, 0x3F, 0x9E, 0xD3, 0x50, 0x89, 0xBD, 0x96, 0x9F, 0x61, 0xC6, 0xDD, 0xE9, 0x99, 0x8C, 0x1F }; static unsigned char dsa2048_256_g[] = { 0x5C, 0x7F, 0xF6, 0xB0, 0x6F, 0x8F, 0x14, 0x3F, 0xE8, 0x28, 0x84, 0x33, 0x49, 0x3E, 0x47, 0x69, 0xC4, 0xD9, 0x88, 0xAC, 0xE5, 0xBE, 0x25, 0xA0, 0xE2, 0x48, 0x09, 0x67, 0x07, 0x16, 0xC6, 0x13, 0xD7, 0xB0, 0xCE, 0xE6, 0x93, 0x2F, 0x8F, 0xAA, 0x7C, 0x44, 0xD2, 0xCB, 0x24, 0x52, 0x3D, 0xA5, 0x3F, 0xBE, 0x4F, 0x6E, 0xC3, 0x59, 0x58, 0x92, 0xD1, 0xAA, 0x58, 0xC4, 0x32, 0x8A, 0x06, 0xC4, 0x6A, 0x15, 0x66, 0x2E, 0x7E, 0xAA, 0x70, 0x3A, 0x1D, 0xEC, 0xF8, 0xBB, 0xB2, 0xD0, 0x5D, 0xBE, 0x2E, 0xB9, 0x56, 0xC1, 0x42, 0xA3, 0x38, 0x66, 0x1D, 0x10, 0x46, 0x1C, 0x0D, 0x13, 0x54, 0x72, 0x08, 0x50, 0x57, 0xF3, 0x49, 0x43, 0x09, 0xFF, 0xA7, 0x3C, 0x61, 0x1F, 0x78, 0xB3, 0x2A, 0xDB, 0xB5, 0x74, 0x0C, 0x36, 0x1C, 0x9F, 0x35, 0xBE, 0x90, 0x99, 0x7D, 0xB2, 0x01, 0x4E, 0x2E, 0xF5, 0xAA, 0x61, 0x78, 0x2F, 0x52, 0xAB, 0xEB, 0x8B, 0xD6, 0x43, 0x2C, 0x4D, 0xD0, 0x97, 0xBC, 0x54, 0x23, 0xB2, 0x85, 0xDA, 0xFB, 0x60, 0xDC, 0x36, 0x4E, 0x81, 0x61, 0xF4, 0xA2, 0xA3, 0x5A, 0xCA, 0x3A, 0x10, 0xB1, 0xC4, 0xD2, 0x03, 0xCC, 0x76, 0xA4, 0x70, 0xA3, 0x3A, 0xFD, 0xCB, 0xDD, 0x92, 0x95, 0x98, 0x59, 0xAB, 0xD8, 0xB5, 0x6E, 0x17, 0x25, 0x25, 0x2D, 0x78, 0xEA, 0xC6, 0x6E, 0x71, 0xBA, 0x9A, 0xE3, 0xF1, 0xDD, 0x24, 0x87, 0x19, 0x98, 0x74, 0x39, 0x3C, 0xD4, 0xD8, 0x32, 0x18, 0x68, 0x00, 0x65, 0x47, 0x60, 0xE1, 0xE3, 0x4C, 0x09, 0xE4, 0xD1, 0x55, 0x17, 0x9F, 0x9E, 0xC0, 0xDC, 0x44, 0x73, 0xF9, 0x96, 0xBD, 0xCE, 0x6E, 0xED, 0x1C, 0xAB, 0xED, 0x8B, 0x6F, 0x11, 0x6F, 0x7A, 0xD9, 0xCF, 0x50, 0x5D, 0xF0, 0xF9, 0x98, 0xE3, 0x4A, 0xB2, 0x75, 0x14, 0xB0, 0xFF, 0xE7 }; typedef struct testdsa_st { unsigned char *priv; unsigned char *pub; unsigned char *p; unsigned char *g; unsigned char *q; int priv_l; int pub_l; int p_l; int g_l; int q_l; } testdsa; #define set_dsa_ptr(st, bits) \ do \ { \ st.priv = dsa##bits##_priv; \ st.pub = dsa##bits##_pub; \ st.p = dsa##bits##_p; \ st.g = dsa##bits##_g; \ st.q = dsa##bits##_q; \ st.priv_l = sizeof(dsa##bits##_priv); \ st.pub_l = sizeof(dsa##bits##_pub); \ st.p_l = sizeof(dsa##bits##_p); \ st.g_l = sizeof(dsa##bits##_g); \ st.q_l = sizeof(dsa##bits##_q); \ } while (0) EVP_PKEY *get_dsa(int dsa_bits, int q_size) { EVP_PKEY *pkey = NULL; BIGNUM *priv_key, *pub_key, *p, *q, *g; EVP_PKEY_CTX *pctx; testdsa dsa_t; OSSL_PARAM_BLD *tmpl = NULL; OSSL_PARAM *params = NULL; switch (dsa_bits) { case 1024: set_dsa_ptr(dsa_t, 1024); break; case 2048: if (q_size == 256) set_dsa_ptr(dsa_t, 2048_256); else set_dsa_ptr(dsa_t, 2048_224); break; case 3072: set_dsa_ptr(dsa_t, 3072); break; case 4096: dsa_t.priv = Priv_key; dsa_t.pub = Pub_key; dsa_t.p = BN_p; dsa_t.g = BN_g; dsa_t.q = BN_q; dsa_t.priv_l = sizeof(Priv_key); dsa_t.pub_l = sizeof(Pub_key); dsa_t.p_l = sizeof(BN_p); dsa_t.g_l = sizeof(BN_g); dsa_t.q_l = sizeof(BN_q); break; default: return NULL; } if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)) == NULL) return NULL; priv_key = BN_bin2bn(dsa_t.priv, dsa_t.priv_l, NULL); pub_key = BN_bin2bn(dsa_t.pub, dsa_t.pub_l, NULL); p = BN_bin2bn(dsa_t.p, dsa_t.p_l, NULL); q = BN_bin2bn(dsa_t.q, dsa_t.q_l, NULL); g = BN_bin2bn(dsa_t.g, dsa_t.g_l, NULL); if (priv_key == NULL || pub_key == NULL || p == NULL || q == NULL || g == NULL) { goto err; } if ((tmpl = OSSL_PARAM_BLD_new()) == NULL || !OSSL_PARAM_BLD_push_BN(tmpl, "p", p) || !OSSL_PARAM_BLD_push_BN(tmpl, "q", q) || !OSSL_PARAM_BLD_push_BN(tmpl, "g", g) || !OSSL_PARAM_BLD_push_BN(tmpl, "priv", priv_key) || !OSSL_PARAM_BLD_push_BN(tmpl, "pub", pub_key) || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) goto err; if (EVP_PKEY_fromdata_init(pctx) <= 0 || EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) pkey = NULL; err: OSSL_PARAM_free(params); OSSL_PARAM_BLD_free(tmpl); BN_free(priv_key); BN_free(pub_key); BN_free(p); BN_free(q); BN_free(g); EVP_PKEY_CTX_free(pctx); return pkey; } #endif /****************************************************************************** * function: * run_dsa(void *args) * * @param args [IN] - the test parameters * * description: * The function is design to test DSA sign and verify using qat engine. * *******************************************************************************/ static int run_dsa(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int size = temp_args->size; int ret = 0; #ifndef QAT_OPENSSL_PROVIDER int count = *(temp_args->count); int print_output = temp_args->print_output; int verify = temp_args->verify; DSA *dsa = NULL; BIGNUM *q = NULL; BIGNUM *p = NULL; BIGNUM *g = NULL; BIGNUM *pub_key = NULL; BIGNUM *priv_key = NULL; int i = 0; unsigned char sig[256] = {0}; unsigned int siglen = 0; unsigned char *DgstData = OPENSSL_malloc(size); if (DgstData == NULL) { WARN("# FAIL DSA DgstData Initial malloc failed ! \n"); exit(EXIT_FAILURE); } /* setup input hash message */ for (i = 0; i < size; i++) DgstData[i] = i % 16; if ((dsa = DSA_new()) == NULL) { WARN("# FAIL DSA DSA_new failed ! \n"); goto end; } if (((q = BN_bin2bn(BN_q, sizeof(BN_q), NULL)) == NULL) || ((p = BN_bin2bn(BN_p, sizeof(BN_p), NULL)) == NULL) || ((g = BN_bin2bn(BN_g, sizeof(BN_g), NULL)) == NULL) || ((pub_key = BN_bin2bn(Pub_key, sizeof(Pub_key), NULL)) == NULL) || ((priv_key = BN_bin2bn(Priv_key, sizeof(Priv_key), NULL)) == NULL)) { ret = 0; WARN("# FAIL DSA set DSA Parameters failed! \n"); if (q) BN_free(q); if (p) BN_free(p); if (g) BN_free(g); if (pub_key) BN_free(pub_key); if (priv_key) BN_free(priv_key); goto end; } DSA_set0_pqg(dsa, p, q, g); DSA_set0_key(dsa, pub_key, priv_key); for (i = 0; i < count; i++) { if (i == 0) { /* * DSA_sign() computes a digital signature on the size byte message * digest dgst using the private key dsa and places its ASN.1 DER * encoding at sig. The length of the signature is placed in * *siglen. sig must point to DSA_size(dsa) bytes of memory. */ DEBUG("%s starting DSA sign \n", __func__); ret = DSA_sign(0, DgstData, size, sig, &siglen, dsa); if (ret <= 0) { WARN("# FAIL DSA signature failed! \n"); goto end; } else DEBUG("# DSA signature completed! \n"); if (print_output) tests_hexdump(" DSA Signature:", sig, siglen); } if (i == 0 || verify) { /* * DSA_verify() verifies that the signature sig of size siglen * matches a given message digest dgst of length 'size'. dsa is the * signer's public key. Returns * 1: correct signature * 0: * incorrect signature * -1: error */ DEBUG("%s starting DSA verify! \n", __func__); ret = DSA_verify(0, DgstData, size, sig, siglen, dsa); if (ret <= 0) { INFO("# FAIL %s for DSA.\n", verify ? "verify" : "sign"); goto end; } else if (i == 0) INFO("# PASS %s for DSA.\n", verify ? "verify" : "sign"); } } #endif #ifdef QAT_OPENSSL_PROVIDER EVP_PKEY *dsa_key = NULL; EVP_PKEY_CTX *dsa_sign_ctx; EVP_PKEY_CTX *dsa_verify_ctx; unsigned char *buf = NULL; unsigned char *buf2 = NULL; size_t buflen = 16 * 1024; size_t sigsize = buflen; buf = OPENSSL_malloc(buflen); if (buf == NULL){ WARN("# FAIL DSA buf malloc failed! \n"); goto end; } buf2 = OPENSSL_malloc(buflen); if (buf2 == NULL){ WARN("# FAIL DSA buf2 malloc failed! \n"); goto end; } memset(buf, 0, buflen); memset(buf2, 0, buflen); if (RAND_bytes(buf, 36) <= 0){ WARN("# FAIL DSA get rand bytes failed! \n"); goto end; } if (size == 2048) dsa_key = get_dsa(size, temp_args->q_size); else dsa_key = get_dsa(size, 0); if (dsa_key == NULL){ WARN("# FAIL DSA get dsa key failed! \n"); goto end; } dsa_sign_ctx = EVP_PKEY_CTX_new(dsa_key, NULL); if (dsa_sign_ctx == NULL || EVP_PKEY_sign_init(dsa_sign_ctx) <= 0 || EVP_PKEY_sign(dsa_sign_ctx, buf2, &sigsize, buf, 20) <= 0){ WARN("# FAIL DSA PKEY sign failed! \n"); goto end; } INFO("# PASS DSA sign.\n"); dsa_verify_ctx = EVP_PKEY_CTX_new(dsa_key, NULL); if (dsa_verify_ctx == NULL || EVP_PKEY_verify_init(dsa_verify_ctx) <= 0 || EVP_PKEY_verify(dsa_verify_ctx, buf2, sigsize, buf, 20) <= 0){ WARN("# FAIL DSA verify init failed! \n"); goto end; } INFO("# PASS DSA verify.\n"); #endif end: DEBUG("%s start to clean up! \n", __func__); #ifdef QAT_OPENSSL_PROVIDER OPENSSL_free(buf); OPENSSL_free(buf2); #endif #ifndef QAT_OPENSSL_PROVIDER if (DgstData) OPENSSL_free(DgstData); if (dsa != NULL) DSA_free(dsa); #endif return ret; } void tests_run_dsa(TEST_PARAMS *args) { int i = 1; if (!args->enable_async) { if (args->size == 2048) { for (i = 1; i < KEY_TYPE_MAX; i++) { if (i == 1) { run_dsa(args); INFO("DSA 2048-224 test finished\n"); } else { args->q_size = 256; run_dsa(args); INFO("DSA 2048-256 test finished\n"); } } } else { run_dsa(args); } } else { start_async_job(args, run_dsa); } } qatengine-1.9.0/test/tests_ecdh.c000066400000000000000000000467061500416242000167530ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define ECDH_NEGATIVE_TESTCOUNT 2 /* Should be incremented when new negative tests added */ #ifdef QAT_OPENSSL_PROVIDER # define MAX_ECDH_SIZE 256 EVP_PKEY *get_ec_key(const int nid); #endif /****************************************************************************** * function: * get_nid (int type) * * @param type [IN] - type of the curve * * description: * get the object identifier for a particular curve * ******************************************************************************/ int get_nid(int type) { switch (type) { case P_CURVE_192: return NID_X9_62_prime192v1; case P_CURVE_224: return NID_secp224r1; case P_CURVE_256: return NID_X9_62_prime256v1; case P_CURVE_384: return NID_secp384r1; case P_CURVE_521: return NID_secp521r1; case K_CURVE_163: return NID_sect163k1; case K_CURVE_233: return NID_sect233k1; case K_CURVE_283: return NID_sect283k1; case K_CURVE_409: return NID_sect409k1; case K_CURVE_571: return NID_sect571k1; case B_CURVE_163: return NID_sect163r2; case B_CURVE_233: return NID_sect233r1; case B_CURVE_283: return NID_sect283r1; case B_CURVE_409: return NID_sect409r1; case B_CURVE_571: return NID_sect571r1; case P_CURVE_SM2: return NID_sm2; case 0: return 0; } return -1; } static const int KDF1_SHA1_len = 20; #ifndef QAT_OPENSSL_PROVIDER static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) { if (*outlen < SHA_DIGEST_LENGTH) return NULL; else *outlen = SHA_DIGEST_LENGTH; return SHA1(in, inlen, out); } #endif /****************************************************************************** * function: * test_ecdh_curve (ENGINE *e, * int nid, * const char *text, * BN_CTX *ctx, * int count, * int print_output, * int verify, * BIO *out, * int kdf) * * @param e [IN] - engine identifier * @param nid [IN] - curve object identifier * @param text [IN] - curve names * @param ctx [IN] - BN context * @param count [IN] - number of iterations * @param print_output [IN] - print hex output flag * @param verify [IN] - verify flag * @param out [IN] - for printf debug messages * @param kdf [IN] - to enable or disable KDF * @param ecdh_negative_testcount [IN] - number of negative test iterations * * description: * perform ECDH compute key * ******************************************************************************/ static int test_ecdh_curve(ENGINE * e, int nid, const char *text, BN_CTX *ctx, int count, int print_output, int verify, BIO *out, int kdf, int ecdh_negative_testcount) { EC_KEY *a = NULL; EC_KEY *b = NULL; BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; char buf[12]; unsigned char *abuf = NULL, *bbuf = NULL; int i, ret = 0; #ifndef QAT_OPENSSL_PROVIDER int aout = 0, bout; #endif #ifdef QAT_OPENSSL_PROVIDER EVP_PKEY_CTX *key_ctx = NULL; EVP_PKEY_CTX *test_ctx = NULL; EVP_PKEY *key1 = NULL; EVP_PKEY *key2 = NULL; size_t outlen = 0; size_t test_outlen = 0; unsigned char *secret_a = OPENSSL_malloc(MAX_ECDH_SIZE); unsigned char *secret_b = OPENSSL_malloc(MAX_ECDH_SIZE) ; int ecdh_checks = 1; #endif #ifndef QAT_OPENSSL_PROVIDER size_t alen = 0, blen = 0; const EC_GROUP *group; a = EC_KEY_new_by_curve_name(nid); b = EC_KEY_new_by_curve_name(nid); if (a == NULL || b == NULL) { WARN("# FAIL ECDH - Initial mallocs failed\n"); ret = -1; goto err; } group = EC_KEY_get0_group(a); if ((x_a=BN_new()) == NULL) { WARN("# FAIL ECDH - Initial mallocs failed\n"); ret = -1; goto err; } if ((y_a=BN_new()) == NULL) { WARN("# FAIL ECDH - Initial mallocs failed\n"); ret = -1; goto err; } if ((x_b=BN_new()) == NULL) { WARN("# FAIL ECDH - Initial mallocs failed\n"); ret = -1; goto err; } if ((y_b=BN_new()) == NULL) { WARN("# FAIL ECDH - Initial mallocs failed\n"); ret = -1; goto err; } if (print_output) { BIO_puts(out,"\nTesting key generation with "); BIO_puts(out,text); BIO_puts(out,"\n"); } if (EC_KEY_generate_key(a) <= 0) { WARN("# FAIL ECDH - EC_KEY_generate_key failed\n"); ret = -1; goto err; } if (!EC_POINT_get_affine_coordinates( group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) { WARN("# FAIL ECDH - EC_POINT_get_affine_coordinates failed\n"); ret = -1; goto err; } if (EC_KEY_generate_key(b) <= 0) { WARN("# FAIL ECDH - EC_KEY_generate_key failed\n"); ret = -1; goto err; } if (!EC_POINT_get_affine_coordinates( group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) { WARN("# FAIL ECDH - EC_POINT_get_affine_coordinates failed\n"); ret = -1; goto err; } alen = KDF1_SHA1_len; abuf = (unsigned char *)OPENSSL_malloc(alen); for (i = 0; i < count; i++) { if(ecdh_negative_testcount > 0) { /* * Negative Scenario1: Change the public key of 'b' with public key * of 'a' */ if (ecdh_negative_testcount == 1) { aout = ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(a), a, (kdf) ? KDF1_SHA1 : NULL); if (print_output) BIO_puts(out, "Negative tests 1 :Changed the public key of 'b' with public key of 'a'\n"); if (aout <= 0) { WARN("# FAIL ECDH - ECDH_compute_key failed \n"); ret = -1; goto err; } } else { /* Negative Scenario2 : Invalid Length */ alen = 10; /* Invalid Length */ if (print_output) BIO_puts(out,"Negative tests 2: Invalid Length \n"); aout = ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, (kdf) ? KDF1_SHA1 : NULL); if (aout <= 0) { WARN("# FAIL ECDH - ECDH_compute_key failed \n"); ret = -1; goto err; } } } else { /* Positive scenario */ if (print_output) BIO_puts(out,"Positive test \n"); aout = ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, (kdf) ? KDF1_SHA1 : NULL); if (aout <= 0) { WARN("# FAIL ECDH - ECDH_compute_key failed \n"); ret = -1; goto err; } } if (print_output) { BIO_puts(out," key1 ="); for (i = 0; i < aout; i++) { sprintf(buf,"%02X",abuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); } } if (verify) { blen = KDF1_SHA1_len; bbuf = (unsigned char *)OPENSSL_malloc(blen); bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, (kdf) ? KDF1_SHA1 : NULL); if (bout <= 0) { WARN("# FAIL ECDH - ECDH_compute_key failed \n"); ret = -1; goto err; } if (print_output) { BIO_puts(out," key2 ="); for (i = 0; i < bout; i++) { sprintf(buf,"%02X",bbuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); } if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0)) { if (print_output) { BIO_printf(out, " failed\n\n"); BIO_printf(out, "key a:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(a)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_a); BIO_printf(out, ","); BN_print(out, y_a); BIO_printf(out, "\nkey b:\n"); BIO_printf(out, "private key: "); BN_print(out, EC_KEY_get0_private_key(b)); BIO_printf(out, "\n"); BIO_printf(out, "public key (x,y): "); BN_print(out, x_b); BIO_printf(out, ","); BN_print(out, y_b); BIO_printf(out, "\n"); BIO_printf(out, "generated key a: "); for (i=0; icount); /* * If temp_args->explicit_engine is not set then set the * engine to NULL to allow fallback to software if * that engine under test does not support this operation. * This relies on the engine we are testing being * set as the default engine. */ ENGINE *e = temp_args->explicit_engine ? temp_args->e : NULL; int print_output = temp_args->print_output; int verify = temp_args->verify; int curve = temp_args->curve; int kdf = temp_args->kdf; int enable_negative = temp_args->enable_negative; int ecdh_negative_testcount = 0; out = BIO_new(BIO_s_file()); if (out == NULL) { WARN("# FAIL: Unable to create BIO\n"); exit(1); } BIO_set_fp(out, stdout, BIO_NOCLOSE); if ((ctx = BN_CTX_new()) == NULL) { WARN("# FAIL ECDH - Initial malloc failed \n"); ret = 0; goto err; } if(enable_negative > 0) ecdh_negative_testcount = ECDH_NEGATIVE_TESTCOUNT; for (i = 0; i <= ecdh_negative_testcount; i++) { if (test_ecdh_curve(e, get_nid(curve), ecdh_curve_name(curve), ctx, count, print_output, verify, out, kdf, i) < 0) ret = 0; } err: if (ret != 1) ERR_print_errors_fp(stderr); if (ctx) BN_CTX_free(ctx); BIO_free(out); return ret; } /****************************************************************************** * function: * tests_run_ecdh (TEST_PARAMS *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ void tests_run_ecdh(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_ecdh(args); else start_async_job(args, run_ecdh); } qatengine-1.9.0/test/tests_ecdsa.c000066400000000000000000000234171500416242000171210ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" static const char rnd_seed[] = "string to make the random number generator think it has entropy"; static int get_nid(int type) { switch (type) { case P_CURVE_192: return NID_X9_62_prime192v1; case P_CURVE_224: return NID_secp224r1; case P_CURVE_256: return NID_X9_62_prime256v1; case P_CURVE_384: return NID_secp384r1; case P_CURVE_521: return NID_secp521r1; case K_CURVE_163: return NID_sect163k1; case K_CURVE_233: return NID_sect233k1; case K_CURVE_283: return NID_sect283k1; case K_CURVE_409: return NID_sect409k1; case K_CURVE_571: return NID_sect571k1; case B_CURVE_163: return NID_sect163r2; case B_CURVE_233: return NID_sect233r1; case B_CURVE_283: return NID_sect283r1; case B_CURVE_409: return NID_sect409r1; case B_CURVE_571: return NID_sect571r1; case 0: return 0; } return -1; } EVP_PKEY *get_ecdsa_key(const int nid) { EVP_PKEY *ec_key = NULL; EVP_PKEY_CTX *kctx = NULL; kctx = EVP_PKEY_CTX_new_id(nid, NULL); if(kctx == NULL) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *params = NULL; /* Create the context for parameter generation */ #ifdef QAT_OPENSSL_3 pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); #else pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); #endif if ((pctx == NULL) || EVP_PKEY_paramgen_init(pctx) <= 0 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { fprintf(stderr, "EC params init failure.\n"); EVP_PKEY_CTX_free(pctx); return NULL; } EVP_PKEY_CTX_free(pctx); /* Create the context for the key generation */ kctx = EVP_PKEY_CTX_new(params, NULL); EVP_PKEY_free(params); } if (kctx == NULL || EVP_PKEY_keygen_init(kctx) <= 0 || EVP_PKEY_keygen(kctx, &ec_key) <= 0) { fprintf(stderr, "# FAIL ECDH - EC keygen init failed\n"); ec_key = NULL; } EVP_PKEY_CTX_free(kctx); return ec_key; } /****************************************************************************** * function: * test_ecdsa (int count, * int size, * engine *e, * int print_output, * int verify, * int curveType, * int ne) * * @param count [IN] - number of iterations * @param size [IN] - the length of input message * @param e [IN] - OpenSSL engine pointer * @param print_output [IN] - print hex output flag * @param verify [IN] - verify flag * @param nid [IN] - nid to be used * @param curveName [IN] - curve name to be used * * description: * ECDSA Sign and Verify Test * ******************************************************************************/ static int test_ecdsa(int count, int size, ENGINE * e, int print_output, int verify, int curveType, int ne) { BIO *out = NULL; int ret = 0, status = 0; unsigned char digest[size], wrong_digest[size]; unsigned char *signature = NULL; size_t sig_len = size; EVP_PKEY *ecdsa_key = NULL; EVP_PKEY_CTX *ecdsa_sign_ctx = NULL; EVP_PKEY_CTX *ecdsa_verify_ctx = NULL; int nid = 0; const char *curveName = NULL; nid = get_nid(curveType); curveName = ecdh_curve_name(curveType); out = BIO_new(BIO_s_file()); if (out == NULL) { WARN("# FAIL: Unable to create BIO\n"); exit(1); } BIO_set_fp(out, stdout, BIO_NOCLOSE); ecdsa_key = get_ecdsa_key(nid); if (ecdsa_key == NULL) { WARN("# FAIL: ECDSA Key NULL\n"); ret = -1; goto builtin_err; } /* fill digest values with some random data */ if ((RAND_bytes(digest, size) <= 0) || (RAND_bytes(wrong_digest, size) <= 0)) { fprintf(stderr,"# FAIL: unable to get random data\n"); ret = -1; goto builtin_err; } if ((signature = OPENSSL_malloc(sig_len)) == NULL) { fprintf(stderr,"# FAIL: failed to malloc signature\n"); ret = -1; goto builtin_err; } ecdsa_sign_ctx = EVP_PKEY_CTX_new(ecdsa_key, NULL); if (ecdsa_sign_ctx == NULL || EVP_PKEY_sign_init(ecdsa_sign_ctx) <= 0) { fprintf(stderr, "ECDSA sign init Failed\n"); ret = -1; goto builtin_err; } status = EVP_PKEY_sign(ecdsa_sign_ctx, signature, &sig_len, digest, size); if (status <= 0) { fprintf(stderr, "ECDSA sign failed\n"); ret = -1; goto builtin_err; } ecdsa_verify_ctx = EVP_PKEY_CTX_new(ecdsa_key, NULL); if (ecdsa_verify_ctx == NULL || EVP_PKEY_verify_init(ecdsa_verify_ctx) <= 0) { fprintf(stderr, "ECDSA verify init failed\n"); ret = -1; goto builtin_err; } if (0 == ne) { status = EVP_PKEY_verify(ecdsa_verify_ctx, signature, sig_len, digest, size); if (status <= 0) { fprintf(stderr, "ECDSA_verify Failed\n"); ret = -1; goto builtin_err; } } /* Verify Signature with a wrong digest */ #if CPA_CY_API_VERSION_NUM_MAJOR < 3 if (1 == ne) { if (EVP_PKEY_verify(ecdsa_verify_ctx, signature, sig_len, wrong_digest, size) == -1) { fprintf(stderr, "FAIL: Verify for ECDSA\n"); ret = -1; goto builtin_err; } } #endif builtin_err: if (signature) OPENSSL_free(signature); if (ecdsa_sign_ctx) EVP_PKEY_CTX_free(ecdsa_sign_ctx); if (ecdsa_verify_ctx) EVP_PKEY_CTX_free(ecdsa_verify_ctx); if (ecdsa_key) EVP_PKEY_free(ecdsa_key); BIO_free(out); if (0 == ret) { INFO("# PASS ECDSA Sign/Verify for nid %s\n",curveName); } else { if (0 == ne) INFO("# FAIL ECDSA Sign/Verify for nid %s\n",curveName); else INFO("# Negative scenario: ECDSA verify Passed for nid %s\n",curveName); } return ret; } /****************************************************************************** * function: * tests_run_ecdsa (void *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ static int run_ecdsa(void *args) { int ret = 1; TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int count = *(temp_args->count); int size = temp_args->size; /* * If temp_args->explicit_engine is not set then set the * engine to NULL to allow fallback to software if * that engine under test does not support this operation. * This relies on the engine we are testing being * set as the default engine. */ ENGINE *e = temp_args->explicit_engine ? temp_args->e : NULL; int print = temp_args->print_output; int verify = temp_args->verify; int curve = temp_args->curve; int ne = 0; #if CPA_CY_API_VERSION_NUM_MAJOR < 3 ne = temp_args->enable_negative; #endif RAND_seed(rnd_seed, sizeof(rnd_seed)); if (test_ecdsa(count, size, e, print, verify, curve, ne) < 0) ret = 0; return ret; } /****************************************************************************** * function: * tests_run_ecdsa(TEST_PARAMS *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ void tests_run_ecdsa(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_ecdsa(args); else start_async_job(args, run_ecdsa); } qatengine-1.9.0/test/tests_ecx.c000066400000000000000000000237671500416242000166310ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define NUM_OF_ECX_OPERATIONS 2 #define MAX_ECX_SIZE 128 /****************************************************************************** * function: * test_ecx_curve (int nid, * const char *text, * int count, * int print_output, * int verify, * BIO *out) * * @param nid [IN] - curve object identifier * @param text [IN] - curve names * @param count [IN] - number of iterations * @param print_output [IN] - print hex output flag * @param verify [IN] - verify flag * @param out [IN] - for printf debug messages * * description: * perform ECX generate key & derive key. * ******************************************************************************/ static int test_ecx_curve(int nid, const char *text, int count, int print_output, int verify, BIO *out) { EVP_PKEY_CTX *kctx = NULL; EVP_PKEY_CTX *ctx = NULL; EVP_PKEY_CTX *comparison_ctx = NULL; EVP_PKEY *key_A = NULL; EVP_PKEY *key_B = NULL; size_t outlen = 0; size_t comparison_outlen = 0; unsigned char *outbuf = NULL, *comparison_outbuf = NULL; char buf[12]; int i = 0, ret = 0; kctx = EVP_PKEY_CTX_new_id(nid, NULL); /* keygen ctx from NID */ if (kctx == NULL) { WARN("# FAIL ECX - Initial mallocs failed\n"); ret = -1; goto err; } if (print_output) { BIO_puts(out, "\nTesting ECX key generation with "); BIO_puts(out, text); BIO_puts(out, "\n"); } #ifdef QAT_OPENSSL_PROVIDER if ((key_A = EVP_PKEY_new()) <= 0 || (key_B = EVP_PKEY_new()) <= 0) { fprintf(stderr, "EVP_PKEY_new failed. \n"); ret = -1; goto err; } #endif if (EVP_PKEY_keygen_init(kctx) <= 0) { WARN("# FAIL ECX - keygen_init failed\n"); ret = -1; goto err; } if (EVP_PKEY_keygen(kctx, &key_A) <= 0) { WARN("# FAIL ECX - keygen key_A failed\n"); ret = -1; goto err; } if (EVP_PKEY_keygen(kctx, &key_B) <= 0) { WARN("# FAIL ECX - keygen key_B failed\n"); ret = -1; goto err; } for (i = 0; i < count; i++) { /* Positive scenario */ if (print_output) BIO_puts(out,"Positive test \n"); if ((ctx = EVP_PKEY_CTX_new(key_A, NULL)) == NULL || EVP_PKEY_derive_init(ctx) <= 0 || EVP_PKEY_derive_set_peer(ctx, key_B) <= 0 || EVP_PKEY_derive(ctx, NULL, &outlen) <= 0 || /* determine max length */ outlen == 0 || outlen > MAX_ECX_SIZE) { WARN("# FAIL ECX - ECX derive failed.\n"); ret = -1; goto err; } outbuf = (unsigned char *)OPENSSL_zalloc(MAX_ECX_SIZE); if (outbuf == NULL) { WARN("#FAIL ECX - memory allocation failed.\n"); ret = -1; goto err; } /* * Here we multiply the private key of key_A with the public key of * key_B, the peerkey. */ if ((EVP_PKEY_derive(ctx, outbuf, &outlen)) <= 0) { WARN("# FAIL ECX - ECX derive failed.\n"); ret = -1; goto err; } if (print_output) { BIO_puts(out," derived key = "); for (i = 0; i < outlen; i++) { sprintf(buf, "%02X ", outbuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); } if (verify) { if ((comparison_ctx = EVP_PKEY_CTX_new(key_B, NULL)) == NULL || EVP_PKEY_derive_init(comparison_ctx) <= 0 || EVP_PKEY_derive_set_peer(comparison_ctx, key_A) <= 0 || EVP_PKEY_derive(comparison_ctx, NULL, &comparison_outlen) <= 0 || /* determine max length */ comparison_outlen == 0 || comparison_outlen > MAX_ECX_SIZE) { WARN("# FAIL ECX - ECX derive failed.\n"); ret = -1; goto err; } comparison_outbuf = (unsigned char *)OPENSSL_zalloc(MAX_ECX_SIZE); if (comparison_outbuf == NULL) { WARN("#FAIL ECX - memory allocation failed.\n"); ret = -1; goto err; } /* * Here we multiply the private key of key_B with the public key of * key_A, the peerkey. */ if ((EVP_PKEY_derive(comparison_ctx, comparison_outbuf, &comparison_outlen)) <= 0) { WARN("# FAIL ECX - ECX derive failed.\n"); ret = -1; goto err; } if (print_output) { BIO_puts(out," comparison derived key = "); for (i = 0; i < comparison_outlen; i++) { sprintf(buf, "%02X ", comparison_outbuf[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); } if ((comparison_outlen != outlen) || (memcmp(outbuf, comparison_outbuf, outlen) != 0)) { WARN("#FAIL ECX - buffer comparison failed.\n"); ret = -1; } } if (ctx != NULL) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } if (comparison_ctx != NULL) { EVP_PKEY_CTX_free(comparison_ctx); comparison_ctx = NULL; } if (outbuf != NULL) { OPENSSL_free(outbuf); outbuf = NULL; } if (comparison_outbuf != NULL) { OPENSSL_free(comparison_outbuf); comparison_outbuf = NULL; } } if (ret == 0) INFO("# PASS verify for ECDH%s.\n", text); else INFO("# FAIL verify for ECDH%s.\n", text); err: if (ret != 0) ERR_print_errors_fp(stderr); EVP_PKEY_free(key_A); EVP_PKEY_free(key_B); if (kctx != NULL) { EVP_PKEY_CTX_free(kctx); kctx = NULL; } if (ctx != NULL) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } if (comparison_ctx != NULL) { EVP_PKEY_CTX_free(comparison_ctx); comparison_ctx = NULL; } if (outbuf != NULL) { OPENSSL_free(outbuf); outbuf = NULL; } if (comparison_outbuf != NULL) { OPENSSL_free(comparison_outbuf); comparison_outbuf = NULL; } return ret; } /****************************************************************************** * function: * run_ecx (void *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ static int run_ecx(void *args) { TEST_PARAMS *local_args = (TEST_PARAMS *)args; int count = *(local_args->count); int print_output = local_args->print_output; int verify = local_args->verify; BIO *out = NULL; int ret = 1; out = BIO_new(BIO_s_file()); if (out == NULL) { WARN("# FAIL: Unable to create BIO\n"); exit(1); } BIO_set_fp(out, stdout, BIO_NOCLOSE); if (local_args->curve == X_CURVE_448) ret = test_ecx_curve(EVP_PKEY_X448, "X448", count, print_output, verify, out); else ret = test_ecx_curve(EVP_PKEY_X25519, "X25519", count, print_output, verify, out); if (ret < 0) ERR_print_errors_fp(stderr); else ret = 1; BIO_free(out); return ret; } /****************************************************************************** * function: * tests_run_ecx (TEST_PARAMS *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ void tests_run_ecx(TEST_PARAMS *args) { if (!args->enable_async) run_ecx(args); else start_async_job(args, run_ecx); } qatengine-1.9.0/test/tests_hkdf.c000066400000000000000000000417421500416242000167570ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ # include # include # include # include # include # include # include #ifdef QAT_OPENSSL_3 # include #endif # include "tests.h" # include "../qat_utils.h" # define OUTPUT_LEN 32 # define SEED_LEN 13 # define SECRET_LEN 22 # define INFO_LEN 10 # define HASH_SIZE_SHA256 32 # define HASH_SIZE_SHA384 48 /* HKDF data */ static const unsigned char hkdf_salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c }; static const unsigned char hkdf_secret[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; unsigned char info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; static const unsigned char hkdf_expand_sha256[] = { 0x3C, 0xB2, 0x5F, 0x25, 0xFA, 0xAC, 0xD5, 0x7A, 0x90, 0x43, 0x4F, 0x64, 0xD0, 0x36, 0x2F, 0x2A, 0x2D, 0x2D, 0x0A, 0x90, 0xCF, 0x1A, 0x5A, 0x4C, 0x5D, 0xB0, 0x2D, 0x56, 0xEC, 0xC4, 0xC5, 0xBF, }; static const unsigned char hkdf_expand_sha384[] = { 0x9B, 0x50, 0x97, 0xA8, 0x60, 0x38, 0xB8, 0x05, 0x30, 0x90, 0x76, 0xA4, 0x4B, 0x3A, 0x9F, 0x38, 0x06, 0x3E, 0x25, 0xB5, 0x16, 0xDC, 0xBF, 0x36, 0x9F, 0x39, 0x4C, 0xFA, 0xB4, 0x36, 0x85, 0xF7, }; static const unsigned char hkdf_extract_sha256[] = { 0x07, 0x77, 0x09, 0x36, 0x2C, 0x2E, 0x32, 0xDF, 0x0D, 0xDC, 0x3F, 0x0D, 0xC4, 0x7B, 0xBA, 0x63, 0x90, 0xB6, 0xC7, 0x3B, 0xB5, 0x0F, 0x9C, 0x31, 0x22, 0xEC, 0x84, 0x4A, 0xD7, 0xC2, 0xB3, 0xE5 }; static const unsigned char hkdf_extract_sha384[] = { 0x70, 0x4B, 0x39, 0x99, 0x07, 0x79, 0xCE, 0x1D, 0xC5, 0x48, 0x05, 0x2C, 0x7D, 0xC3, 0x9F, 0x30, 0x35, 0x70, 0xDD, 0x13, 0xFB, 0x39, 0xF7, 0xAC, 0xC5, 0x64, 0x68, 0x0B, 0xEF, 0x80, 0xE8, 0xDE, 0xC7, 0x0E, 0xE9, 0xA7, 0xE1, 0xF3, 0xE2, 0x93, 0xEF, 0x68, 0xEC, 0xEB, 0x07, 0x2A, 0x5A, 0xDE }; #ifdef QAT_OPENSSL_3 /* TLS13_KDF data */ static const unsigned char tls13_kdf_key[] = { 0xF8, 0xAF, 0x6A, 0xEA, 0x2D, 0x39, 0x7B, 0xAF, 0x29, 0x48, 0xA2, 0x5B, 0x28, 0x34, 0x20, 0x06, 0x92, 0xCF, 0xF1, 0x7E, 0xEE, 0x91, 0x65, 0xE4, 0xE2, 0x7B, 0xAB, 0xEE, 0x9E, 0xDE, 0xFD, 0x05 }; static const unsigned char tls13_kdf_extract_out[] = { 0x15, 0x3B, 0x63, 0x94, 0xA9, 0xC0, 0x3C, 0xF3, 0xF5, 0xAC, 0xCC, 0x6E, 0x45, 0x5A, 0x76, 0x93, 0x28, 0x11, 0x38, 0xA1, 0xBC, 0xFA, 0x38, 0x03, 0xC2, 0x67, 0x35, 0xDD, 0x11, 0x94, 0xD2, 0x16 }; static const unsigned char tls13_kdf_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20 /* "tls13 " */ }; /* client_hello_hash tls13_kdf_data*/ static const unsigned char tls13_kdf_data[] = { 0x7c, 0x92, 0xf6, 0x8b, 0xd5, 0xbf, 0x36, 0x38, 0xea, 0x33, 0x8a, 0x64, 0x94, 0x72, 0x2e, 0x1b, 0x44, 0x12, 0x7e, 0x1b, 0x7e, 0x8a, 0xad, 0x53, 0x5f, 0x23, 0x22, 0xa6, 0x44, 0xff, 0x22, 0xb3 }; static const unsigned char tls13_kdf_label[] = { 0x63, 0x20, 0x65, 0x20, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63 /* "c e traffic" */ }; /* tls13_kdf_client_early_traffic_secret */ static const unsigned char tls13_kdf_expand_secret[] = { 0xC8, 0x05, 0x83, 0xA9, 0x0E, 0x99, 0x5C, 0x48, 0x96, 0x00, 0x49, 0x2A, 0x5D, 0xA6, 0x42, 0xE6, 0xB1, 0xF6, 0x79, 0xBA, 0x67, 0x48, 0x28, 0x79, 0x2D, 0xF0, 0x87, 0xB9, 0x39, 0x63, 0x61, 0x71 }; static int qat_extract_expand(const EVP_MD *md, int mode, unsigned char *key, size_t key_len, unsigned char *out, size_t out_len) { EVP_KDF *kdf; EVP_KDF_CTX *kctx; int ret = 0; OSSL_PARAM params[8], *p = params; kdf = EVP_KDF_fetch(NULL, "TLS13-KDF", NULL); kctx = EVP_KDF_CTX_new(kdf); if (kctx == NULL) return 0; EVP_KDF_free(kdf); size_t mdlen = (size_t)EVP_MD_get_size(md); const char *mdname = EVP_MD_get0_name(md); if (mode == EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) { *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (unsigned char *)key, key_len); *p++ = OSSL_PARAM_construct_end(); ret = EVP_KDF_derive(kctx, out, mdlen, params); if (ret != 0) EVP_KDF_CTX_free(kctx); } if (mode == EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) { *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (unsigned char *)key, key_len); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA, (unsigned char *) tls13_kdf_data, (size_t) sizeof(tls13_kdf_data)); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, (unsigned char *) tls13_kdf_prefix, (size_t) sizeof(tls13_kdf_prefix)); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL, (unsigned char *) tls13_kdf_label, (size_t) sizeof(tls13_kdf_label)); *p++ = OSSL_PARAM_construct_end(); ret = EVP_KDF_derive(kctx, out, mdlen, params); if (ret != 0) EVP_KDF_CTX_free(kctx); } return ret; } static int runTls13KdfOps(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int print_output = temp_args->print_output; char *digest_kdf = temp_args->digest_kdf; const EVP_MD *md = NULL; size_t mdlen; int res = 0; if (!strcmp(digest_kdf, "SHA256")) md = EVP_sha256(); else if (!strcmp(digest_kdf, "SHA384")) md = EVP_sha384(); else { WARN("# FAIL: message digest is not supported!!\n"); return res; } mdlen = (size_t)EVP_MD_get_size(md); /*extract output will store in tls13_kdf_early_secret */ unsigned char *tls13_kdf_early_secret = OPENSSL_zalloc(mdlen); /*expand output will store in tls13_kdf_master_secret */ unsigned char *tls13_kdf_master_secret = OPENSSL_zalloc(mdlen); res = qat_extract_expand(md, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY, (unsigned char *)tls13_kdf_key, (size_t)sizeof(tls13_kdf_key), tls13_kdf_early_secret, mdlen); if (!memcmp(tls13_kdf_early_secret, tls13_kdf_extract_out, mdlen)) { res = qat_extract_expand(md, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY, tls13_kdf_early_secret, mdlen, tls13_kdf_master_secret, mdlen); } if (memcmp(tls13_kdf_master_secret, tls13_kdf_expand_secret, sizeof(tls13_kdf_expand_secret))) { INFO("# FAIL verify for TLS13-KDF extract & expand.\n"); tests_hexdump("TLS13-KDF expand actual :", tls13_kdf_master_secret, mdlen); tests_hexdump("TLS13-KDF expand expected:", tls13_kdf_expand_secret, sizeof(tls13_kdf_expand_secret)); res = 0; } else { INFO("# PASS verify for TLS13-KDF extract & expand.\n"); } if (print_output) { tests_hexdump("TLS13-KDF extract key:", tls13_kdf_early_secret, mdlen); tests_hexdump("TLS13-KDF expand key:", tls13_kdf_master_secret, mdlen); } if (tls13_kdf_master_secret) { OPENSSL_free(tls13_kdf_master_secret); tls13_kdf_master_secret = NULL; } if (tls13_kdf_early_secret) { OPENSSL_free(tls13_kdf_early_secret); tls13_kdf_early_secret = NULL; } return res; } #endif static void populate_HKDF(char *digest_kdf, int operation, unsigned char **salt, int *salt_len, unsigned char **secret, int *secret_len, unsigned char **expectedMasterSecret, size_t *masterSecretSize) { *salt = (unsigned char *)&hkdf_salt; *secret = (unsigned char *)&hkdf_secret; *secret_len = SECRET_LEN; *salt_len = SEED_LEN; *masterSecretSize = OUTPUT_LEN; switch (operation) { case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: WARN("# HKDF mode EXTRACT_AND_EXPAND.\n"); if (!strcmp(digest_kdf, "SHA256")) *expectedMasterSecret = (unsigned char *)hkdf_expand_sha256; else if (!strcmp(digest_kdf, "SHA384")) *expectedMasterSecret = (unsigned char *)hkdf_expand_sha384; break; case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: WARN("# HKDF mode EXTRACT.\n"); if (!strcmp(digest_kdf, "SHA256")) { *expectedMasterSecret = (unsigned char *)hkdf_extract_sha256; *masterSecretSize = HASH_SIZE_SHA256; } else if (!strcmp(digest_kdf, "SHA384")) { *expectedMasterSecret = (unsigned char *)hkdf_extract_sha384; *masterSecretSize = HASH_SIZE_SHA384; } break; case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: WARN("# HKDF mode EXPAND.\n"); if (!strcmp(digest_kdf, "SHA256")) { *secret = (unsigned char *)&hkdf_extract_sha256; *expectedMasterSecret = (unsigned char *)hkdf_expand_sha256; *secret_len = HASH_SIZE_SHA256; } else if (!strcmp(digest_kdf, "SHA384")) { *secret = (unsigned char *)&hkdf_extract_sha384; *expectedMasterSecret = (unsigned char *)hkdf_expand_sha384; *secret_len = HASH_SIZE_SHA384; } break; } } static int qat_HKDF(const EVP_MD *md, int mode, unsigned char *salt, int *salt_len, unsigned char *secret, int *secret_len, unsigned char *out, size_t out_len) { EVP_PKEY_CTX *pctx = NULL; int ret = 0; pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0) goto err; if (EVP_PKEY_CTX_hkdf_mode(pctx, mode) <= 0) goto err; if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) goto err; if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, *salt_len) <= 0) goto err; if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, *secret_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info, INFO_LEN) <= 0) goto err; if (EVP_PKEY_derive(pctx, out, &out_len) <= 0) goto err; ret = 1; err: if (ret == 0) WARN("# FAIL: performing qat_HKDF operations\n"); EVP_PKEY_CTX_free(pctx); return ret; } static int runHkdfOps(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int operation = temp_args->hkdf_op; int print_output = temp_args->print_output; int verify = temp_args->verify; char *digest_kdf = temp_args->digest_kdf; const EVP_MD *md = NULL; unsigned char *salt = NULL; unsigned char *secret = NULL, *expectedMasterSecret = NULL; unsigned char *masterSecret = NULL; int res = 0; size_t masterSecretSize = OUTPUT_LEN; int salt_len = 0, secret_len = 0; int count = 0; if (!strcmp(digest_kdf, "SHA256")) md = EVP_sha256(); else if (!strcmp(digest_kdf, "SHA384")) md = EVP_sha384(); else { WARN("# FAIL: message digest is not supported!!\n"); return res; } for (count = 0; count < *(temp_args->count); count++) { masterSecret = OPENSSL_zalloc(sizeof(hkdf_extract_sha384)); populate_HKDF(digest_kdf, operation, &salt, &salt_len, &secret, &secret_len, &expectedMasterSecret, &masterSecretSize); res = qat_HKDF(md, operation, salt, &salt_len, secret, &secret_len, masterSecret, masterSecretSize); if ((verify && count == 0) || res == 0) { if (memcmp(masterSecret, expectedMasterSecret, masterSecretSize)) { INFO("# FAIL verify for HKDF mode.\n"); tests_hexdump("HKDF actual :", masterSecret, masterSecretSize); tests_hexdump("HKDF expected:", expectedMasterSecret, masterSecretSize); res = 0; } else { switch(operation) { case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: INFO("# PASS verify for HKDF extract & expand.\n"); break; case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: INFO("# PASS verify for HKDF extract.\n"); break; case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: INFO("# PASS verify for HKDF expand.\n"); break; } } if (print_output) tests_hexdump("HKDF master secret:", masterSecret, masterSecretSize); } if (masterSecret) { OPENSSL_free(masterSecret); masterSecret = NULL; } } return res; } /****************************************************************************** * function: * tests_run_hkdf (TEST_PARAMS *args) * * * @param args [IN] - the test parameters * * Description: * This is a function to test the HKDF (Hash-based Key Derivation Function). ******************************************************************************/ void tests_run_hkdf(TEST_PARAMS *args) { int op = 0; if (args->performance || args->hkdf_op != -1) { /* Operation if not specified for performance tests */ if (args->hkdf_op == -1) args->hkdf_op = 0; if (!args->enable_async) { runHkdfOps(args); #ifdef QAT_OPENSSL_3 if (args->hkdf_op != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) runTls13KdfOps(args); #endif } else { start_async_job(args, runHkdfOps); #ifdef QAT_OPENSSL_3 if (args->hkdf_op != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) start_async_job(args, runTls13KdfOps); #endif } return; } if (!args->enable_async) { for (op = 0; op <= EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; op++) { args->hkdf_op = op; runHkdfOps(args); } #ifdef QAT_OPENSSL_3 if (args->hkdf_op != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) runTls13KdfOps(args); #endif } else { for (op = 0; op <= EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; op++) { args->hkdf_op = op; start_async_job(args, runHkdfOps); } #ifdef QAT_OPENSSL_3 if (args->hkdf_op != EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) start_async_job(args, runTls13KdfOps); #endif } } qatengine-1.9.0/test/tests_prf.c000066400000000000000000000731601500416242000166310ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define MD_SERVER_FINISHED_SEED2_LEN 32 #define MD_SERVER_FINISHED_SEC_LEN 48 #define MD_SERVER_FINISHED_BUFF_SIZE 12 #define MD_SERVER_FINISHED_MASTER_SEC_LEN 12 #define MD_CLIENT_FINISHED_SEED2_LEN 32 #define MD_CLIENT_FINISHED_SEC_LEN 48 #define MD_CLIENT_FINISHED_BUFF_SIZE 12 #define MD_CLIENT_FINISHED_MASTER_SEC_LEN 12 #define MD_KEY_EXPANSION_SEED2_LEN 32 #define MD_KEY_EXPANSION_SEED3_LEN 32 #define MD_KEY_EXPANSION_SEC_LEN 48 #define MD_KEY_EXPANSION_BUFF_SIZE 104 #define MD_KEY_EXPANSION_MASTER_SEC_LEN 104 #define MASTER_SECRET_SEED2_LEN 32 #define MASTER_SECRET_SEED4_LEN 32 #define MASTER_SECRET_SEC_LEN 48 #define EXTENDED_MASTER_SECRET_SEED2_LEN 32 #define EXTENDED_MASTER_SECRET_SEC_LEN 48 static const unsigned char prf_sf_lseed2[] = { 0xD8, 0xDD, 0x4A, 0xC2, 0x78, 0xD2, 0x2C, 0xE6, 0x22, 0x9C, 0x18, 0x2C, 0x88, 0x1B, 0x4D, 0x7F, 0xC7, 0xC0, 0x71, 0x46, 0x8C, 0xE8, 0x86, 0x5B, 0x87, 0x5A, 0x31, 0x2E, 0x53, 0x33, 0xE1, 0x39 }; static const unsigned char prf_sf_lsec[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_sf_resMasSec_TLS1_2_SHA256[] = { 0x68, 0xCA, 0xCC, 0xAF, 0x1A, 0x9F, 0xAE, 0xE4, 0xFC, 0x23, 0xD5, 0xC6 }; static const unsigned char prf_sf_resMasSec_TLS1_2_SHA384[] = { 0xD3, 0xF1, 0xF1, 0x54, 0x13, 0x84, 0xD5, 0x48, 0x85, 0xDD, 0xEC, 0xD0 }; static const unsigned char prf_sf_resMasSec_TLS1_2_SHA512[] = { 0x3D, 0xFB, 0x40, 0x47, 0x89, 0x66, 0x7C, 0xDE, 0xFB, 0xDD, 0x59, 0x52 }; static const unsigned char prf_sf_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0x1D, 0xFA, 0xC3, 0xDE, 0xAE, 0x74, 0x2B, 0xE1, 0x87, 0xC0, 0x0B, 0x9B }; static const unsigned char prf_cf_lseed2[] = { 0xC2, 0xFA, 0x5E, 0xE1, 0x95, 0xCF, 0x3C, 0xF8, 0x09, 0xC8, 0x37, 0xC5, 0x80, 0x41, 0xFA, 0xC2, 0xE3, 0x7C, 0x2F, 0xCC, 0xA7, 0x50, 0x82, 0x6C, 0x9E, 0x5D, 0x87, 0x5F, 0x46, 0xD4, 0xF7, 0x02 }; static const unsigned char prf_cf_lsec[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_cf_resMasSec_TLS1_2_SHA256[] = { 0xC9, 0x86, 0xD8, 0xFE, 0x8D, 0x26, 0xCB, 0x11, 0xC8, 0xB3, 0xF6, 0xD3 }; static const unsigned char prf_cf_resMasSec_TLS1_2_SHA384[] = { 0x62, 0x8C, 0x23, 0xB7, 0x10, 0x0D, 0x85, 0x08, 0x35, 0x74, 0x14, 0x73 }; static const unsigned char prf_cf_resMasSec_TLS1_2_SHA512[] = { 0x9A, 0xEF, 0x80, 0x3C, 0xEE, 0x32, 0xBC, 0xBC, 0x1A, 0xC0, 0xA7, 0xDD }; static const unsigned char prf_cf_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0x67, 0x18, 0x75, 0xEF, 0xBE, 0x50, 0xAD, 0xD5, 0x94, 0x78, 0x53, 0x85 }; static const unsigned char prf_ke_lseed2[] = { 0xEF, 0x14, 0xF7, 0x48, 0x0C, 0x36, 0xB2, 0xF3, 0xFB, 0x4F, 0x9F, 0xBF, 0xBA, 0x6C, 0x6F, 0x0A, 0x27, 0xAB, 0xF8, 0x16, 0xFF, 0x37, 0xE9, 0x88, 0x0D, 0x8A, 0x3B, 0x59, 0x57, 0xA6, 0xC1, 0x7E }; static const unsigned char prf_ke_lseed3[] = { 0x88, 0x3E, 0x61, 0xAE, 0xE3, 0xB6, 0xD8, 0x62, 0x18, 0x86, 0x4A, 0x7D, 0x4B, 0x0A, 0xA5, 0xF9, 0xE7, 0xE7, 0xAA, 0xD5, 0x8B, 0xB1, 0xBD, 0x54, 0x1F, 0xF2, 0x47, 0xCC, 0xDA, 0xA8, 0x3F, 0x2D }; static const unsigned char prf_ke_lsec[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_ke_resMasSec_TLS1_2_SHA256[] = { 0x5E, 0xD9, 0x1F, 0x2F, 0x5C, 0x3A, 0x78, 0x82, 0x7C, 0xC3, 0xEA, 0x22, 0x47, 0x5F, 0x24, 0xD6, 0xEA, 0x8B, 0xCC, 0x40, 0xF5, 0xAD, 0xC1, 0x39, 0xBE, 0x15, 0x87, 0x85, 0x3A, 0x4C, 0x63, 0xA6, 0xBD, 0x5C, 0x58, 0x5D, 0xD8, 0xD9, 0x1F, 0x1D, 0xE1, 0x60, 0xD2, 0x2E, 0x59, 0x31, 0x0E, 0xFC, 0xB7, 0xFB, 0x0D, 0x9A, 0x4E, 0xF8, 0x8D, 0x72, 0x35, 0x6D, 0x8C, 0xEC, 0x99, 0x6F, 0x08, 0x41, 0xB3, 0xB5, 0xDA, 0xB6, 0x7F, 0x97, 0xF0, 0xFF, 0xAF, 0xF4, 0x05, 0x26, 0xC2, 0x05, 0x3D, 0x60, 0x18, 0xAD, 0x01, 0x59, 0xE6, 0x16, 0x06, 0x0C, 0x90, 0x81, 0x8D, 0x23, 0x08, 0x90, 0x57, 0x73, 0x56, 0xAE, 0xD6, 0x7F, 0x64, 0x2B, 0x29, 0x72 }; static const unsigned char prf_ke_resMasSec_TLS1_2_SHA384[] = { 0xB7, 0xC3, 0x82, 0xDE, 0x7C, 0x72, 0xA0, 0x3F, 0x4E, 0xF6, 0x4B, 0x3B, 0x92, 0x1A, 0xBA, 0x44, 0x58, 0x28, 0x3D, 0xA6, 0x2F, 0x02, 0x34, 0x2F, 0x0B, 0x75, 0x73, 0xB1, 0x69, 0x43, 0x40, 0xA5, 0x8A, 0x9B, 0xDC, 0x88, 0x06, 0x4E, 0x57, 0x62, 0xBC, 0x3A, 0xB6, 0x38, 0x30, 0x8A, 0x3E, 0x8C, 0x41, 0xA9, 0xF1, 0x54, 0xB9, 0xA5, 0x83, 0xDC, 0x3A, 0x3D, 0x52, 0x0C, 0xB9, 0x79, 0xC9, 0xAC, 0x10, 0xBD, 0x4F, 0x13, 0x8C, 0xBC, 0xA2, 0x99, 0x17, 0xBA, 0xA9, 0x0C, 0xF8, 0x20, 0x0C, 0x4F, 0x96, 0xA3, 0x39, 0x9B, 0x78, 0x8D, 0x1B, 0x21, 0x93, 0x14, 0x76, 0xBF, 0x7A, 0xA7, 0x80, 0x5E, 0xF3, 0x94, 0x56, 0xFB, 0x4B, 0x51, 0x01, 0x13 }; static const unsigned char prf_ke_resMasSec_TLS1_2_SHA512[] = { 0xBC, 0x50, 0xE2, 0x72, 0x61, 0xAC, 0x97, 0x4E, 0x89, 0x41, 0xAB, 0xBA, 0x39, 0xBD, 0xAC, 0x82, 0xCD, 0x7A, 0x8C, 0x4E, 0x2D, 0x22, 0xC5, 0x62, 0x3F, 0x2D, 0x4F, 0xB2, 0x55, 0x53, 0x7D, 0xC6, 0x58, 0xE2, 0xBF, 0x23, 0xF7, 0x03, 0x44, 0xF7, 0x1B, 0xE8, 0x13, 0x4A, 0xDC, 0x03, 0xFD, 0x49, 0x43, 0xB1, 0xB7, 0xAE, 0x60, 0x78, 0x41, 0x20, 0x27, 0x17, 0x0F, 0x18, 0x1F, 0xE4, 0x39, 0x49, 0x2E, 0xF9, 0x87, 0x2F, 0x3F, 0x45, 0xC1, 0x7D, 0x68, 0xC0, 0xCF, 0x4D, 0x6B, 0xA7, 0x55, 0x8D, 0xFF, 0x38, 0xE4, 0x22, 0x4F, 0x86, 0x86, 0xD1, 0x71, 0xA1, 0x51, 0x5B, 0x61, 0xA1, 0xFC, 0xB0, 0xEE, 0x5C, 0x07, 0x17, 0xA0, 0x90, 0x9F, 0x50 }; static const unsigned char prf_ke_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0x6C, 0x73, 0xAE, 0xFE, 0xB0, 0xBC, 0x7A, 0x0C, 0xF6, 0xBB, 0x28, 0xE7, 0x19, 0x01, 0x5C, 0x95, 0x4D, 0x46, 0xDA, 0xC2, 0xC6, 0xCD, 0x10, 0xE8, 0xF5, 0x19, 0xE9, 0x7A, 0xED, 0x75, 0x7F, 0xAC, 0x7F, 0x16, 0xAB, 0x42, 0x98, 0x52, 0x0D, 0x1C, 0xED, 0x73, 0x23, 0x57, 0x19, 0x45, 0x26, 0x51, 0xD2, 0xA1, 0xF2, 0xA1, 0x3D, 0xA9, 0x59, 0xBB, 0xD8, 0x63, 0x26, 0xFD, 0xCF, 0x95, 0x67, 0x71, 0x4A, 0xF0, 0xBB, 0xA1, 0xE4, 0xAE, 0xE1, 0x8C, 0xAE, 0xA7, 0xC3, 0xA6, 0xDE, 0xB1, 0x8C, 0x75, 0x12, 0x61, 0x27, 0xB0, 0x07, 0x78, 0x94, 0xF9, 0x8C, 0xDC, 0xF9, 0xE5, 0x1A, 0x3C, 0x90, 0x0B, 0xB5, 0x65, 0x17, 0x7E, 0xB9, 0x23, 0x71, 0x0C }; static const unsigned char prf_ms_lseed2[] = { 0x88, 0x3E, 0x61, 0xAE, 0xE3, 0xB6, 0xD8, 0x62, 0x18, 0x86, 0x4A, 0x7D, 0x4B, 0x0A, 0xA5, 0xF9, 0xE7, 0xE7, 0xAA, 0xD5, 0x8B, 0xB1, 0xBD, 0x54, 0x1F, 0xF2, 0x47, 0xCC, 0xDA, 0xA8, 0x3F, 0x2D }; static const unsigned char prf_ms_lseed4[] = { 0xEF, 0x14, 0xF7, 0x48, 0x0C, 0x36, 0xB2, 0xF3, 0xFB, 0x4F, 0x9F, 0xBF, 0xBA, 0x6C, 0x6F, 0x0A, 0x27, 0xAB, 0xF8, 0x16, 0xFF, 0x37, 0xE9, 0x88, 0x0D, 0x8A, 0x3B, 0x59, 0x57, 0xA6, 0xC1, 0x7E }; static const unsigned char prf_ms_lsec[] = { 0x03, 0x03, 0x0B, 0x03, 0x07, 0xEF, 0x7A, 0xDC, 0xFB, 0xD1, 0x86, 0xE3, 0x46, 0xC0, 0x45, 0x36, 0xA2, 0x73, 0x31, 0xE3, 0x7A, 0xC8, 0x45, 0x3A, 0xB9, 0x58, 0x0A, 0x4E, 0xA1, 0xC0, 0x73, 0x55, 0x57, 0x92, 0xA5, 0xCD, 0x1A, 0x76, 0xE8, 0xDD, 0xCF, 0xE3, 0x7A, 0x77, 0x48, 0xEE, 0x16, 0xAE }; static const unsigned char prf_ms_resMasSec_TLS1_2_SHA256[] = { 0x57, 0x0A, 0xD8, 0x78, 0x67, 0x2B, 0x0B, 0x11, 0xE1, 0x51, 0x51, 0x71, 0x3B, 0xAF, 0xB2, 0xFE, 0xE4, 0x33, 0x41, 0x67, 0x35, 0x3F, 0x20, 0xB1, 0x6F, 0x9B, 0xF8, 0x91, 0x2F, 0xD9, 0xF6, 0x3B, 0x32, 0x7A, 0xAD, 0x77, 0xBD, 0xC2, 0x35, 0x6D, 0x30, 0x53, 0x39, 0x53, 0xE0, 0x09, 0x7E, 0xE9 }; static const unsigned char prf_ms_resMasSec_TLS1_2_SHA384[] = { 0xD0, 0x90, 0xDE, 0x77, 0xDB, 0x2C, 0xBB, 0x24, 0x37, 0xEB, 0xB2, 0x9E, 0x65, 0xE4, 0xCB, 0xD0, 0x15, 0x60, 0x90, 0x61, 0x90, 0x82, 0x44, 0x86, 0x9B, 0x9C, 0x70, 0xB6, 0xBB, 0x17, 0x37, 0x6E, 0x55, 0xCD, 0x04, 0x61, 0x9F, 0xC1, 0x7A, 0x40, 0x32, 0x82, 0xCB, 0xC1, 0x70, 0xD5, 0xC4, 0xDA }; static const unsigned char prf_ms_resMasSec_TLS1_2_SHA512[] = { 0x36, 0x25, 0x70, 0x6A, 0x23, 0x20, 0x5D, 0x88, 0x3B, 0xAA, 0x7E, 0x7C, 0x72, 0xE1, 0x91, 0x9B, 0x6F, 0x91, 0x21, 0xAB, 0x51, 0x36, 0x12, 0xCB, 0x77, 0x10, 0x26, 0xBA, 0xC8, 0xC5, 0xAE, 0x8F, 0x05, 0x1C, 0x6D, 0xD0, 0x79, 0xED, 0x57, 0x0F, 0x4C, 0x0B, 0x79, 0xD3, 0x45, 0x22, 0x71, 0xCE }; static const unsigned char prf_ms_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0xB0, 0xCC, 0x9D, 0xAB, 0xA4, 0xA4, 0xF9, 0x9C, 0x0D, 0x17, 0x25, 0xF4, 0x82, 0xBB, 0x91, 0x20, 0x1F, 0xF8, 0xA3, 0x7A, 0x9A, 0x69, 0x00, 0x0B, 0x35, 0x4F, 0xE7, 0xA7, 0xBB, 0xBC, 0x96, 0x90, 0x83, 0x80, 0x42, 0xB5, 0x33, 0xE9, 0x60, 0x42, 0x9C, 0x4B, 0x8F, 0x7B, 0xA1, 0x2E, 0x4E, 0x19 }; static const unsigned char prf_ems_lseed2[] = { 0xFF, 0x77, 0x85, 0x63, 0xD4, 0x23, 0x6A, 0x57, 0xD4, 0x68, 0x83, 0x29, 0x6F, 0x86, 0x18, 0x6A, 0x4C, 0xF3, 0xC3, 0xF4, 0xC8, 0xDC, 0xDF, 0x97, 0x30, 0xD2, 0x2F, 0x9C, 0x5B, 0xA7, 0xD0, 0x5E }; static const unsigned char prf_ems_lsec[] = { 0x03, 0x03, 0xE3, 0x11, 0xC5, 0xED, 0xE6, 0x51, 0x41, 0xC3, 0x99, 0xC9, 0x87, 0x56, 0x8C, 0x46, 0xD0, 0x07, 0xA8, 0x3E, 0xE3, 0x7F, 0xBD, 0x60, 0x56, 0xA2, 0xD0, 0x61, 0x83, 0xFF, 0xA3, 0x0E, 0x21, 0x9A, 0x6C, 0x59, 0x79, 0x9D, 0x27, 0x23, 0xDD, 0xBC, 0x0C, 0x5D, 0xB9, 0x76, 0xA9, 0xC5 }; static const unsigned char prf_ems_resMasSec_TLS1_2_SHA256[] = { 0x44, 0x31, 0xBF, 0x20, 0xBF, 0xD7, 0xA8, 0x48, 0x0D, 0x6F, 0x4E, 0xE8, 0xC9, 0xF8, 0xC1, 0x6A, 0x65, 0xD1, 0x93, 0xE7, 0x54, 0x32, 0xA6, 0x10, 0x3F, 0x73, 0x4B, 0x32, 0x14, 0xE8, 0xE6, 0x33, 0x91, 0x84, 0x1F, 0x2F, 0xED, 0x71, 0xBC, 0x4C, 0x67, 0x11, 0x97, 0xCE, 0x0F, 0xB3, 0x5D, 0x0D }; static const unsigned char prf_ems_resMasSec_TLS1_2_SHA384[] = { 0xAA, 0x39, 0xE6, 0xF6, 0x6D, 0xD0, 0xA6, 0x3E, 0x09, 0x2D, 0xA2, 0xCA, 0x17, 0x2D, 0x91, 0xF4, 0xFB, 0x1F, 0x14, 0x3A, 0xB2, 0xF2, 0x55, 0xD8, 0xDA, 0x3B, 0xE4, 0x10, 0xEB, 0x02, 0x98, 0x72, 0xBA, 0xD7, 0xC0, 0x18, 0x18, 0xED, 0xB3, 0xE8, 0x52, 0x60, 0x90, 0x53, 0xB1, 0x4F, 0x89, 0x00 }; static const unsigned char prf_ems_resMasSec_TLS1_2_SHA512[] = { 0xD2, 0xBA, 0xC7, 0x9D, 0x39, 0xA4, 0x6B, 0x34, 0xBE, 0x3D, 0xA2, 0xEA, 0xE7, 0x8C, 0xDD, 0x66, 0xF2, 0xAF, 0x4E, 0xD1, 0x19, 0xAB, 0x65, 0x50, 0x58, 0xBB, 0x27, 0x87, 0x99, 0xCF, 0x1A, 0x0E, 0x8C, 0x65, 0x41, 0x57, 0x5F, 0xF4, 0xE2, 0xAB, 0x94, 0x1A, 0x75, 0xC8, 0x71, 0x33, 0x1C, 0x5B }; static const unsigned char prf_ems_resMasSec_TLS1_TLS1_1_MD5SHA1[] = { 0xC3, 0x5D, 0xF1, 0xC2, 0x5B, 0x8B, 0x01, 0xB7, 0xA8, 0x9A, 0x71, 0x03, 0x0E, 0x01, 0x4C, 0x0E, 0xF9, 0xBB, 0x07, 0xC4, 0xDC, 0x62, 0xE6, 0xE0, 0x4C, 0x48, 0x02, 0x2E, 0x94, 0x94, 0xC9, 0x85, 0x38, 0xA4, 0x26, 0x4F, 0xDE, 0x90, 0xE8, 0x8A, 0xD6, 0x5D, 0xB9, 0x96, 0x7A, 0xA9, 0xC8, 0xF8 }; static int qat_PRF(const EVP_MD **md,int md_count, const void *seed1, int seed1_len, const void *seed2, int seed2_len, const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, int slen, unsigned char *out, int olen); void populateMdServerFinished(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MD_SERVER_FINISHED_SEED2_LEN; *seed2 = (void *)&prf_sf_lseed2; seed3 = NULL; seed4 = NULL; seed5 = NULL; *sec_len = MD_SERVER_FINISHED_SEC_LEN; *sec = (void *)&prf_sf_lsec; *buff_size = MD_SERVER_FINISHED_BUFF_SIZE; *masterSecLen = MD_SERVER_FINISHED_MASTER_SEC_LEN; if (TLS1_2_VERSION == tls_version) { if (!strcmp(digest_kdf, "SHA256")) *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_2_SHA256; else if (!strcmp(digest_kdf, "SHA384")) *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_2_SHA384; else if (!strcmp(digest_kdf, "SHA512")) *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_2_SHA512; } else *expectedMasterSecret = (void *)&prf_sf_resMasSec_TLS1_TLS1_1_MD5SHA1; } void populateMdClientFinished(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MD_CLIENT_FINISHED_SEED2_LEN; *seed2 = (void *)&prf_cf_lseed2; seed3 = NULL; seed4 = NULL; seed5 = NULL; *sec_len = MD_CLIENT_FINISHED_SEC_LEN; *sec = (void *)&prf_cf_lsec; *buff_size = MD_CLIENT_FINISHED_BUFF_SIZE; *masterSecLen = MD_CLIENT_FINISHED_MASTER_SEC_LEN; if (TLS1_2_VERSION == tls_version) { if(!strcmp(digest_kdf, "SHA256") ){ *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_2_SHA256; } else if(!strcmp(digest_kdf, "SHA384")){ *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_2_SHA384; } else if(!strcmp(digest_kdf, "SHA512")){ *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_cf_resMasSec_TLS1_TLS1_1_MD5SHA1; } } void populateMdKeyExpansion(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MD_KEY_EXPANSION_SEED2_LEN; *seed2 = (void *)&prf_ke_lseed2; *seed3_len = MD_KEY_EXPANSION_SEED3_LEN; *seed3 = (void *)&prf_ke_lseed3; seed4 = NULL; seed5 = NULL; *sec_len = MD_KEY_EXPANSION_SEC_LEN; *sec = (void *)&prf_ke_lsec; *buff_size = MD_KEY_EXPANSION_BUFF_SIZE; *masterSecLen = MD_KEY_EXPANSION_MASTER_SEC_LEN; if (TLS1_2_VERSION == tls_version) { if(!strcmp(digest_kdf, "SHA256") ){ *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_2_SHA256; } else if(!strcmp(digest_kdf, "SHA384")){ *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_2_SHA384; } else if(!strcmp(digest_kdf, "SHA512")){ *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_ke_resMasSec_TLS1_TLS1_1_MD5SHA1; } } void populateMasterSecret(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = MASTER_SECRET_SEED2_LEN; *seed2 = (void *)&prf_ms_lseed2; seed3 = NULL; *seed4_len = MASTER_SECRET_SEED4_LEN; *seed4 = (void *)&prf_ms_lseed4; seed5 = NULL; *sec_len = MASTER_SECRET_SEC_LEN; *sec = (void *)&prf_ms_lsec; *buff_size = SSL_MAX_MASTER_KEY_LENGTH; *masterSecLen = SSL_MAX_MASTER_KEY_LENGTH; if (TLS1_2_VERSION == tls_version) { if(!strcmp(digest_kdf, "SHA256") ){ *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_2_SHA256; } else if(!strcmp(digest_kdf, "SHA384")){ *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_2_SHA384; } else if(!strcmp(digest_kdf, "SHA512")){ *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_ms_resMasSec_TLS1_TLS1_1_MD5SHA1; } } void populateExtendedMasterSecret(void **seed2, int *seed2_len, void **seed3, int *seed3_len, void **seed4, int *seed4_len, void **seed5, int *seed5_len, unsigned char **sec, int *sec_len, int *buff_size, size_t *masterSecLen, unsigned char **expectedMasterSecret, int tls_version, char *digest_kdf) { *seed2_len = EXTENDED_MASTER_SECRET_SEED2_LEN; *seed2 = (void *)&prf_ems_lseed2; seed3 = NULL; seed4 = NULL; seed5 = NULL; *sec_len = EXTENDED_MASTER_SECRET_SEC_LEN; *sec = (void *)&prf_ems_lsec; *buff_size = SSL_MAX_MASTER_KEY_LENGTH; *masterSecLen = SSL_MAX_MASTER_KEY_LENGTH; if (TLS1_2_VERSION == tls_version) { if(!strcmp(digest_kdf, "SHA256") ){ *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_2_SHA256; } else if(!strcmp(digest_kdf, "SHA384")){ *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_2_SHA384; } else if(!strcmp(digest_kdf, "SHA512")){ *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_2_SHA512; } } else { *expectedMasterSecret = (void *)&prf_ems_resMasSec_TLS1_TLS1_1_MD5SHA1; } } static int qat_PRF(const EVP_MD **md,int md_count, const void *seed1, int seed1_len, const void *seed2, int seed2_len, const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, const unsigned char *sec, int slen, unsigned char *out, int olen) { EVP_PKEY_CTX *pctx = NULL; int ret = 0; size_t outlen = olen; if (md == NULL) { /* Should never happen */ WARN("# FAIL: md has not been set\n"); return 0; } pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_tls1_prf_md(pctx, *md) <= 0) goto err; if (EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, slen) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed4, seed4_len) <= 0) goto err; if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed5, seed5_len) <= 0) goto err; if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) goto err; ret = 1; err: if (ret == 0) WARN("# FAIL: performing qat_PRF operations\n"); EVP_PKEY_CTX_free(pctx); return ret; } static int runTlsPrfOps(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int operation = temp_args->prf_op; int print_output = temp_args->print_output; int verify = temp_args->verify; char *tls_version = temp_args->tls_version; char *digest_kdf = temp_args->digest_kdf; const EVP_MD *md[SSL_MAX_DIGEST] = {0}; int md_count = 0, version = 0; void *seed1 = NULL, *seed2 = NULL, *seed3 = NULL, *seed4 = NULL, *seed5 = NULL; int seed1_len = 0, seed2_len = 0, seed3_len = 0, seed4_len = 0, seed5_len = 0; int secSize = 0, buff_len = 0; unsigned char *secret = NULL, *expectedMasterSecret = NULL; unsigned char *masterSecret = NULL; int res = 0; size_t masterSecretSize = 0; int count = 0; OpenSSL_add_all_digests(); for (count = 0; count < *(temp_args->count); count++) { if(!strcmp(tls_version, "TLSv1_2")) { md_count=1; version = TLS1_2_VERSION; if(!strcmp(digest_kdf, "SHA256") ){ md[0] = EVP_get_digestbyname(SN_sha256); } else if(!strcmp(digest_kdf, "SHA384")){ md[0] = EVP_get_digestbyname(SN_sha384); } else if(!strcmp(digest_kdf, "SHA512")){ md[0] = EVP_get_digestbyname(SN_sha512); } } else if(!strcmp(tls_version, "TLSv1") || !strcmp(tls_version, "TLSv1_1")) { md_count = 1; /* This does not need to be done when using the QAT Engine * but we will do it anyway as otherwise if prf is disabled *in the build we will crash when we drop to software. */ md[0] = EVP_get_digestbyname(SN_md5_sha1); if (!strcmp(tls_version, "TLSv1")) version = TLS1_VERSION; else version = TLS1_1_VERSION; } else if(!strcmp(tls_version, "SSLv3")) { WARN("# FAIL: SSL3 version is currently not supported!!\n"); return res; } switch(operation) { case 0: /*TLS_MD_MASTER_SECRET_CONST*/ if (count == 0) DEBUG("Validating: TLS_MD_MASTER_SECRET_CONST\n"); seed1 = TLS_MD_MASTER_SECRET_CONST; seed1_len = TLS_MD_MASTER_SECRET_CONST_SIZE; populateMasterSecret(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 1: /*TLS_MD_KEY_EXPANSION_CONST*/ if (count == 0) DEBUG("Validating: TLS_MD_KEY_EXPANSION_CONST\n"); seed1 = TLS_MD_KEY_EXPANSION_CONST; seed1_len = TLS_MD_KEY_EXPANSION_CONST_SIZE; populateMdKeyExpansion(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 2: /*TLS_MD_CLIENT_FINISH_CONST*/ if (count == 0) DEBUG("Validating: TLS_MD_CLIENT_FINISH_CONST\n"); seed1 = TLS_MD_CLIENT_FINISH_CONST; seed1_len = TLS_MD_CLIENT_FINISH_CONST_SIZE; populateMdClientFinished(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 3: /*TLS_MD_SERVER_FINISH_CONST*/ if (count == 0) DEBUG("Validating: TLS_MD_SERVER_FINISH_CONST\n"); seed1 = TLS_MD_SERVER_FINISH_CONST; seed1_len = TLS_MD_SERVER_FINISH_CONST_SIZE; populateMdServerFinished(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; case 4: /*TLS_MD_EXTENDED_MASTER_SECRET_CONST*/ if (count == 0) DEBUG("Validating: TLS_MD_EXTENDED_MASTER_SECRET_CONST\n"); seed1 = TLS_MD_EXTENDED_MASTER_SECRET_CONST; seed1_len = TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE; populateExtendedMasterSecret(&seed2, &seed2_len, &seed3, &seed3_len, &seed4, &seed4_len, &seed5, &seed5_len, &secret, &secSize, &buff_len, &masterSecretSize, &expectedMasterSecret, version, digest_kdf); break; } masterSecret = OPENSSL_malloc(sizeof (unsigned char) * masterSecretSize); res = qat_PRF(md, md_count, seed1, seed1_len, seed2, seed2_len, seed3, seed3_len, seed4, seed4_len, seed5, seed5_len, secret, secSize, masterSecret, masterSecretSize); if ((verify && count == 0) || res == 0) { if (memcmp(masterSecret,expectedMasterSecret,masterSecretSize)) { INFO("# FAIL verify for PRF.\n"); tests_hexdump("PRF actual :", masterSecret, masterSecretSize); tests_hexdump("PRF expected:", expectedMasterSecret, masterSecretSize); res = 0; } else { INFO("# PASS verify for PRF.\n"); } } if (print_output) tests_hexdump("PRF master secret:", masterSecret, masterSecretSize); if (masterSecret) OPENSSL_free(masterSecret); } return res; } /****************************************************************************** * function: * tests_run_prf (TEST_PARAMS *args) * * * @param args [IN] - the test parameters * * Description: * This is a function to test the PRF (Pseudo Random Function) used in TLS1.2 ******************************************************************************/ void tests_run_prf(TEST_PARAMS *args) { int operation = 0; if (args->performance || args->prf_op != -1 ) { if (args->prf_op != -1) args->prf_op = 0; /* Operation if not specified for performance tests */ if (!args->enable_async) { runTlsPrfOps(args); } else { start_async_job(args, runTlsPrfOps); } return; } if (!args->enable_async) { for (operation = 0; operation < 5; operation++) { args->prf_op = operation; runTlsPrfOps(args); } } else { for (operation = 0; operation < 5; operation++) { args->prf_op = operation; start_async_job(args, runTlsPrfOps); } } } qatengine-1.9.0/test/tests_rsa.c000066400000000000000000005162421500416242000166320ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" # define RSA_DEFAULT_PRIME_NUM 2 /* Maximum RSA size supported */ #define RSA_SIZE 1024 #define RSA_PKCS1_OAEP_PADDING_SIZE 62 /* RSA data sizes in bytes */ /* RSA 1024 bit */ #define RSA_SIZE_1024 128 #define HASH_DATA_SIZE_1024 25 #define HASH_DATA_SIZE_NO_PADDING_1024 128 /* RSA 2048 bit */ #define RSA_SIZE_2048 256 #define HASH_DATA_SIZE_2048 50 #define HASH_DATA_SIZE_NO_PADDING_2048 256 /* RSA 4096 bit */ #define RSA_SIZE_4096 512 #define HASH_DATA_SIZE_4096 100 #define HASH_DATA_SIZE_NO_PADDING_4096 512 /* RSA 8192 bit */ #define RSA_SIZE_8192 1024 #define HASH_DATA_SIZE_8192 200 #define HASH_DATA_SIZE_NO_PADDING_8192 1024 #define MAX_MISALIGNMENT 63 #define USE_ENGINE 1 #define USE_SW 0 static int padding[] = { RSA_NO_PADDING, RSA_PKCS1_PADDING, RSA_X931_PADDING, RSA_PKCS1_OAEP_PADDING }; static const unsigned char rsaCrtCoefQInv_1024_KeyPair[] = { 0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d, 0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11, 0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81, 0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1 }; static const unsigned char rsaCrtCoefQInv_2048_KeyPair[] = { 0x6f, 0x38, 0x52, 0x6b, 0x39, 0x25, 0x08, 0x55, 0x34, 0xef, 0x3e, 0x41, 0x5a, 0x83, 0x6e, 0xde, 0x8b, 0x86, 0x15, 0x8a, 0x2c, 0x7c, 0xbf, 0xec, 0xcb, 0x0b, 0xd8, 0x34, 0x30, 0x4f, 0xec, 0x68, 0x3b, 0xa8, 0xd4, 0xf4, 0x79, 0xc4, 0x33, 0xd4, 0x34, 0x16, 0xe6, 0x32, 0x69, 0x62, 0x3c, 0xea, 0x10, 0x07, 0x76, 0xd8, 0x5a, 0xff, 0x40, 0x1d, 0x3f, 0xff, 0x61, 0x0e, 0xe6, 0x54, 0x11, 0xce, 0x3b, 0x13, 0x63, 0xd6, 0x3a, 0x97, 0x09, 0xee, 0xde, 0x42, 0x64, 0x7c, 0xea, 0x56, 0x14, 0x93, 0xd5, 0x45, 0x70, 0xa8, 0x79, 0xc1, 0x86, 0x82, 0xcd, 0x97, 0x71, 0x0b, 0x96, 0x20, 0x5e, 0xc3, 0x11, 0x17, 0xd7, 0x3b, 0x5f, 0x36, 0x22, 0x3f, 0xad, 0xd6, 0xe8, 0xba, 0x90, 0xdd, 0x7c, 0x0e, 0xe6, 0x1d, 0x44, 0xe1, 0x63, 0x25, 0x1e, 0x20, 0xc7, 0xf6, 0x6e, 0xb3, 0x05, 0x11, 0x7c, 0xb8 }; static const unsigned char rsaCrtCoefQInv_4096_KeyPair[] = { 0x94, 0x13, 0xB8, 0x44, 0x05, 0x22, 0xCD, 0xC8, 0x71, 0xFB, 0x20, 0xC0, 0x39, 0x90, 0xD6, 0xA7, 0x82, 0x7F, 0x93, 0xE2, 0x5A, 0x8C, 0x96, 0x7D, 0x4D, 0xDC, 0xFE, 0xDD, 0x89, 0x5B, 0x95, 0x3D, 0xF9, 0xF3, 0xE6, 0xE4, 0x50, 0xE4, 0xF0, 0xE6, 0xD3, 0xDB, 0x1E, 0x85, 0xC7, 0xCA, 0xCE, 0x6B, 0xC6, 0x6E, 0x21, 0x3B, 0x61, 0x83, 0xC9, 0x31, 0x8A, 0xB9, 0x9C, 0x0F, 0x87, 0x1A, 0xD7, 0x78, 0xC8, 0xCD, 0x53, 0xCA, 0x0F, 0xA4, 0x2B, 0xFE, 0x35, 0x44, 0x8B, 0x59, 0x1E, 0xE7, 0x5A, 0x04, 0xCB, 0xFD, 0xC2, 0xD0, 0x95, 0x4F, 0x43, 0x58, 0x7F, 0x00, 0x06, 0x20, 0x54, 0xD9, 0x9D, 0x49, 0x4D, 0xDA, 0x19, 0xEE, 0xD5, 0x49, 0xA4, 0xAA, 0xD1, 0xE1, 0xBA, 0xCF, 0x18, 0x58, 0x21, 0xB5, 0x96, 0x06, 0x5E, 0x27, 0x82, 0x79, 0x0E, 0x6D, 0x33, 0xD4, 0xE3, 0x58, 0xB9, 0xD5, 0x73, 0x20, 0x7E, 0x21, 0x23, 0x97, 0x12, 0x84, 0x54, 0xBB, 0x9B, 0xBB, 0xC1, 0xBE, 0x6F, 0xF1, 0xF3, 0x12, 0xBA, 0x20, 0xD7, 0x51, 0xAA, 0x46, 0x96, 0x87, 0x85, 0xAA, 0x50, 0xDB, 0x3C, 0x4D, 0xA1, 0x6E, 0xAD, 0xF6, 0xB6, 0xB6, 0x73, 0xD2, 0xAE, 0x5C, 0x96, 0x83, 0x25, 0x4E, 0x32, 0x9F, 0x3A, 0x89, 0xB6, 0x1A, 0x28, 0x4C, 0xFE, 0x9E, 0x89, 0x4B, 0x64, 0xB7, 0x89, 0xE2, 0xEE, 0xF9, 0x38, 0x5D, 0x65, 0x9C, 0x66, 0x15, 0x74, 0x00, 0xA8, 0xBE, 0xD2, 0x30, 0xA2, 0x25, 0xB4, 0x33, 0xDA, 0xD2, 0xBD, 0x6C, 0xB3, 0xE0, 0x2C, 0x54, 0xE6, 0xF6, 0x90, 0xA9, 0x0C, 0x44, 0xCC, 0xE9, 0x2A, 0x50, 0xC7, 0x80, 0x5D, 0x40, 0xF3, 0x2D, 0x83, 0x60, 0x27, 0x95, 0x57, 0x79, 0xBF, 0x0E, 0xC0, 0x23, 0x75, 0x21, 0xA5, 0x78, 0xBC, 0xA2, 0x5E, 0x63, 0xAF, 0x9D, 0xBC, 0x29, 0x10, 0x81, 0x4D, 0xFD }; static const unsigned char rsaCrtCoefQInv_8192_KeyPair[] = { 0x18, 0x2c, 0xbc, 0x37, 0x37, 0x3c, 0xa2, 0x29, 0xce, 0x4d, 0x97, 0xd7, 0x33, 0x1c, 0x51, 0x38, 0x03, 0xab, 0xb5, 0x0c, 0x08, 0x7a, 0xf2, 0x18, 0x4d, 0xdd, 0x65, 0xf4, 0x36, 0x25, 0x7c, 0xe8, 0xd8, 0xb5, 0xda, 0x18, 0xbc, 0x9c, 0x82, 0x40, 0x0c, 0xb0, 0xcc, 0x90, 0xbe, 0xbb, 0x4a, 0x26, 0x21, 0x89, 0x9d, 0xb8, 0x18, 0x0c, 0xc7, 0x42, 0x67, 0xcb, 0xc6, 0x1c, 0x9d, 0x64, 0xf3, 0x15, 0x03, 0x6c, 0xf3, 0xbd, 0x65, 0xbb, 0x32, 0x94, 0x52, 0x6f, 0x44, 0x53, 0x0c, 0x37, 0xc7, 0x7d, 0xe4, 0x8a, 0xd0, 0x37, 0xca, 0xcd, 0x76, 0x49, 0xb2, 0xac, 0x64, 0xcc, 0xa2, 0xff, 0x3e, 0x08, 0x93, 0xa7, 0xf5, 0x9e, 0xd2, 0x72, 0x28, 0xeb, 0xb0, 0x1f, 0xf3, 0x63, 0x9e, 0xe8, 0x80, 0x7c, 0xe6, 0x10, 0x83, 0x71, 0xf6, 0xa4, 0x95, 0xbd, 0x8e, 0xf1, 0xdb, 0xdb, 0x33, 0x74, 0x45, 0x3a, 0x6f, 0xfa, 0x14, 0xc1, 0x8a, 0xb5, 0xa7, 0xa5, 0x45, 0x10, 0xcd, 0x0b, 0xca, 0x52, 0xa8, 0xa9, 0xcd, 0x92, 0xf0, 0x17, 0x83, 0xca, 0x0c, 0x68, 0xf5, 0x30, 0xd8, 0xd1, 0x70, 0x2b, 0x73, 0xdb, 0xfa, 0xf2, 0x85, 0xeb, 0xa5, 0x04, 0x97, 0x7d, 0x33, 0xcf, 0xd3, 0x40, 0x4d, 0x69, 0xd5, 0x83, 0x9a, 0x08, 0x44, 0xcc, 0x40, 0xa7, 0x07, 0x89, 0x93, 0x7d, 0xa8, 0x39, 0x8e, 0x75, 0x01, 0xf0, 0xb6, 0x7c, 0x24, 0x55, 0x17, 0x74, 0x00, 0xa5, 0xe9, 0x79, 0xf8, 0x0a, 0x62, 0xba, 0xa5, 0xce, 0x80, 0xaf, 0xb2, 0xd3, 0x7d, 0x46, 0x21, 0x31, 0xc3, 0xe2, 0x75, 0x77, 0xdd, 0xd5, 0xb1, 0xe5, 0x58, 0xec, 0x42, 0x6d, 0xe6, 0x48, 0xdb, 0x9c, 0xe6, 0x9b, 0x58, 0xcd, 0x2e, 0xf0, 0xc9, 0x1d, 0x8c, 0x63, 0x80, 0xd2, 0x5f, 0x25, 0x86, 0x11, 0x88, 0x36, 0x65, 0x7a, 0x89, 0x8e, 0x7b, 0xb0, 0x6b, 0xcf, 0x02, 0xa7, 0x41, 0xf1, 0xa9, 0xac, 0x4c, 0x74, 0x66, 0xb2, 0x4d, 0x20, 0x48, 0x07, 0xbe, 0x06, 0x05, 0xf0, 0x0e, 0x46, 0xa8, 0xf5, 0xb8, 0xae, 0xe9, 0x7d, 0xf3, 0x31, 0x34, 0xf7, 0x61, 0xc7, 0x6c, 0x59, 0x1b, 0x96, 0xeb, 0x68, 0xff, 0x4c, 0x39, 0xac, 0xb1, 0x91, 0xa6, 0x94, 0x9a, 0x7c, 0x21, 0x80, 0xb2, 0x23, 0x1a, 0x46, 0x5c, 0x4b, 0x37, 0x54, 0x53, 0x11, 0xf8, 0xf5, 0x7f, 0xc1, 0x85, 0x55, 0xaa, 0x7e, 0x99, 0x22, 0x5e, 0xaa, 0x38, 0x22, 0x15, 0xa5, 0x7c, 0x72, 0x46, 0xcf, 0xe3, 0xb9, 0x85, 0x22, 0x74, 0x72, 0x2f, 0x47, 0xcc, 0x03, 0xfe, 0xd7, 0xfe, 0xac, 0x6c, 0x8c, 0xdd, 0xf7, 0xd8, 0x2e, 0x70, 0x72, 0x02, 0x1f, 0xdb, 0x89, 0x73, 0x23, 0xf8, 0x38, 0xe4, 0xde, 0x30, 0xe0, 0x8c, 0x0f, 0x06, 0xb2, 0x51, 0xb6, 0xc1, 0x9f, 0xd3, 0x13, 0x0c, 0xaa, 0x36, 0xd3, 0x7a, 0x84, 0x84, 0x8e, 0xe1, 0x1a, 0xd1, 0x0a, 0x32, 0x2d, 0xf7, 0x77, 0xa5, 0x63, 0xc8, 0xe3, 0xc1, 0x76, 0xbb, 0x64, 0x6b, 0xcb, 0x1c, 0x12, 0x84, 0x45, 0x63, 0x10, 0xc5, 0x03, 0x48, 0x92, 0xfc, 0x01, 0xaf, 0x8e, 0xe4, 0x13, 0x57, 0xa6, 0x95, 0x03, 0x49, 0xf3, 0xa8, 0x42, 0x42, 0x95, 0x8b, 0xd4, 0xba, 0x73, 0xaf, 0x21, 0x86, 0xfd, 0xef, 0x02, 0x44, 0x28, 0x65, 0x88, 0xbd, 0x1b, 0xdb, 0x0f, 0xdf, 0x31, 0xd2, 0xa6, 0x87, 0x7f, 0xd8, 0x50, 0x08, 0x6a, 0xd1, 0x89, 0x11, 0x43, 0x40, 0x76, 0x8f, 0x54, 0xe7, 0xfd, 0x8a, 0x95, 0x2b, 0x20, 0xa2, 0x9c, 0xba, 0x13, 0xfd, 0xe1, 0xd9, 0xe5, 0x36, 0x7b, 0x7d, 0x97, 0x0b, 0xd8, 0xce, 0xb4, 0x1e, 0x54, 0xaa, 0x02, 0x17, 0x34, 0xab, 0x58, 0x42, 0x73, 0x1e, 0xa8, 0x39, 0x6d, 0x2b, 0x4b, 0xf5, 0x6c, 0xd0, 0x37}; static const unsigned char rsaCrtExpDq_1024_KeyPair[] = { 0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc, 0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73, 0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a, 0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83 }; static const unsigned char rsaCrtExpDq_2048_KeyPair[] = { 0x26, 0x58, 0xb3, 0x7f, 0x6d, 0xf9, 0xc1, 0x03, 0x0b, 0xe1, 0xdb, 0x68, 0x11, 0x7f, 0xa9, 0xd8, 0x7e, 0x39, 0xea, 0x2b, 0x69, 0x3b, 0x7e, 0x6d, 0x3a, 0x2f, 0x70, 0x94, 0x74, 0x13, 0xee, 0xc6, 0x14, 0x2e, 0x18, 0xfb, 0x8d, 0xfc, 0xb6, 0xac, 0x54, 0x5d, 0x7c, 0x86, 0xa0, 0xad, 0x48, 0xf8, 0x45, 0x71, 0x70, 0xf0, 0xef, 0xb2, 0x6b, 0xc4, 0x81, 0x26, 0xc5, 0x3e, 0xfd, 0x1d, 0x16, 0x92, 0x01, 0x98, 0xdc, 0x2a, 0x11, 0x07, 0xdc, 0x28, 0x2d, 0xb6, 0xa8, 0x0c, 0xd3, 0x06, 0x23, 0x60, 0xba, 0x3f, 0xa1, 0x3f, 0x70, 0xe4, 0x31, 0x2f, 0xf1, 0xa6, 0xcd, 0x6b, 0x8f, 0xc4, 0xcd, 0x9c, 0x5c, 0x3d, 0xb1, 0x7c, 0x6d, 0x6a, 0x57, 0x21, 0x2f, 0x73, 0xae, 0x29, 0xf6, 0x19, 0x32, 0x7b, 0xad, 0x59, 0xb1, 0x53, 0x85, 0x85, 0x85, 0xba, 0x4e, 0x28, 0xb6, 0x0a, 0x62, 0xa4, 0x5e, 0x49 }; static const unsigned char rsaCrtExpDq_4096_KeyPair[] = { 0x2A, 0x38, 0xD4, 0x7A, 0x18, 0x8D, 0xCE, 0xFA, 0x18, 0xD4, 0x6D, 0x2A, 0x8A, 0xD7, 0xD7, 0xA7, 0x94, 0x54, 0x4C, 0x09, 0x2E, 0x57, 0xD0, 0x01, 0x7E, 0x59, 0xE2, 0x18, 0xD7, 0xAE, 0xB5, 0x14, 0x00, 0xAA, 0x6E, 0xDA, 0x3A, 0x35, 0x39, 0x05, 0xC7, 0x31, 0xA0, 0xCA, 0xBB, 0x05, 0x34, 0x48, 0x18, 0xCF, 0x3A, 0xDC, 0x66, 0xA4, 0xBE, 0xB0, 0x6B, 0x13, 0x0E, 0x7F, 0x26, 0x60, 0xF8, 0xC3, 0x5A, 0x6A, 0x20, 0xB4, 0x45, 0x47, 0xCC, 0x10, 0x8A, 0x2C, 0xFD, 0x23, 0xC2, 0x77, 0x1E, 0x78, 0xCC, 0xAF, 0x46, 0x89, 0x7E, 0xFE, 0xE7, 0x4F, 0x6F, 0x3C, 0xA4, 0xE9, 0xE0, 0xBA, 0xBA, 0x88, 0xE1, 0x81, 0x59, 0x60, 0xE8, 0xDE, 0x0A, 0xE7, 0xB7, 0xB3, 0x4C, 0xCD, 0x7A, 0x35, 0x54, 0x8A, 0x23, 0x70, 0x8F, 0x0A, 0xED, 0x46, 0x3A, 0x83, 0x3C, 0x33, 0x98, 0xDA, 0x80, 0x71, 0x21, 0x6F, 0xE4, 0x8D, 0x6C, 0x60, 0x50, 0x7B, 0x97, 0xF7, 0x7C, 0x8E, 0x18, 0x24, 0x69, 0xB2, 0x2B, 0x76, 0x95, 0x89, 0xD1, 0xD3, 0x93, 0x5E, 0x78, 0xB0, 0xA0, 0x1C, 0x9D, 0x64, 0xD4, 0xEE, 0xD4, 0xF6, 0x17, 0x3A, 0x84, 0x0F, 0x87, 0xEA, 0x85, 0x2A, 0xDC, 0x77, 0x24, 0x53, 0x13, 0xAC, 0x97, 0xCD, 0xC3, 0x2D, 0xDF, 0x1A, 0x1E, 0x3D, 0xC3, 0x3D, 0x75, 0xDF, 0x08, 0xA8, 0xD4, 0x91, 0xF2, 0x8C, 0x09, 0x4C, 0x43, 0xF7, 0xC1, 0xB3, 0xAE, 0xC4, 0xC8, 0x6F, 0x80, 0x0C, 0x60, 0xB6, 0x3D, 0xFF, 0x84, 0xAA, 0xDA, 0x33, 0x2C, 0x59, 0x54, 0xE7, 0x07, 0x1B, 0x72, 0x74, 0x73, 0x13, 0x5E, 0x2D, 0x6B, 0x35, 0xCB, 0x56, 0xE0, 0x03, 0xA6, 0xBF, 0xA5, 0xB0, 0xC6, 0x53, 0x0E, 0x27, 0x12, 0x6D, 0xED, 0x24, 0x17, 0x9F, 0x11, 0x18, 0x1C, 0xB8, 0xE2, 0x73, 0x20, 0xEE, 0x63, 0x4D, 0x68, 0x4F }; static const unsigned char rsaCrtExpDq_8192_KeyPair[] = { 0x5a, 0xda, 0xbc, 0x9d, 0x7f, 0x7c, 0x15, 0x44, 0xf4, 0x99, 0xf2, 0x6b, 0x22, 0xf0, 0x10, 0x4f, 0xc4, 0x77, 0x36, 0x97, 0xef, 0xfe, 0x09, 0x7e, 0x83, 0x47, 0xaf, 0xc5, 0xbf, 0xbb, 0x35, 0x25, 0x46, 0x91, 0xf7, 0x2c, 0x87, 0x76, 0xc3, 0x68, 0x91, 0x69, 0x88, 0x5b, 0xeb, 0xcc, 0x8e, 0x72, 0xcf, 0x47, 0x79, 0x52, 0x01, 0x76, 0x5c, 0xab, 0x18, 0xce, 0x7f, 0x6e, 0xd2, 0x5a, 0x04, 0x94, 0x67, 0xe4, 0xbf, 0xfe, 0x1f, 0x2e, 0x55, 0x7e, 0xd2, 0x98, 0x2d, 0x7e, 0xc5, 0x96, 0xab, 0x10, 0xc6, 0x67, 0xfe, 0xf9, 0xa0, 0xa1, 0xb7, 0xf2, 0x3a, 0x5e, 0xd0, 0x7b, 0x17, 0xcc, 0x52, 0xcd, 0x18, 0xa2, 0x1c, 0x42, 0x3a, 0xfa, 0x70, 0x8c, 0x8d, 0x15, 0x7a, 0x26, 0x38, 0xba, 0xcf, 0x7a, 0x8e, 0x49, 0xb0, 0xb1, 0x36, 0xa8, 0x06, 0x13, 0xd8, 0x7a, 0x3b, 0x39, 0x9b, 0xc3, 0xc1, 0x9e, 0x60, 0xef, 0x55, 0xa2, 0x8d, 0xc8, 0x02, 0xaa, 0xcd, 0xc0, 0xef, 0x9d, 0xc8, 0x5d, 0x34, 0x04, 0x35, 0x59, 0x27, 0x40, 0xa6, 0x1b, 0xdc, 0xc9, 0xdd, 0x68, 0x17, 0x71, 0xe7, 0xd1, 0x1c, 0x83, 0x76, 0x70, 0x06, 0x95, 0xd5, 0xbb, 0x7c, 0xf6, 0x19, 0x5e, 0xe9, 0x7a, 0x72, 0x1e, 0xca, 0x8f, 0x14, 0x8a, 0x8c, 0x21, 0xc1, 0xa0, 0x75, 0xd1, 0xf2, 0xda, 0x72, 0xfb, 0xba, 0x53, 0x8a, 0xaa, 0x24, 0xa2, 0xfb, 0x72, 0x18, 0xe4, 0xe2, 0xe6, 0xbb, 0x6e, 0x50, 0x25, 0x84, 0x08, 0x61, 0x1f, 0x5c, 0x6d, 0x83, 0xf2, 0x41, 0x92, 0xd1, 0x86, 0xdc, 0xb7, 0x38, 0x94, 0xc0, 0xf8, 0x57, 0x7a, 0xf7, 0x03, 0x51, 0x1d, 0x73, 0x5d, 0x72, 0x74, 0x2d, 0x75, 0x6f, 0xee, 0x30, 0xd9, 0x9b, 0xc3, 0x3e, 0x75, 0xeb, 0xe7, 0xc1, 0x85, 0xbb, 0x0d, 0xfa, 0x3a, 0x62, 0xe8, 0x89, 0x2c, 0x91, 0xa5, 0xce, 0xd5, 0x77, 0x78, 0x87, 0x32, 0xdf, 0xe3, 0xa1, 0x38, 0xde, 0x71, 0x21, 0x90, 0x41, 0xf4, 0xca, 0xa1, 0x7f, 0xbe, 0x19, 0x86, 0x56, 0x21, 0xe3, 0x31, 0xc8, 0xe3, 0x58, 0x41, 0x3d, 0x57, 0x24, 0x67, 0x56, 0x3a, 0x0e, 0x91, 0xee, 0xba, 0xf3, 0x26, 0x11, 0xd9, 0xef, 0xeb, 0xad, 0xdd, 0x9b, 0xc8, 0x15, 0xa4, 0x1c, 0x9b, 0x0b, 0x9f, 0x89, 0x9f, 0xa4, 0xcc, 0xb7, 0x85, 0x34, 0x27, 0x47, 0x11, 0x2b, 0x89, 0x66, 0x41, 0x3a, 0x99, 0xae, 0x01, 0x0c, 0x97, 0xe9, 0xa8, 0x49, 0xef, 0x33, 0x9a, 0x70, 0x48, 0xeb, 0x03, 0xc2, 0x03, 0xad, 0x97, 0xde, 0x7a, 0x4d, 0x44, 0xf9, 0xfb, 0x3b, 0x38, 0x5a, 0x23, 0xef, 0x31, 0x6f, 0xc2, 0xb3, 0xeb, 0x3d, 0xa7, 0xca, 0x99, 0x75, 0x75, 0xd2, 0x99, 0x80, 0x60, 0x24, 0x14, 0x02, 0xcf, 0x39, 0xbc, 0xb6, 0x3d, 0x54, 0x89, 0x5a, 0x2b, 0x0d, 0x99, 0x3c, 0xa6, 0x1f, 0x16, 0x54, 0xda, 0x53, 0xb3, 0x24, 0xa8, 0xcc, 0x0c, 0xe9, 0x0e, 0xfa, 0xe0, 0xeb, 0x17, 0x7d, 0x58, 0x8e, 0xe3, 0x23, 0xc6, 0x9f, 0x2e, 0x7c, 0x4c, 0xdd, 0xe7, 0x5e, 0xd1, 0x13, 0x5f, 0x66, 0x8c, 0x2a, 0xce, 0x1f, 0x19, 0x55, 0x1a, 0x20, 0x6d, 0x15, 0xcd, 0x62, 0xac, 0xab, 0xe6, 0xb1, 0x4c, 0xe8, 0xce, 0x2d, 0x79, 0xb7, 0xa1, 0xb4, 0x77, 0xa4, 0x40, 0x5d, 0x86, 0x7a, 0x56, 0x0e, 0x0e, 0x1c, 0xe4, 0x09, 0x53, 0x7b, 0x5a, 0x50, 0x43, 0xc4, 0x9e, 0x00, 0xa6, 0x1e, 0x1b, 0x09, 0x75, 0xa7, 0x04, 0x49, 0xce, 0xad, 0x87, 0xf8, 0xab, 0x17, 0x7c, 0x95, 0xd9, 0x50, 0x1d, 0x40, 0xc8, 0x6a, 0x3a, 0xa0, 0x39, 0x85, 0xfb, 0x24, 0xf2, 0x1d, 0xb5, 0x4d, 0x75, 0x7c, 0x5d, 0x37, 0x82, 0x4d, 0xb9, 0x5a, 0x74, 0x2b, 0x50, 0x97, 0xb0, 0x5d, 0x49 }; static const unsigned char rsaCrtExpDp_1024_KeyPair[] = { 0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04, 0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3, 0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d, 0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1 }; static const unsigned char rsaCrtExpDp_2048_KeyPair[] = { 0xc7, 0x35, 0x64, 0x57, 0x1d, 0x00, 0xfb, 0x15, 0xd0, 0x8a, 0x3d, 0xe9, 0x95, 0x7a, 0x50, 0x91, 0x5d, 0x71, 0x26, 0xe9, 0x44, 0x2d, 0xac, 0xf4, 0x2b, 0xc8, 0x2e, 0x86, 0x2e, 0x56, 0x73, 0xff, 0x6a, 0x00, 0x8e, 0xd4, 0xd2, 0xe3, 0x74, 0x61, 0x7d, 0xf8, 0x9f, 0x17, 0xa1, 0x60, 0xb4, 0x3b, 0x7f, 0xda, 0x9c, 0xb6, 0xb6, 0xb7, 0x42, 0x18, 0x60, 0x98, 0x15, 0xf7, 0xd4, 0x5c, 0xa2, 0x63, 0xc1, 0x59, 0xaa, 0x32, 0xd2, 0x72, 0xd1, 0x27, 0xfa, 0xf4, 0xbc, 0x8c, 0xa2, 0xd7, 0x73, 0x78, 0xe8, 0xae, 0xb1, 0x9b, 0x0a, 0xd7, 0xda, 0x3c, 0xb3, 0xde, 0x0a, 0xe7, 0x31, 0x49, 0x80, 0xf6, 0x2b, 0x6d, 0x4b, 0x0a, 0x87, 0x5d, 0x1d, 0xf0, 0x3c, 0x1b, 0xae, 0x39, 0xcc, 0xd8, 0x33, 0xef, 0x6c, 0xd7, 0xe2, 0xd9, 0x52, 0x8b, 0xf0, 0x84, 0xd1, 0xf9, 0x69, 0xe7, 0x94, 0xe9, 0xf6, 0xc1 }; static const unsigned char rsaCrtExpDp_4096_KeyPair[] = { 0x64, 0x73, 0xFE, 0xD9, 0x52, 0xBA, 0x7B, 0xA6, 0xF6, 0xB9, 0xAA, 0xB0, 0x74, 0xDA, 0x36, 0x78, 0x76, 0x47, 0xE9, 0xC5, 0x12, 0xBD, 0xEF, 0xA9, 0x29, 0xF0, 0x2B, 0x70, 0xDA, 0xA8, 0x23, 0x18, 0x92, 0x18, 0x98, 0x9B, 0xE6, 0x2E, 0x14, 0x03, 0x77, 0x0E, 0x61, 0x8F, 0x1E, 0x9B, 0x7B, 0xCB, 0x23, 0xE8, 0xF4, 0x5D, 0xCB, 0x42, 0xD6, 0x2A, 0x58, 0x37, 0xFA, 0x58, 0x46, 0x5A, 0x07, 0xF3, 0x26, 0x29, 0x3C, 0xFE, 0x73, 0xD2, 0x0B, 0x66, 0x3D, 0x66, 0x56, 0x1B, 0xEC, 0x8D, 0xD0, 0xED, 0xE2, 0x38, 0x49, 0x3C, 0x4A, 0x62, 0xC2, 0xFC, 0xCE, 0xDB, 0xAC, 0xAA, 0xC2, 0xB8, 0xCC, 0x2D, 0x99, 0xC3, 0xCC, 0x00, 0x42, 0x31, 0x87, 0xB9, 0xB1, 0x3A, 0xA3, 0x78, 0x04, 0x38, 0xF0, 0x16, 0x01, 0xFC, 0x23, 0x05, 0x1E, 0x1F, 0xC3, 0xC1, 0xAF, 0x5A, 0x19, 0x13, 0x8B, 0xB9, 0x64, 0x48, 0x04, 0x6A, 0xA0, 0x25, 0xA6, 0xE5, 0xE8, 0x29, 0x20, 0xA0, 0xFF, 0x0F, 0xAE, 0x06, 0xF7, 0x4C, 0xAC, 0x64, 0x09, 0x24, 0x47, 0xA7, 0x00, 0x46, 0x6E, 0xA9, 0x70, 0xBD, 0x6B, 0xAF, 0x70, 0xD7, 0x63, 0xC2, 0x57, 0xFA, 0x68, 0xE0, 0x75, 0x66, 0x43, 0x03, 0x2C, 0x61, 0xF5, 0x61, 0xC3, 0x92, 0x04, 0x13, 0xD2, 0xC4, 0x9F, 0xF4, 0xA4, 0xA0, 0x3D, 0xF6, 0x25, 0xB8, 0xDE, 0xCE, 0x5C, 0x53, 0x91, 0x61, 0xDB, 0x60, 0x34, 0xE0, 0x5E, 0x3E, 0xF4, 0x73, 0xB2, 0x45, 0xE5, 0xE3, 0x71, 0xFF, 0x1C, 0xA9, 0xE6, 0x9F, 0xE4, 0xB9, 0xB4, 0xD7, 0xE5, 0x60, 0xD7, 0xAC, 0x31, 0xFB, 0x19, 0xD6, 0x2D, 0x11, 0x29, 0x55, 0x79, 0x8A, 0xF4, 0x99, 0x0E, 0x69, 0x2A, 0xED, 0x5F, 0xC1, 0x59, 0xAE, 0xAE, 0xC6, 0x66, 0x40, 0x23, 0xED, 0xED, 0x94, 0x62, 0x78, 0x9C, 0xEB, 0x48, 0x04, 0x17, 0x85 }; static const unsigned char rsaCrtExpDp_8192_KeyPair[] = { 0x26, 0x0f, 0x8f, 0x37, 0x1b, 0x58, 0x6e, 0xc1, 0xd5, 0xbc, 0x10, 0x14, 0x1a, 0x64, 0xbf, 0xfb, 0x92, 0xdc, 0x70, 0xde, 0x33, 0x20, 0xe6, 0xb6, 0xb2, 0x58, 0x46, 0x73, 0xcf, 0x6f, 0x4b, 0xe7, 0x1d, 0xb4, 0x7f, 0x54, 0x6d, 0x25, 0x65, 0x52, 0x4d, 0xd1, 0x99, 0x33, 0x41, 0xac, 0x4b, 0x71, 0xea, 0x89, 0xe4, 0x8d, 0xb2, 0x02, 0x9f, 0xbd, 0x02, 0xd2, 0x03, 0x9b, 0x67, 0x23, 0x35, 0x20, 0x6a, 0xd1, 0x0a, 0xf8, 0x7b, 0xe8, 0x20, 0x3d, 0xb0, 0x5e, 0xfc, 0x4c, 0x2e, 0xaa, 0x04, 0xac, 0x77, 0xd1, 0xb1, 0x73, 0x67, 0xf3, 0xab, 0x0b, 0x46, 0x20, 0xf2, 0xbd, 0x88, 0xb0, 0x6f, 0x75, 0xf4, 0xd4, 0xaf, 0x25, 0xea, 0xda, 0x9f, 0x6e, 0xd6, 0xb2, 0xe0, 0x81, 0x72, 0xe1, 0xc8, 0xac, 0xa4, 0xc7, 0xf3, 0x61, 0x7f, 0x11, 0x9f, 0x2a, 0x5a, 0x52, 0x3d, 0x62, 0x0e, 0x3e, 0x85, 0x25, 0x5f, 0x15, 0x51, 0x84, 0xde, 0x47, 0x3b, 0x21, 0x83, 0x2f, 0x59, 0xf8, 0x62, 0xad, 0x0c, 0x81, 0xef, 0x38, 0x03, 0x25, 0x4e, 0xad, 0xd8, 0x1c, 0x7e, 0xa0, 0x5b, 0xdf, 0x8d, 0xd8, 0x5a, 0x62, 0x43, 0xc9, 0x74, 0x6f, 0x24, 0x3c, 0x5d, 0x8d, 0x4b, 0x3c, 0xd7, 0x88, 0x0a, 0xd0, 0x5b, 0x67, 0x89, 0x44, 0xbc, 0x50, 0x34, 0x43, 0x46, 0x77, 0xfd, 0x4c, 0x9b, 0x8b, 0xb1, 0x20, 0xc5, 0x9b, 0xc4, 0x58, 0xb1, 0x23, 0xd4, 0xe9, 0xc9, 0x8c, 0x35, 0x9f, 0xf5, 0x21, 0x59, 0x43, 0x74, 0x87, 0x09, 0x38, 0x81, 0xeb, 0xea, 0xf6, 0x10, 0x53, 0x93, 0x2a, 0xbd, 0x6a, 0x77, 0x83, 0xd4, 0x9c, 0x8e, 0x9c, 0x1a, 0xbe, 0xe3, 0x65, 0x3d, 0x00, 0x83, 0xa2, 0x1e, 0xff, 0x60, 0x0c, 0x6e, 0x3a, 0xbd, 0xcf, 0x1a, 0xf4, 0x5c, 0x07, 0x63, 0xd6, 0x20, 0xf6, 0x92, 0x02, 0x4e, 0x30, 0xfe, 0xe2, 0x4d, 0x2c, 0x94, 0xee, 0x1f, 0x8f, 0x9f, 0x35, 0x70, 0x4c, 0x09, 0x5c, 0x44, 0x37, 0xa3, 0xbe, 0xd5, 0x85, 0x89, 0x91, 0x8e, 0x04, 0x80, 0xb6, 0x8c, 0xb9, 0x45, 0xc0, 0xc9, 0xb8, 0x43, 0x3b, 0xf3, 0x95, 0x37, 0x2a, 0x85, 0xdf, 0xae, 0x85, 0x0f, 0x30, 0x9d, 0xb7, 0x51, 0x86, 0x17, 0xa3, 0x84, 0x07, 0xea, 0xad, 0xcc, 0x23, 0xa2, 0xc3, 0xa0, 0x4c, 0x21, 0x6c, 0x2a, 0x7b, 0x12, 0xed, 0x11, 0xcc, 0xa7, 0x08, 0x29, 0x23, 0x39, 0x73, 0x15, 0x78, 0xfd, 0x65, 0xa1, 0xcf, 0xb3, 0xbb, 0x05, 0x66, 0x21, 0x83, 0xc3, 0x24, 0xf3, 0x6b, 0x5e, 0x95, 0xa3, 0x5f, 0x3b, 0x93, 0xd2, 0xf8, 0xec, 0x64, 0x78, 0xcd, 0x05, 0x40, 0x72, 0x7c, 0xd9, 0xca, 0x1c, 0x3a, 0xea, 0x07, 0x9b, 0xe6, 0xa5, 0x8c, 0xfb, 0xfd, 0x4c, 0xe5, 0x45, 0xf2, 0xcd, 0xeb, 0xd9, 0x41, 0x42, 0x98, 0xbd, 0xe5, 0x87, 0xb7, 0xec, 0xf9, 0x73, 0x3e, 0x8b, 0x75, 0x2e, 0x33, 0xd7, 0xc9, 0xdb, 0x2a, 0x2a, 0xfb, 0x90, 0x8e, 0x9f, 0xb6, 0x1e, 0x07, 0xc1, 0xf6, 0xfe, 0x5c, 0x8c, 0x59, 0xd8, 0x82, 0xd8, 0x6c, 0xdd, 0x78, 0x6a, 0xbf, 0x84, 0x92, 0x03, 0x6f, 0x13, 0xa2, 0xc8, 0xde, 0x31, 0xe1, 0xfe, 0x30, 0x01, 0x80, 0x66, 0x7e, 0x1c, 0x18, 0x5a, 0xeb, 0xca, 0xbb, 0x3a, 0xee, 0x65, 0xfb, 0x12, 0xdf, 0x26, 0xc3, 0x2d, 0x88, 0xf4, 0xb4, 0x28, 0xb2, 0xf7, 0x72, 0x67, 0xde, 0x2e, 0x83, 0xa4, 0x51, 0x76, 0x7d, 0xcf, 0xee, 0x70, 0xc1, 0xd4, 0x55, 0x75, 0x20, 0x14, 0x79, 0x11, 0xdd, 0x72, 0x7b, 0x89, 0xb6, 0xcd, 0x54, 0x2a, 0x12, 0x99, 0x23, 0x11, 0x20, 0xdd, 0x8d, 0xdf, 0x47, 0x93, 0xb6, 0x7a, 0xab, 0xa3, 0xa2, 0x16, 0x2b, 0x43, 0x70, 0x5d, 0xf5, 0x77, 0x13, 0xf2, 0x51, 0xc0, 0x01 }; static const unsigned char rsaPrimeQ_1024_KeyPair[] = { 0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7, 0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c, 0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe, 0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77 }; static const unsigned char rsaPrimeQ_2048_KeyPair[] = { 0xbc, 0x46, 0xc4, 0x64, 0xfc, 0x6a, 0xc4, 0xca, 0x78, 0x3b, 0x0e, 0xb0, 0x8a, 0x3c, 0x84, 0x1b, 0x77, 0x2f, 0x7e, 0x9b, 0x2f, 0x28, 0xba, 0xbd, 0x58, 0x8a, 0xe8, 0x85, 0xe1, 0xa0, 0xc6, 0x1e, 0x48, 0x58, 0xa0, 0xfb, 0x25, 0xac, 0x29, 0x99, 0x90, 0xf3, 0x5b, 0xe8, 0x51, 0x64, 0xc2, 0x59, 0xba, 0x11, 0x75, 0xcd, 0xd7, 0x19, 0x27, 0x07, 0x13, 0x51, 0x84, 0x99, 0x2b, 0x6c, 0x29, 0xb7, 0x46, 0xdd, 0x0d, 0x2c, 0xab, 0xe1, 0x42, 0x83, 0x5f, 0x7d, 0x14, 0x8c, 0xc1, 0x61, 0x52, 0x4b, 0x4a, 0x09, 0x94, 0x6d, 0x48, 0xb8, 0x28, 0x47, 0x3f, 0x1c, 0xe7, 0x6b, 0x6c, 0xb6, 0x88, 0x6c, 0x34, 0x5c, 0x03, 0xe0, 0x5f, 0x41, 0xd5, 0x1b, 0x5c, 0x3a, 0x90, 0xa3, 0xf2, 0x40, 0x73, 0xc7, 0xd7, 0x4a, 0x4f, 0xe2, 0x5d, 0x9c, 0xf2, 0x1c, 0x75, 0x96, 0x0f, 0x3f, 0xc3, 0x86, 0x31, 0x83 }; static const unsigned char rsaPrimeQ_4096_KeyPair[] = { 0xD0, 0xB2, 0x39, 0x17, 0x5C, 0xE3, 0x20, 0x42, 0xE0, 0xC0, 0x43, 0xF1, 0x67, 0x52, 0x96, 0xA0, 0x85, 0xFE, 0x1D, 0x6A, 0x2E, 0x16, 0x53, 0x8C, 0xD1, 0x48, 0x64, 0x9B, 0x58, 0x52, 0xE2, 0x11, 0x4B, 0x71, 0x80, 0x14, 0x90, 0x55, 0x53, 0x2D, 0x65, 0x7D, 0x21, 0xEE, 0x31, 0xD9, 0xDF, 0x8C, 0xB7, 0x41, 0x4F, 0xB6, 0xD0, 0x81, 0x8A, 0x97, 0xE8, 0x6F, 0x3E, 0x0A, 0x18, 0x72, 0x21, 0x54, 0xCD, 0x76, 0x3E, 0x06, 0x19, 0xD5, 0xBE, 0x03, 0x53, 0x57, 0x8C, 0x03, 0x9F, 0x49, 0x22, 0xD9, 0x45, 0x9B, 0x01, 0x8A, 0x4A, 0xA6, 0xAB, 0x61, 0x92, 0x73, 0x31, 0x39, 0xAA, 0x3F, 0x46, 0xB7, 0x62, 0x7E, 0x22, 0x73, 0x27, 0xCF, 0xB9, 0xFC, 0x61, 0xC1, 0x42, 0x87, 0xA2, 0xEA, 0x05, 0xE5, 0xDB, 0x67, 0xFB, 0x1F, 0xE2, 0x0E, 0x8D, 0xC8, 0xF2, 0xCA, 0x53, 0x69, 0x31, 0x98, 0x1F, 0x60, 0x18, 0x0B, 0x4B, 0x28, 0xDA, 0x2C, 0xAF, 0xC2, 0x4D, 0x88, 0x09, 0x29, 0x5F, 0x86, 0xB1, 0x73, 0xA7, 0x1D, 0x8C, 0x38, 0x3F, 0x36, 0xD0, 0xC6, 0x7F, 0x7E, 0x34, 0x5A, 0x04, 0xBE, 0x41, 0x64, 0xBB, 0x4B, 0xBA, 0xEB, 0x0C, 0xFE, 0xBA, 0x30, 0xE1, 0x3E, 0x34, 0x85, 0x60, 0x8D, 0x17, 0x14, 0x59, 0x94, 0x93, 0xE5, 0x75, 0x68, 0x4F, 0x25, 0x75, 0x7F, 0x1C, 0xC8, 0xFA, 0x47, 0xD8, 0x92, 0xCF, 0xF2, 0xF8, 0xF4, 0x00, 0xEA, 0x7B, 0x27, 0x32, 0xCD, 0xCA, 0x48, 0xA6, 0x67, 0xBB, 0xFE, 0x6D, 0xFB, 0xC4, 0xE1, 0x68, 0x71, 0xDC, 0xAC, 0x88, 0x83, 0xA1, 0x8B, 0x86, 0xF9, 0xE7, 0x57, 0x0B, 0xDB, 0xE7, 0xC3, 0x35, 0x02, 0x77, 0x80, 0x31, 0x20, 0x74, 0xD8, 0xB7, 0xD9, 0x8C, 0xE8, 0x39, 0x58, 0x13, 0xAD, 0x74, 0x50, 0x0B, 0xC2, 0x1F, 0x51, 0x37, 0x1D, 0x2D, 0xA8, 0x9B, 0x2B }; static const unsigned char rsaPrimeQ_8192_KeyPair[] = { 0xd2, 0xe0, 0x8d, 0x82, 0xd9, 0x07, 0x55, 0x20, 0x0a, 0x24, 0xfb, 0x70, 0xb9, 0xed, 0x63, 0x8c, 0x48, 0x73, 0x22, 0xa0, 0x48, 0x26, 0x87, 0x18, 0x4e, 0x19, 0xa1, 0x9c, 0xfd, 0x6f, 0x0d, 0xbf, 0xc5, 0x50, 0xab, 0xbd, 0xb1, 0x9f, 0x8f, 0x22, 0x88, 0x4e, 0x47, 0x0e, 0xcc, 0x40, 0xca, 0x80, 0x93, 0xe9, 0x97, 0xdb, 0xaf, 0xdb, 0x23, 0x15, 0x0c, 0x29, 0xda, 0x54, 0xf3, 0x59, 0xd2, 0x12, 0xc0, 0xf1, 0xbf, 0x1c, 0x3e, 0x58, 0x50, 0x31, 0xaf, 0x55, 0xfc, 0xa7, 0x6e, 0x42, 0xce, 0xb5, 0xb4, 0x6d, 0xdc, 0x8b, 0xfb, 0x75, 0xfa, 0x4e, 0x48, 0x52, 0xc8, 0xc8, 0xd7, 0xa1, 0x83, 0xd6, 0xc2, 0xbd, 0x6c, 0x95, 0x30, 0xbf, 0x4c, 0x2f, 0x6a, 0x05, 0xf0, 0xcd, 0x4a, 0x51, 0x61, 0xdb, 0x7f, 0x13, 0xd3, 0xff, 0xeb, 0xeb, 0x84, 0x39, 0x49, 0x6b, 0xb4, 0xe4, 0x64, 0x81, 0x3a, 0x39, 0xd4, 0xad, 0x8e, 0x11, 0xf2, 0x3e, 0x04, 0xbd, 0x74, 0xc5, 0xfc, 0xb9, 0x76, 0x81, 0xdf, 0x02, 0xce, 0x09, 0xc2, 0xcc, 0xbb, 0x88, 0xed, 0xf4, 0x8f, 0x57, 0x0b, 0xa8, 0xcf, 0x77, 0xae, 0x14, 0xb2, 0xbf, 0xd1, 0xa2, 0x09, 0xcd, 0xc2, 0x94, 0x87, 0x88, 0xc8, 0xb4, 0xff, 0xaf, 0x50, 0x99, 0x77, 0xf2, 0x14, 0x7e, 0x2f, 0x3c, 0xf5, 0x2d, 0xaa, 0x29, 0x9d, 0x0c, 0xec, 0x27, 0xf0, 0x05, 0xa6, 0xb0, 0x08, 0xe5, 0x18, 0x08, 0xf4, 0xae, 0x7e, 0xe7, 0x43, 0x4e, 0xc5, 0x56, 0xd4, 0xa8, 0xf9, 0xea, 0x51, 0x04, 0x00, 0xc5, 0x75, 0x7a, 0xe3, 0x83, 0x95, 0x7c, 0xbb, 0x65, 0x26, 0x37, 0xc3, 0x59, 0x1b, 0x2b, 0x85, 0xf4, 0xaa, 0x51, 0x98, 0xdf, 0xf4, 0x23, 0x41, 0xe4, 0x9f, 0xf9, 0xda, 0xdf, 0xda, 0x8d, 0x7c, 0x55, 0x1e, 0xf7, 0xe3, 0x5a, 0x75, 0x05, 0x13, 0xf4, 0xc8, 0x7f, 0xa8, 0xeb, 0x59, 0x73, 0x0f, 0x27, 0x57, 0x0f, 0x7e, 0xdc, 0xb5, 0xda, 0xca, 0x97, 0xd7, 0x23, 0x54, 0x03, 0x23, 0xef, 0x8b, 0xfd, 0x62, 0xc0, 0xf2, 0x24, 0xbc, 0xeb, 0x28, 0x55, 0x33, 0xe6, 0x56, 0xf3, 0x95, 0xae, 0x72, 0x0e, 0x43, 0xa4, 0xc5, 0xba, 0xec, 0x3c, 0x37, 0x9c, 0x2d, 0x32, 0xe5, 0x52, 0xe1, 0x52, 0x29, 0x8d, 0x8c, 0x1e, 0x38, 0x7e, 0xa0, 0x30, 0x6a, 0xed, 0xca, 0xa8, 0x4d, 0x65, 0x2b, 0x37, 0x3f, 0xbe, 0x26, 0x2d, 0x8e, 0x26, 0x77, 0x1b, 0x00, 0x8b, 0xba, 0x70, 0x09, 0xf3, 0xa1, 0xe2, 0x6f, 0xe2, 0xd0, 0xbd, 0x98, 0x05, 0x9f, 0x30, 0xaa, 0x96, 0x6c, 0x6f, 0xbe, 0xe6, 0x30, 0xec, 0xd3, 0xd7, 0x3a, 0x51, 0x0d, 0x12, 0xc3, 0x7f, 0xfb, 0xf3, 0x17, 0x05, 0xb1, 0xbb, 0x7c, 0x14, 0x7e, 0x88, 0x59, 0x63, 0x5f, 0x86, 0x00, 0x74, 0x25, 0xec, 0x0a, 0xc6, 0x4c, 0x8f, 0x45, 0x27, 0x2a, 0x25, 0x19, 0x6d, 0xa2, 0xeb, 0x4b, 0xa6, 0x5b, 0x83, 0x95, 0x0d, 0x20, 0xac, 0xad, 0xdc, 0x9b, 0xcc, 0x52, 0xca, 0xbf, 0xef, 0x33, 0x12, 0x7d, 0xa7, 0xad, 0x35, 0x19, 0x7f, 0xb6, 0x2a, 0xcf, 0x9e, 0x18, 0x3f, 0x0c, 0x12, 0x50, 0xe7, 0x6c, 0xf8, 0xb1, 0xcc, 0x12, 0x5e, 0x7e, 0xe3, 0x5c, 0x66, 0xcb, 0xd7, 0x70, 0x75, 0x8c, 0x20, 0x2b, 0x2b, 0x20, 0x62, 0xa8, 0xb2, 0xa4, 0xd5, 0x2c, 0x76, 0x9d, 0xa1, 0x67, 0x19, 0x64, 0x66, 0x5f, 0xf1, 0x1a, 0x4f, 0x08, 0xd9, 0x95, 0x51, 0x0c, 0xce, 0xdd, 0x3d, 0x1d, 0x82, 0xcd, 0xfa, 0x2e, 0x60, 0x1b, 0x0d, 0x23, 0xeb, 0x99, 0xa5, 0x20, 0x4a, 0xa9, 0x88, 0xa2, 0xa7, 0x3d, 0xcd, 0x8b, 0x6a, 0xc1, 0x12, 0xd9, 0xc3, 0xd0, 0xbb, 0xe4, 0x49, 0xe2, 0x70, 0xb7, 0x31, 0x31, 0x41, 0x7c, 0xa7, 0x72, 0xa7 }; static const unsigned char rsaPrimeP_1024_KeyPair[] = { 0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b, 0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a, 0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1, 0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d }; static const unsigned char rsaPrimeP_2048_KeyPair[] = { 0xec, 0xf5, 0xae, 0xcd, 0x1e, 0x55, 0x15, 0xff, 0xfa, 0xcb, 0xd7, 0x5a, 0x28, 0x16, 0xc6, 0xeb, 0xf4, 0x90, 0x18, 0xcd, 0xfb, 0x46, 0x38, 0xe1, 0x85, 0xd6, 0x6a, 0x73, 0x96, 0xb6, 0xf8, 0x09, 0x0f, 0x80, 0x18, 0xc7, 0xfd, 0x95, 0xcc, 0x34, 0xb8, 0x57, 0xdc, 0x17, 0xf0, 0xcc, 0x65, 0x16, 0xbb, 0x13, 0x46, 0xab, 0x4d, 0x58, 0x2c, 0xad, 0xad, 0x7b, 0x41, 0x03, 0x35, 0x23, 0x87, 0xb7, 0x03, 0x38, 0xd0, 0x84, 0x04, 0x7c, 0x9d, 0x95, 0x39, 0xb6, 0x49, 0x62, 0x04, 0xb3, 0xdd, 0x6e, 0xa4, 0x42, 0x49, 0x92, 0x07, 0xbe, 0xc0, 0x1f, 0x96, 0x42, 0x87, 0xff, 0x63, 0x36, 0xc3, 0x98, 0x46, 0x58, 0x33, 0x68, 0x46, 0xf5, 0x6e, 0x46, 0x86, 0x18, 0x81, 0xc1, 0x02, 0x33, 0xd2, 0x17, 0x6b, 0xf1, 0x5a, 0x5e, 0x96, 0xdd, 0xc7, 0x80, 0xbc, 0x86, 0x8a, 0xa7, 0x7d, 0x3c, 0xe7, 0x69 }; static const unsigned char rsaPrimeP_4096_KeyPair[] = { 0xD9, 0x33, 0xBC, 0x12, 0x30, 0x71, 0xE8, 0x20, 0x73, 0xF3, 0xEA, 0xCD, 0x2A, 0xF2, 0x06, 0x45, 0xCD, 0xF7, 0xFE, 0x5A, 0x57, 0xE5, 0xF0, 0x59, 0xAD, 0x46, 0x10, 0x30, 0xF8, 0x97, 0xBD, 0x62, 0x2B, 0x8E, 0xC7, 0x32, 0x2D, 0x1E, 0x5F, 0xA7, 0xFB, 0xF6, 0x23, 0xE4, 0x3B, 0x13, 0xAA, 0x72, 0x5B, 0x6B, 0xC1, 0xD3, 0x92, 0x12, 0x4A, 0x10, 0xA4, 0x58, 0x9A, 0x99, 0x48, 0xF1, 0x57, 0x16, 0xBC, 0xDB, 0x6B, 0xE3, 0x27, 0xB7, 0xB1, 0xF5, 0xF9, 0x0B, 0x99, 0xC9, 0xBB, 0x32, 0x3B, 0x97, 0xC4, 0xBA, 0x1C, 0xDB, 0x4A, 0x4C, 0xE7, 0x8D, 0xB0, 0x93, 0xCD, 0x4F, 0x78, 0xE4, 0xA4, 0x72, 0xB6, 0xC0, 0x2D, 0xFB, 0x16, 0x06, 0x89, 0x5C, 0x30, 0x36, 0x7F, 0xF6, 0x9A, 0xF9, 0xF0, 0x36, 0xBF, 0x79, 0x2C, 0xF5, 0xE4, 0x2B, 0x53, 0xC7, 0xBD, 0xE1, 0xE6, 0xE0, 0xDF, 0xE5, 0x60, 0xC9, 0x6D, 0x6E, 0xBB, 0x89, 0xE1, 0xDC, 0x59, 0x85, 0x22, 0x28, 0x2A, 0xB5, 0x7F, 0x81, 0xD3, 0xBD, 0x57, 0x52, 0x42, 0xB9, 0xFD, 0x27, 0xF3, 0x01, 0x53, 0x53, 0xE5, 0xE8, 0xB1, 0x45, 0xEB, 0xC0, 0xDC, 0xC2, 0xC3, 0x8C, 0xAA, 0xF8, 0xF1, 0x01, 0x81, 0xC2, 0xAD, 0x30, 0x01, 0x61, 0xFF, 0xCB, 0xA1, 0xA7, 0xFB, 0x7A, 0x08, 0xE5, 0x5D, 0xB5, 0x41, 0xE1, 0xED, 0xEA, 0xC9, 0xB8, 0x19, 0x8E, 0xA2, 0x72, 0x55, 0x0D, 0x65, 0xC7, 0xA3, 0xF7, 0x4E, 0x73, 0xD5, 0xD9, 0xCA, 0x99, 0x35, 0xE3, 0xFB, 0x47, 0x5C, 0xF8, 0xF3, 0x53, 0xD9, 0x4B, 0xFB, 0x8B, 0xF5, 0xC5, 0xAB, 0x29, 0x6F, 0x50, 0x1C, 0x2B, 0xA2, 0xBE, 0x77, 0x4B, 0xB6, 0x2E, 0x7A, 0x8D, 0xDF, 0x0C, 0x4D, 0xA0, 0x19, 0x45, 0x58, 0x93, 0x12, 0x48, 0x25, 0xD2, 0x70, 0x14, 0xF2, 0x57, 0xBB, 0x84, 0xBA, 0xAF, 0xB5, 0x37 }; static const unsigned char rsaPrimeP_8192_KeyPair[] = { 0xd3, 0xd1, 0xda, 0x94, 0x67, 0x4b, 0x59, 0x9d, 0x50, 0xa6, 0x63, 0x22, 0x50, 0x8a ,0x50, 0x01, 0xcd, 0x0b, 0x36, 0x24, 0xf4, 0xd9, 0x9a, 0xf2, 0xa1, 0xb7, 0x7e, 0xdf, 0x15, 0xa1, 0xfc, 0x50, 0x35, 0x78, 0x48, 0x8a, 0xb4, 0xbc, 0x3a, 0x41, 0x1c, 0x9b, 0x48, 0x74, 0x0f, 0xfd, 0x80, 0xa8, 0x21, 0x4c, 0xd9, 0x8e, 0x67, 0x4f, 0xb0, 0xb0, 0x0e, 0x3d, 0x5b, 0x6c, 0x0f, 0x46, 0x2d, 0xfd, 0xe9, 0x6c, 0x4c, 0xba, 0x95, 0x94, 0x17, 0x15, 0x3b, 0x0e, 0xe2, 0x54, 0x69, 0x86, 0xae, 0x66, 0xe1, 0x59, 0xf0, 0xce, 0x77, 0x1c, 0x3d, 0x31, 0xc3, 0xbe, 0x74, 0x24, 0x13, 0x16, 0x17, 0x18, 0x70, 0xed, 0x4d, 0xcb, 0xb2, 0x19, 0x44, 0x61, 0x2d, 0x41, 0x33, 0x39, 0x77, 0x06, 0xdc, 0x23, 0xc5, 0x51, 0x38, 0x8d, 0x9e, 0x54, 0x22, 0xb1, 0xf2, 0x03, 0x4c, 0x44, 0x6d, 0x3a, 0xdb, 0x37, 0x0c, 0x68, 0x03, 0x5a, 0x15, 0x21, 0xf1, 0x94, 0xd5, 0x3c, 0x75, 0xbb, 0xc0, 0xd0, 0x54, 0x7f, 0xe8, 0x37, 0x5b, 0x12, 0x79, 0x75, 0xb6, 0x7c, 0x52, 0x04, 0xbf, 0xff, 0x83, 0xff, 0x7b, 0xb5, 0x86, 0x84, 0x01, 0x3a, 0xf8, 0x99, 0x15, 0x14, 0x5d, 0x70, 0x0f, 0x69, 0x18, 0x2e, 0xbe, 0x6e, 0xb5, 0xd4, 0xfd, 0xac, 0x2f, 0xba, 0x51, 0xfb, 0xe8, 0x72, 0xa0, 0x87, 0x3b, 0x66, 0xc1, 0x50, 0xe9, 0x7c, 0xfd, 0x24, 0x4e, 0x35, 0x88, 0x21, 0x5f, 0x91, 0xa0, 0x07, 0x44, 0xf9, 0x57, 0xe1, 0x57, 0xa4, 0x6a, 0x87, 0xee, 0xa6, 0xda, 0xa4, 0xf2, 0x0c, 0xe1, 0xda, 0x31, 0xb3, 0xbd, 0xeb, 0xe5, 0x67, 0xdb, 0x05, 0x86, 0x59, 0xbf, 0x6d, 0xed, 0x46, 0x51, 0x6c, 0x80, 0x41, 0xb3, 0xa2, 0x59, 0x41, 0xed, 0xfd, 0x05, 0x79, 0x0a, 0x61, 0x7e, 0xe2, 0x7f, 0xd8, 0x5a, 0x28, 0xa1, 0xcf, 0x91, 0x04, 0xea, 0x51, 0xd6, 0x36, 0x3b, 0xef, 0xa4, 0x34, 0xbb, 0x4f, 0x99, 0x79, 0xe9, 0x88, 0x33, 0x92, 0xc3, 0x48, 0xdc, 0x4e, 0x3b, 0xb7, 0xf1, 0xbc, 0x3a, 0x4e, 0x3f, 0xd9, 0x53, 0x38, 0xd8, 0x06, 0x7e, 0x9a, 0x5e, 0xd4, 0x9e, 0x04, 0x1f, 0xc6, 0x8a, 0x9b, 0x76, 0x34, 0x5f, 0x83, 0x62, 0x55, 0xe2, 0x8f, 0x1a, 0xd0, 0x52, 0xf0, 0xc3, 0x20, 0x09, 0x92, 0x58, 0x81, 0x55, 0xbe, 0x04, 0x09, 0x95, 0x52, 0x70, 0x3f, 0x5c, 0x4f, 0xa0, 0xf5, 0x47, 0x9f, 0x49, 0x81, 0xdc, 0x0f, 0x27, 0xad, 0x5e, 0x20, 0xcc, 0x03, 0xf8, 0x01, 0xc8, 0x5e, 0xa6, 0xb6, 0xef, 0x05, 0xe1, 0xab, 0x1d, 0xdb, 0x3e, 0x4b, 0x16, 0x8d, 0xbb, 0xc4, 0x70, 0xd8, 0xd3, 0x96, 0x65, 0x9e, 0xbc, 0xd4, 0xe6, 0xb0, 0x08, 0x92, 0x47, 0xb5, 0x47, 0x7a, 0xdd, 0xe2, 0x3e, 0x32, 0xb1, 0x42, 0xcb, 0x17, 0xc6, 0x34, 0x9f, 0xae, 0x9d, 0x0b, 0x1a, 0x2a, 0xfe, 0x1b, 0xf4, 0xd1, 0xcd, 0xa7, 0x17, 0x14, 0xc5, 0xc9, 0x65, 0xab, 0x14, 0xd2, 0xc8, 0x52, 0x18, 0x13, 0xb6, 0x0d, 0x52, 0xb5, 0xee, 0xf3, 0x42, 0x33, 0xa8, 0x2c, 0x28, 0xba, 0x9b, 0xd9, 0x8b, 0x84, 0xcb, 0x26, 0xd7, 0xa8, 0x00, 0x64, 0x2a, 0xca, 0x9b, 0xcb, 0x2f, 0xca, 0xef, 0x64, 0xfe, 0x10, 0xd1, 0x99, 0xc2, 0x4a, 0xf9, 0x9d, 0x14, 0x39, 0x7c, 0x17, 0x01, 0x54, 0x1e, 0x11, 0x64, 0xfc, 0x81, 0xc0, 0x7c, 0x8f, 0xb6, 0xb8, 0x3c, 0x28, 0x7c, 0xc9, 0xc1, 0x0c, 0xa1, 0xe5, 0xc5, 0x56, 0x78, 0x32, 0xeb, 0x9e, 0xb4, 0x05, 0x7b, 0x87, 0x75, 0x1b, 0xa3, 0xa0, 0x11, 0xdc, 0xbe, 0xb1, 0xb5, 0xe2, 0xb6, 0xba, 0x26, 0xea, 0x0d, 0x43, 0x70, 0xfe, 0x79, 0x55, 0x6d, 0x1f, 0x55, 0xb1, 0x27, 0x29, 0x3f, 0x6d, 0x9d, 0xa1 }; static const unsigned char rsaPrivateExponentD_1024[] = { 0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c, 0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd, 0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b, 0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55, 0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73, 0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf, 0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde, 0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1 }; static const unsigned char rsaPrivateExponentD_2048[] = { 0x05, 0x6b, 0x04, 0x21, 0x6f, 0xe5, 0xf3, 0x54, 0xac, 0x77, 0x25, 0x0a, 0x4b, 0x6b, 0x0c, 0x85, 0x25, 0xa8, 0x5c, 0x59, 0xb0, 0xbd, 0x80, 0xc5, 0x64, 0x50, 0xa2, 0x2d, 0x5f, 0x43, 0x8e, 0x59, 0x6a, 0x33, 0x3a, 0xa8, 0x75, 0xe2, 0x91, 0xdd, 0x43, 0xf4, 0x8c, 0xb8, 0x8b, 0x9d, 0x5f, 0xc0, 0xd4, 0x99, 0xf9, 0xfc, 0xd1, 0xc3, 0x97, 0xf9, 0xaf, 0xc0, 0x70, 0xcd, 0x9e, 0x39, 0x8c, 0x8d, 0x19, 0xe6, 0x1d, 0xb7, 0xc7, 0x41, 0x0a, 0x6b, 0x26, 0x75, 0xdf, 0xbf, 0x5d, 0x34, 0x5b, 0x80, 0x4d, 0x20, 0x1a, 0xdd, 0x50, 0x2d, 0x5c, 0xe2, 0xdf, 0xcb, 0x09, 0x1c, 0xe9, 0x99, 0x7b, 0xbe, 0xbe, 0x57, 0x30, 0x6f, 0x38, 0x3e, 0x4d, 0x58, 0x81, 0x03, 0xf0, 0x36, 0xf7, 0xe8, 0x5d, 0x19, 0x34, 0xd1, 0x52, 0xa3, 0x23, 0xe4, 0xa8, 0xdb, 0x45, 0x1d, 0x6f, 0x4a, 0x5b, 0x1b, 0x0f, 0x10, 0x2c, 0xc1, 0x50, 0xe0, 0x2f, 0xee, 0xe2, 0xb8, 0x8d, 0xea, 0x4a, 0xd4, 0xc1, 0xba, 0xcc, 0xb2, 0x4d, 0x84, 0x07, 0x2d, 0x14, 0xe1, 0xd2, 0x4a, 0x67, 0x71, 0xf7, 0x40, 0x8e, 0xe3, 0x05, 0x64, 0xfb, 0x86, 0xd4, 0x39, 0x3a, 0x34, 0xbc, 0xf0, 0xb7, 0x88, 0x50, 0x1d, 0x19, 0x33, 0x03, 0xf1, 0x3a, 0x22, 0x84, 0xb0, 0x01, 0xf0, 0xf6, 0x49, 0xea, 0xf7, 0x93, 0x28, 0xd4, 0xac, 0x5c, 0x43, 0x0a, 0xb4, 0x41, 0x49, 0x20, 0xa9, 0x46, 0x0e, 0xd1, 0xb7, 0xbc, 0x40, 0xec, 0x65, 0x3e, 0x87, 0x6d, 0x09, 0xab, 0xc5, 0x09, 0xae, 0x45, 0xb5, 0x25, 0x19, 0x01, 0x16, 0xa0, 0xc2, 0x61, 0x01, 0x84, 0x82, 0x98, 0x50, 0x9c, 0x1c, 0x3b, 0xf3, 0xa4, 0x83, 0xe7, 0x27, 0x40, 0x54, 0xe1, 0x5e, 0x97, 0x07, 0x50, 0x36, 0xe9, 0x89, 0xf6, 0x09, 0x32, 0x80, 0x7b, 0x52, 0x57, 0x75, 0x1e, 0x79 }; static const unsigned char rsaPrivateExponentD_4096[] = { 0x9D, 0x0E, 0xD2, 0x47, 0x6D, 0x75, 0x03, 0x44, 0x57, 0xC1, 0x31, 0x0A, 0x81, 0xC4, 0xBA, 0xB9, 0xF5, 0x22, 0x96, 0xAD, 0xF8, 0x64, 0x88, 0xB2, 0x89, 0x82, 0x93, 0x34, 0xB5, 0x70, 0x03, 0x06, 0x21, 0x99, 0xAD, 0xAF, 0x16, 0x24, 0x84, 0x3A, 0x43, 0x1E, 0x18, 0x8F, 0x31, 0x24, 0x39, 0xC8, 0x93, 0x4C, 0x40, 0x29, 0x14, 0xB5, 0xD3, 0xB8, 0x94, 0x42, 0x10, 0x5C, 0x80, 0x81, 0xDE, 0xAE, 0x90, 0x95, 0x33, 0xF9, 0x79, 0x62, 0x40, 0x64, 0x7B, 0x1F, 0x5C, 0xA4, 0xF9, 0x44, 0x29, 0x75, 0xC4, 0xF6, 0xDC, 0x4E, 0x91, 0xC2, 0x38, 0x62, 0x40, 0x73, 0x99, 0x17, 0x54, 0x0C, 0x4E, 0xC2, 0x13, 0x15, 0xA0, 0x06, 0x79, 0x04, 0x9C, 0x12, 0xD9, 0x60, 0xA3, 0x88, 0x52, 0xA4, 0x41, 0x61, 0xC3, 0xA3, 0x0E, 0x84, 0x8F, 0x7D, 0x2E, 0xD9, 0x5D, 0xB4, 0xDF, 0x35, 0x06, 0xC1, 0x11, 0x0C, 0x64, 0xBC, 0x40, 0xA2, 0xC8, 0x4A, 0x61, 0xC3, 0xAF, 0x1E, 0x20, 0x81, 0xC9, 0x1D, 0xD2, 0xD9, 0x0D, 0x8B, 0xA4, 0xA0, 0xA8, 0x35, 0xB1, 0x15, 0x5F, 0xAD, 0x71, 0x91, 0x0A, 0x9F, 0xE4, 0x77, 0x13, 0x35, 0x6D, 0xFB, 0x83, 0xF3, 0x4C, 0xA5, 0xB2, 0xC2, 0x54, 0x82, 0xAA, 0x79, 0x1A, 0x11, 0xA1, 0x7D, 0xE1, 0x8E, 0x84, 0xD6, 0x4E, 0xD8, 0x50, 0x35, 0x72, 0x84, 0x57, 0x26, 0xC6, 0xA9, 0xEB, 0xDE, 0x00, 0x71, 0x09, 0x21, 0xD9, 0x90, 0x77, 0x44, 0xF3, 0x7A, 0x92, 0xCD, 0x06, 0xE0, 0xC7, 0xE4, 0x50, 0x6D, 0x69, 0xB5, 0xBE, 0x63, 0xC8, 0x80, 0x7A, 0x2A, 0xD4, 0x4D, 0x1D, 0x9A, 0x30, 0xB4, 0xA7, 0xFC, 0x32, 0x6E, 0x94, 0xCA, 0x72, 0x0B, 0x66, 0x5F, 0xAA, 0x1B, 0xE4, 0x1F, 0x9F, 0xB6, 0xA5, 0x00, 0x97, 0x60, 0x7C, 0xCB, 0x6D, 0xD1, 0x9D, 0x40, 0x0C, 0x7B, 0x5B, 0xF7, 0xF1, 0xE0, 0x12, 0x21, 0x2F, 0x7D, 0x9A, 0x04, 0x9A, 0x8B, 0x7E, 0x5E, 0x25, 0x5B, 0xB6, 0xE8, 0x9C, 0x45, 0x49, 0x17, 0x94, 0x1D, 0x73, 0x30, 0x0D, 0xF0, 0xED, 0x80, 0xCD, 0x7A, 0xEE, 0x7E, 0x48, 0xD8, 0x89, 0x6A, 0xCB, 0x8D, 0xAE, 0xE1, 0x0A, 0x80, 0xED, 0x90, 0x9B, 0x47, 0xAE, 0xF9, 0x4C, 0xC5, 0x7E, 0x1B, 0xC7, 0xF3, 0x8B, 0x76, 0xAF, 0xF4, 0xA6, 0x7C, 0x8B, 0x5D, 0xE5, 0xCF, 0xA4, 0x5E, 0x76, 0x98, 0x1C, 0x41, 0xC6, 0x00, 0x28, 0x72, 0x53, 0xBA, 0x7A, 0x29, 0x84, 0xB6, 0xCA, 0x36, 0xA5, 0xFB, 0xE1, 0x8A, 0xDB, 0xC8, 0x3B, 0xD6, 0xDF, 0x1B, 0x32, 0x3D, 0x5F, 0xAE, 0x78, 0xD8, 0xE1, 0x72, 0x92, 0x26, 0xA4, 0x09, 0xDF, 0x3C, 0x34, 0x01, 0x4A, 0x3A, 0x9E, 0x69, 0xEF, 0x7C, 0x57, 0x18, 0x97, 0xDC, 0xBF, 0x5E, 0xF3, 0xDC, 0xBA, 0x54, 0x73, 0x4D, 0x33, 0xD0, 0xBD, 0xD4, 0x9E, 0xAA, 0x49, 0x29, 0x54, 0xF0, 0x99, 0xB9, 0x89, 0x85, 0x71, 0x04, 0xEF, 0xF2, 0x09, 0xCF, 0xAD, 0xB6, 0x74, 0x81, 0xB7, 0x76, 0x29, 0x20, 0x90, 0x59, 0x7C, 0x54, 0xF6, 0xA4, 0xAC, 0x37, 0x16, 0xF4, 0x58, 0xE0, 0x21, 0x00, 0xDD, 0x77, 0xAD, 0x5D, 0xAC, 0x96, 0xD0, 0x66, 0xC0, 0xE0, 0xE4, 0x6F, 0x12, 0x7A, 0x46, 0xE4, 0xE2, 0x74, 0x35, 0x76, 0xD6, 0x41, 0xB1, 0xEB, 0x3F, 0x07, 0xA6, 0x0F, 0x7B, 0xB2, 0x71, 0x76, 0xE9, 0x00, 0x22, 0xDF, 0xA4, 0xE8, 0xB0, 0x4C, 0x86, 0xC8, 0x80, 0x64, 0x53, 0xD6, 0x41, 0x8D, 0x03, 0x75, 0xB7, 0x91, 0x53, 0x55, 0x78, 0xA9, 0x39, 0xE6, 0x19, 0x81, 0xC0, 0x56, 0xF6, 0xA8, 0x38, 0x9D, 0x0B, 0x17, 0x80, 0x9A, 0xD6, 0x4A, 0x34, 0x89, 0x2A, 0x0E, 0x83, 0x3A, 0xCD, 0x25, 0x94, 0x45, 0x7C, 0x71, 0xDF, 0xDB, 0x28, 0x55 }; static const unsigned char rsaPrivateExponentD_8192[] = { 0x49, 0x7c, 0xa6, 0x57, 0x7c, 0x24, 0x49, 0x79, 0x72, 0x3b, 0xf6, 0xf3, 0xe6, 0xf8, 0x97, 0x12, 0xe1, 0xfe, 0xb7, 0x29, 0xfa, 0x1e, 0x85, 0x38, 0x1d, 0x6c, 0xc9, 0x2c, 0x87, 0x68, 0xd4, 0x5f, 0x3b, 0x3d, 0x26, 0x25, 0x97, 0x32, 0xda, 0xdf, 0x0a, 0xa6, 0xb6, 0xf9, 0x9e, 0xa0, 0xb8, 0xc9, 0x58, 0x03, 0xc6, 0xec, 0xf3, 0x7c, 0x16, 0x68, 0x55, 0xa5, 0x27, 0x3b, 0x75, 0x90, 0xc3, 0x80, 0xfa, 0x82, 0x4d, 0x5a, 0x74, 0xce, 0x18, 0xfa, 0xe8, 0x2f, 0x24, 0xf6, 0xe8, 0xf9, 0x43, 0x5b, 0x79, 0x28, 0x49, 0xd0, 0xfc, 0x7b, 0x04, 0x2f, 0xff, 0x92, 0x39, 0xae, 0xeb, 0x99, 0x0d, 0xde, 0xb9, 0xe5, 0xa7, 0x2b, 0x61, 0x9d, 0xcc, 0x29, 0x54, 0x71, 0xfb, 0x30, 0x51, 0x99, 0x7c, 0x0d, 0x5c, 0x62, 0x41, 0x32, 0x58, 0x2f, 0xf0, 0xec, 0xb8, 0x56, 0xae, 0x55, 0x1c, 0x21, 0xef, 0x10, 0x59, 0x0a, 0x9b, 0xfc, 0xec, 0x8d, 0xd5, 0xb3, 0xf2, 0x16, 0x5a, 0x01, 0x8c, 0x40, 0x31, 0xc6, 0xa7, 0x44, 0x5a, 0xca, 0xf1, 0x34, 0x93, 0xf8, 0x73, 0x2d, 0x44, 0xd5, 0x90, 0xf5, 0x8e, 0x2e, 0xf4, 0x34, 0x5b, 0x63, 0x63, 0xc6, 0x84, 0xae, 0x53, 0x62, 0x37, 0x70, 0xad, 0x29, 0x2d, 0xc4, 0xcf, 0xe6, 0xc9, 0xba, 0x7f, 0x68, 0x77, 0x43, 0x1f, 0xfe, 0x59, 0x46, 0x78, 0xbd, 0x36, 0x79, 0xa8, 0xb9, 0xd4, 0xb9, 0x5b, 0x62, 0xca, 0x46, 0x25, 0xbf, 0x2f, 0xe0, 0x70, 0x44, 0x9f, 0x6c, 0xf7, 0xcf, 0xbe, 0x3b, 0x6a, 0x96, 0x51, 0x25, 0x32, 0x44, 0x99, 0xfc, 0x9b, 0xbd, 0x07, 0x72, 0x6e, 0x87, 0x09, 0x98, 0x02, 0x7a, 0xda, 0xd0, 0xe8, 0xf7, 0x49, 0xeb, 0xae, 0x2f, 0x70, 0xb0, 0x5b, 0x58, 0x60, 0x17, 0x41, 0xd0, 0x0c, 0xc8, 0x42, 0xab, 0x60, 0x50, 0xeb, 0x26, 0x68, 0xa3, 0xb4, 0x8e, 0x42, 0xb8, 0x9c, 0x54, 0x4f, 0xa9, 0x2c, 0xdb, 0x8b, 0xc9, 0x14, 0x6e, 0xb3, 0x3e, 0xe6, 0xc6, 0x99, 0x14, 0x82, 0x14, 0x30, 0x86, 0x57, 0xa5, 0x42, 0x23, 0x02, 0x5c, 0xcc, 0xa7, 0x86, 0x27, 0x98, 0x40, 0x1c, 0x36, 0xc4, 0xb9, 0xd4, 0xaf, 0xa6, 0x88, 0x29, 0xce, 0x66, 0xdd, 0x01, 0x4a, 0x69, 0x25, 0x49, 0x87, 0x5b, 0xa7, 0xe1, 0x23, 0x9f, 0x67, 0x9b, 0x88, 0x01, 0x0d, 0x4b, 0xea, 0x74, 0x99, 0xd9, 0x3d, 0x7c, 0x9a, 0xee, 0x55, 0xf3, 0x1e, 0x78, 0xe0, 0x48, 0xe0, 0x0a, 0xbb, 0x2e, 0xc3, 0xe0, 0xdd, 0xe6, 0x7f, 0x88, 0xc5, 0xef, 0xbd, 0x94, 0xd0, 0xbd, 0x63, 0x90, 0x14, 0x75, 0x3f, 0xb6, 0x5c, 0x29, 0x00, 0x79, 0x5e, 0x54, 0xf5, 0x91, 0xcf, 0x73, 0x7e, 0x8e, 0x2e, 0xfd, 0x91, 0x59, 0x37, 0x78, 0xc2, 0x8f, 0x63, 0x57, 0x4b, 0x46, 0xe3, 0x0e, 0x68, 0xd4, 0x8b, 0xb4, 0x04, 0x92, 0x06, 0x2d, 0x80, 0x8b, 0x5a, 0x93, 0xaf, 0x1b, 0x48, 0x25, 0x63, 0x2b, 0xfe, 0x04, 0x2c, 0xdd, 0xed, 0x9b, 0x4b, 0x92, 0x33, 0xa6, 0x7a, 0xc6, 0xfd, 0x8f, 0x56, 0x52, 0xac, 0x06, 0x89, 0x3f, 0xad, 0xea, 0x12, 0x0f, 0x13, 0x9d, 0xde, 0xcd, 0x71, 0x55, 0x0d, 0xa7, 0x4e, 0x71, 0x30, 0x5d, 0x7a, 0xaa, 0x20, 0x6c, 0x1c, 0xa8, 0x26, 0xf3, 0x9d, 0x09, 0xdc, 0xd3, 0xe4, 0xaa, 0xc5, 0xf7, 0xe5, 0xba, 0xc8, 0xb7, 0x53, 0x2d, 0xe7, 0xc2, 0xf5, 0x32, 0x3c, 0xb6, 0x11, 0xda, 0x94, 0x5e, 0x25, 0x66, 0x49, 0xb7, 0x64, 0xec, 0x21, 0xac, 0x98, 0x7d, 0x71, 0xf0, 0x61, 0xe1, 0x42, 0x15, 0xf3, 0xfa, 0x19, 0x76, 0x5a, 0xf8, 0x6b, 0x2a, 0xeb, 0x13, 0xa9, 0x81, 0x4e, 0x2e, 0x58, 0x3e, 0x53, 0x36, 0xdb, 0x2f, 0x97, 0x0c, 0x8b, 0x82, 0x71, 0x86, 0x9a, 0x8f, 0xf4, 0x0b, 0xb2, 0x58, 0x51, 0x98, 0x3c, 0x3a, 0x5d, 0x80, 0x4b, 0x50, 0xc5, 0xaa, 0xdc, 0x7f, 0xbe, 0x21, 0x4c, 0x76, 0xe3, 0xb5, 0x6b, 0x33, 0xa0, 0x6b, 0x6c, 0xfe, 0x53, 0x96, 0x26, 0x08, 0xc3, 0x98, 0x90, 0x39, 0x05, 0x5a, 0xdd, 0x18, 0x45, 0xf7, 0xef, 0xde, 0xc2, 0xe9, 0xce, 0x34, 0x41, 0x52, 0x1d, 0x73, 0x6f, 0x6b, 0x71, 0x4e, 0x18, 0x97, 0x2f, 0x8f, 0xe3, 0xd6, 0xaf, 0x6b, 0xc6, 0xfe, 0xec, 0xd8, 0x48, 0xca, 0x6f, 0xd9, 0x48, 0x34, 0x1e, 0x02, 0x5b, 0xf5, 0xda, 0x3c, 0x3c, 0x8c, 0xce, 0xd6, 0xe3, 0x9f, 0x90, 0x1c, 0x2e, 0x1a, 0xcf, 0xe3, 0x42, 0x5e, 0x7a, 0x1d, 0x42, 0x9b, 0xf3, 0xda, 0x64, 0xf5, 0x8d, 0x14, 0xd3, 0x0b, 0x63, 0x75, 0xfb, 0xf3, 0xe1, 0x99, 0xb8, 0x77, 0x64, 0xf9, 0x82, 0x10, 0x4d, 0x2e, 0x8b, 0x72, 0xb6, 0x48, 0x6a, 0x53, 0x1c, 0x30, 0x8f, 0x5d, 0x3d, 0x63, 0x4c, 0x6e, 0x47, 0xb0, 0x92, 0xc4, 0x2f, 0x07, 0x7f, 0x19, 0xdd, 0x6f, 0xde, 0xa2, 0x47, 0x14, 0x6a, 0xd0, 0xf1, 0xfc, 0x87, 0x91, 0x16, 0x19, 0x7b, 0x7a, 0x80, 0x52, 0xdc, 0xf2, 0x89, 0xe2, 0x15, 0xa1, 0xda, 0x4a, 0xdf, 0x30, 0x40, 0x1f, 0x34, 0xb8, 0xd9, 0xa5, 0x78, 0x23, 0x0e, 0x77, 0x62, 0xc2, 0x60, 0x2a, 0x2d, 0x4e, 0x09, 0x88, 0x07, 0x56, 0x14, 0x65, 0x26, 0x1d, 0xe7, 0x23, 0xfb, 0x27, 0x3a, 0x69, 0xc7, 0x30, 0x92, 0x33, 0xed, 0x68, 0x21, 0xbd, 0x3e, 0x88, 0x95, 0xc1, 0xdc, 0x41, 0x79, 0xbd, 0x90, 0xd7, 0xdd, 0xe3, 0x94, 0xb3, 0x88, 0x3c, 0xa5, 0x6a, 0x34, 0x7d, 0x9e, 0x93, 0x33, 0x30, 0xcd, 0x87, 0xb5, 0x9e, 0x2c, 0x90, 0x74, 0x4f, 0xca, 0xfe, 0xb2, 0x36, 0x95, 0x71, 0x11, 0xf9, 0xc8, 0x11, 0xf9, 0xb5, 0xd6, 0x25, 0xac, 0x2d, 0x25, 0xf4, 0x6f, 0xa4, 0x2c, 0x63, 0x90, 0xf7, 0x5f, 0x28, 0x39, 0x24, 0x5c, 0x46, 0x7c, 0x52, 0x45, 0xdb, 0x7c, 0x9c, 0x54, 0x06, 0xe7, 0x33, 0x80, 0xa5, 0x36, 0x54, 0x82, 0xc3, 0x9f, 0xfc, 0xe9, 0x5f, 0x33, 0xe6, 0x15, 0x98, 0x2e, 0xe8, 0x6e, 0x74, 0x0d, 0x98, 0x61, 0xcd, 0x27, 0x72, 0x95, 0x08, 0x7e, 0x9b, 0xb2, 0xda, 0x01, 0x66, 0xfe, 0x93, 0x20, 0x30, 0x5d, 0x46, 0x22, 0x9a, 0x99, 0xd0, 0xe0, 0x9e, 0x45, 0xfc, 0xd4, 0x8a, 0xa0, 0x63, 0x50, 0x6e, 0xf6, 0x98, 0x76, 0x3c, 0x7f, 0x01, 0x61, 0xaf, 0x97, 0xc2, 0x14, 0x33, 0x72, 0xb4, 0x3d, 0x8d, 0x0c, 0xa6, 0xa5, 0x9e, 0x0d, 0x55, 0x69, 0x53, 0x36, 0x3e, 0x0f, 0xec, 0x88, 0xac, 0x59, 0x7b, 0xf1, 0x91, 0x7b, 0xae, 0x39, 0xbe, 0x6a, 0x0a, 0x39, 0x8c, 0xe6, 0x09, 0xd9, 0xf2, 0x92, 0x06, 0x81, 0x5c, 0xef, 0x25, 0xd0, 0xa4, 0xc7, 0xd2, 0xe9, 0xa1, 0xe7, 0xf9, 0x2b, 0x6c, 0x77, 0x49, 0xd7, 0x78, 0xe6, 0xc1, 0xf5, 0x01, 0x7d, 0xcd, 0x59, 0x67, 0x4c, 0x3e, 0xc0, 0x0b, 0xff, 0x57, 0xd3, 0x63, 0x6b, 0xb5, 0x03, 0x0b, 0x4c, 0x42, 0x98, 0x17, 0x57, 0x27, 0xd0, 0xda, 0x3f, 0x4c, 0x5c, 0x2c, 0x2b, 0x2f, 0x56, 0x5a, 0x23, 0x49, 0xa6, 0xfe, 0x44, 0x58, 0x9d, 0x1e, 0x53, 0xf0, 0x29, 0xae, 0x7c, 0x43, 0xae, 0x05, 0x88, 0xe6, 0xfd, 0x56, 0x98, 0x1b, 0xac, 0x61, 0x1b, 0x13, 0x73, 0x00, 0xe3, 0x69, 0x52, 0xf0, 0xf4, 0xe6, 0xe4, 0x96, 0x04, 0xf3, 0x33, 0xce, 0x2c, 0x60, 0xf8, 0xcc, 0xb1, 0x9d, 0x6a, 0x91, 0xa2, 0xfd, 0x72, 0xd2, 0xd5, 0x0f, 0x2f, 0xe7, 0x23, 0x2b, 0xb5, 0x00, 0x9c, 0x81, 0xe5, 0x32, 0x82, 0xa6, 0x50, 0xa0, 0xd3, 0x64, 0x2e, 0x04, 0xba, 0xa0, 0x70, 0xd7, 0x81 }; static const unsigned char rsaPublicExponentE_1024[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01 }; static const unsigned char rsaPublicExponentE_2048[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01}; static const unsigned char rsaPublicExponentE_4096[] = { 0x01, 0x00, 0x01 }; static const unsigned char rsaPublicExponentE_8192[] = { 0x01, 0x00, 0x01 }; static const unsigned char rsaModulusN_1024[] = { 0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4, 0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab, 0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85, 0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72, 0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97, 0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14, 0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24, 0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb }; static const unsigned char rsaModulusN_2048[] = { 0xae, 0x45, 0xed, 0x56, 0x01, 0xce, 0xc6, 0xb8, 0xcc, 0x05, 0xf8, 0x03, 0x93, 0x5c, 0x67, 0x4d, 0xdb, 0xe0, 0xd7, 0x5c, 0x4c, 0x09, 0xfd, 0x79, 0x51, 0xfc, 0x6b, 0x0c, 0xae, 0xc3, 0x13, 0xa8, 0xdf, 0x39, 0x97, 0x0c, 0x51, 0x8b, 0xff, 0xba, 0x5e, 0xd6, 0x8f, 0x3f, 0x0d, 0x7f, 0x22, 0xa4, 0x02, 0x9d, 0x41, 0x3f, 0x1a, 0xe0, 0x7e, 0x4e, 0xbe, 0x9e, 0x41, 0x77, 0xce, 0x23, 0xe7, 0xf5, 0x40, 0x4b, 0x56, 0x9e, 0x4e, 0xe1, 0xbd, 0xcf, 0x3c, 0x1f, 0xb0, 0x3e, 0xf1, 0x13, 0x80, 0x2d, 0x4f, 0x85, 0x5e, 0xb9, 0xb5, 0x13, 0x4b, 0x5a, 0x7c, 0x80, 0x85, 0xad, 0xca, 0xe6, 0xfa, 0x2f, 0xa1, 0x41, 0x7e, 0xc3, 0x76, 0x3b, 0xe1, 0x71, 0xb0, 0xc6, 0x2b, 0x76, 0x0e, 0xde, 0x23, 0xc1, 0x2a, 0xd9, 0x2b, 0x98, 0x08, 0x84, 0xc6, 0x41, 0xf5, 0xa8, 0xfa, 0xc2, 0x6b, 0xda, 0xd4, 0xa0, 0x33, 0x81, 0xa2, 0x2f, 0xe1, 0xb7, 0x54, 0x88, 0x50, 0x94, 0xc8, 0x25, 0x06, 0xd4, 0x01, 0x9a, 0x53, 0x5a, 0x28, 0x6a, 0xfe, 0xb2, 0x71, 0xbb, 0x9b, 0xa5, 0x92, 0xde, 0x18, 0xdc, 0xf6, 0x00, 0xc2, 0xae, 0xea, 0xe5, 0x6e, 0x02, 0xf7, 0xcf, 0x79, 0xfc, 0x14, 0xcf, 0x3b, 0xdc, 0x7c, 0xd8, 0x4f, 0xeb, 0xbb, 0xf9, 0x50, 0xca, 0x90, 0x30, 0x4b, 0x22, 0x19, 0xa7, 0xaa, 0x06, 0x3a, 0xef, 0xa2, 0xc3, 0xc1, 0x98, 0x0e, 0x56, 0x0c, 0xd6, 0x4a, 0xfe, 0x77, 0x95, 0x85, 0xb6, 0x10, 0x76, 0x57, 0xb9, 0x57, 0x85, 0x7e, 0xfd, 0xe6, 0x01, 0x09, 0x88, 0xab, 0x7d, 0xe4, 0x17, 0xfc, 0x88, 0xd8, 0xf3, 0x84, 0xc4, 0xe6, 0xe7, 0x2c, 0x3f, 0x94, 0x3e, 0x0c, 0x31, 0xc0, 0xc4, 0xa5, 0xcc, 0x36, 0xf8, 0x79, 0xd8, 0xa3, 0xac, 0x9d, 0x7d, 0x59, 0x86, 0x0e, 0xaa, 0xda, 0x6b, 0x83, 0xbb }; static const unsigned char rsaModulusN_4096[] = { 0xB1, 0x11, 0x3F, 0x37, 0xE3, 0x57, 0x7A, 0x0E, 0xFE, 0xC4, 0xEF, 0x49, 0x3C, 0x31, 0x5C, 0x49, 0x1E, 0xF0, 0x7E, 0x45, 0x01, 0x12, 0x85, 0xE1, 0xB3, 0xD3, 0xC0, 0xD8, 0x7E, 0xF5, 0x0E, 0xF8, 0x24, 0x52, 0x74, 0x58, 0x1C, 0x84, 0x7E, 0xE9, 0xD9, 0xA4, 0xE2, 0x0B, 0xDA, 0x95, 0x15, 0x45, 0x0B, 0x3A, 0xA2, 0x84, 0x40, 0x58, 0x1D, 0x33, 0x04, 0xBA, 0x68, 0xA3, 0x4C, 0x67, 0x6A, 0x96, 0x94, 0xF6, 0xA7, 0x30, 0xCB, 0xD3, 0x90, 0x6F, 0xA9, 0x6B, 0x70, 0x8A, 0xB1, 0xC0, 0xC8, 0x15, 0x84, 0xE1, 0x49, 0xEC, 0xC3, 0xA8, 0x56, 0x70, 0xD6, 0xCA, 0xE4, 0x5A, 0x32, 0x1F, 0x7B, 0x74, 0x67, 0xFB, 0x78, 0x0B, 0x7D, 0x65, 0x3E, 0xAD, 0x74, 0xCF, 0x4D, 0x47, 0x4D, 0xAE, 0x97, 0x31, 0x64, 0xC4, 0x9D, 0x64, 0x4C, 0x31, 0xB8, 0x8D, 0xED, 0xFB, 0x02, 0x93, 0x67, 0xC6, 0xEC, 0xDF, 0x28, 0xD9, 0x38, 0xAB, 0x39, 0xC2, 0xF6, 0x82, 0x8F, 0x70, 0xF6, 0x1F, 0x2D, 0x75, 0x8D, 0x3D, 0x57, 0xC8, 0xF1, 0xA1, 0xAE, 0x9E, 0x52, 0xF0, 0x1C, 0x20, 0x66, 0x71, 0xC5, 0x12, 0x64, 0x0F, 0x45, 0x67, 0x06, 0x40, 0xD3, 0x06, 0xF0, 0x4D, 0xFF, 0x91, 0x8C, 0x5E, 0x41, 0x65, 0x66, 0xA4, 0xC7, 0xFC, 0x3E, 0x65, 0x3C, 0xC3, 0x75, 0x7B, 0xF1, 0x2C, 0xF4, 0x08, 0xA8, 0x10, 0x83, 0x7B, 0xFB, 0xDC, 0x2B, 0xF2, 0x36, 0xCE, 0x2C, 0x6D, 0x69, 0xAF, 0x72, 0xB8, 0xF6, 0x79, 0x04, 0x2B, 0x6A, 0xA0, 0x58, 0x6F, 0xD4, 0xF6, 0x3E, 0xF4, 0x8E, 0xEE, 0xB1, 0x01, 0x51, 0x9D, 0xC2, 0x31, 0x80, 0x26, 0xB8, 0xBE, 0xC0, 0x02, 0xD9, 0xAB, 0x46, 0x0F, 0x63, 0x8D, 0xBB, 0x2A, 0x79, 0xE3, 0x34, 0xF9, 0x9C, 0xF8, 0xC4, 0x22, 0x6B, 0xD5, 0x0C, 0x2E, 0x65, 0x13, 0x5A, 0x8D, 0xBE, 0x84, 0xAB, 0x29, 0x88, 0xE2, 0xD5, 0x5C, 0x4C, 0x04, 0xCF, 0x27, 0x39, 0x51, 0x04, 0x02, 0x8C, 0x2C, 0xE3, 0x1F, 0x03, 0x53, 0x62, 0x94, 0x1F, 0xD9, 0x2A, 0x1B, 0xB5, 0x09, 0x2C, 0x3A, 0x14, 0xD2, 0xC3, 0xFD, 0x04, 0x2E, 0x47, 0xEC, 0x98, 0x49, 0x31, 0xD8, 0x35, 0x8E, 0x78, 0x14, 0x67, 0x73, 0xD9, 0x3F, 0xBC, 0xF3, 0xE3, 0x66, 0x74, 0x8D, 0xE5, 0x31, 0x9A, 0x27, 0x23, 0x72, 0x2C, 0xF5, 0x48, 0xDC, 0x56, 0x16, 0x22, 0x8F, 0xE6, 0x78, 0xE3, 0x7B, 0x22, 0xDD, 0x2A, 0xCC, 0x0A, 0xDC, 0xC0, 0xF4, 0x00, 0x67, 0x8F, 0xBD, 0x95, 0x90, 0x6A, 0x1D, 0xC7, 0x90, 0x12, 0x08, 0xAB, 0xF2, 0x51, 0x41, 0xEA, 0xF6, 0xAE, 0x04, 0x5F, 0x47, 0x05, 0xA5, 0xFC, 0x5B, 0x81, 0x58, 0x02, 0x8C, 0xF6, 0xDC, 0x06, 0x35, 0xDB, 0x2D, 0x3B, 0xFA, 0xAF, 0xF5, 0x3B, 0x29, 0x7D, 0xCF, 0x64, 0x03, 0x37, 0x15, 0xDB, 0xC3, 0xC1, 0x2E, 0x84, 0x90, 0x7E, 0x9F, 0x51, 0xC1, 0x47, 0x9E, 0x14, 0x43, 0x70, 0xC6, 0xE7, 0xD2, 0xFB, 0x91, 0x7E, 0x16, 0xD2, 0x82, 0xE0, 0x05, 0x1A, 0xAC, 0x2F, 0xF8, 0xF6, 0xFB, 0x00, 0xDA, 0xB0, 0x9E, 0x99, 0xB4, 0x68, 0x70, 0xAF, 0x90, 0x3F, 0xC6, 0x84, 0x44, 0xDB, 0x6D, 0x0F, 0x9C, 0xE5, 0x54, 0x1B, 0x41, 0x4E, 0x32, 0xB0, 0xE2, 0xCE, 0x68, 0x8E, 0x39, 0x88, 0x01, 0x43, 0x4F, 0x21, 0xE3, 0xC7, 0xB0, 0xEF, 0x52, 0x67, 0x54, 0x0F, 0x00, 0x80, 0x40, 0xBF, 0x0F, 0xFF, 0xFC, 0x93, 0xCF, 0x36, 0x2D, 0x3E, 0x3F, 0xFC, 0x2D, 0xBC, 0x53, 0x50, 0x60, 0x4A, 0xC9, 0x3A, 0x78, 0x6A, 0x5E, 0xA7, 0x39, 0x91, 0xB3, 0x0E, 0x5F, 0x9D, 0x44, 0xBA, 0x47, 0x00, 0x5E, 0x5F, 0x85, 0x48, 0x82, 0xC3, 0x26, 0x1C, 0x6E, 0x9A, 0xB8, 0x55, 0x53, 0xBD, 0x3D }; static const unsigned char rsaModulusN_8192[] = { 0xae, 0x7b, 0xf2, 0x03, 0xd8, 0x1d, 0xe1, 0x26, 0x60, 0x3f, 0x4d, 0x2e, 0xc7, 0xe4, 0x87, 0x5e, 0x55, 0x61, 0x0a, 0xe5, 0x18, 0xc4, 0x9e, 0x07, 0x2f, 0x40, 0xed, 0xaa, 0xb7, 0x21, 0xd0, 0x41, 0x24, 0x4d, 0xfe, 0x94, 0x1c, 0x58, 0xfb, 0x66, 0x17, 0x63, 0x75, 0x53, 0xf3, 0x68, 0x7b, 0xb4, 0xd8, 0x68, 0x4f, 0xd7, 0xe1, 0xa9, 0xb0, 0x50, 0xd6, 0xb4, 0x4e, 0xe0, 0xad, 0x70, 0x53, 0x90, 0x04, 0x7b, 0x76, 0xa1, 0x5c, 0xce, 0xc4, 0x98, 0x7c, 0x98, 0xbf, 0x0a, 0x63, 0x17, 0xa7, 0x4d, 0xbe, 0xc7, 0x35, 0xf8, 0xd2, 0xfb, 0x0d, 0xb2, 0xe8, 0x12, 0xc8, 0x9a, 0x87, 0x39, 0x89, 0x05, 0xb1, 0x47, 0xaa, 0x88, 0xb7, 0x5a, 0x5e, 0xda, 0x7a, 0xf0, 0x5c, 0x06, 0xb8, 0xe1, 0x3d, 0xec, 0xf8, 0xed, 0xda, 0xd5, 0x25, 0x2c, 0xf4, 0x99, 0x27, 0xc8, 0x69, 0xea, 0x3e, 0xf2, 0x9e, 0x52, 0x52, 0xb8, 0x76, 0xef, 0x2e, 0x44, 0xe9, 0xd0, 0x1a, 0x82, 0x83, 0xa9, 0x9e, 0x2f, 0xcd, 0x4f, 0xf9, 0xde, 0x97, 0xd6, 0xb5, 0x85, 0x10, 0xcb, 0xf6, 0x09, 0x4f, 0xd8, 0x22, 0xad, 0xdf, 0xba, 0x92, 0xc1, 0x9d, 0x5a, 0x1f, 0xa9, 0xb6, 0x67, 0x65, 0x14, 0xa2, 0x71, 0xf9, 0x14, 0x69, 0xb6, 0x7c, 0x59, 0xf1, 0x48, 0xa1, 0xa1, 0x33, 0x49, 0x05, 0xa2, 0x56, 0x5f, 0x9f, 0x47, 0xd5, 0x9f, 0x6c, 0xad, 0x14, 0x44, 0x56, 0x41, 0x88, 0x24, 0x81, 0x60, 0x31, 0x8f, 0x7b, 0x15, 0xc1, 0x6d, 0xdc, 0x64, 0x4c, 0x01, 0xef, 0xcd, 0xcd, 0x8a, 0x8a, 0x35, 0xa5, 0xac, 0xfd, 0x2d, 0x58, 0x7e, 0x7c, 0xec, 0xd6, 0xf0, 0xfe, 0x86, 0x29, 0x40, 0x6b, 0x83, 0x98, 0xf7, 0x99, 0x1d, 0xf2, 0x62, 0x03, 0xe6, 0xf3, 0xfe, 0xc1, 0x9c, 0xac, 0x70, 0x1b, 0x7c, 0x9f, 0xb6, 0x80, 0x9d, 0x7b, 0x77, 0x3a, 0x5b, 0x25, 0x1b, 0x59, 0xfd, 0xd9, 0x22, 0x60, 0x76, 0xa5, 0xd6, 0x57, 0x11, 0x99, 0xb2, 0x4b, 0xfd, 0xfe, 0xcd, 0xf6, 0xea, 0xd2, 0x7c, 0x18, 0xd0, 0xbb, 0xf1, 0xde, 0xb8, 0x7b, 0xa7, 0x36, 0x2c, 0xb0, 0x70, 0x60, 0x5f, 0x47, 0x40, 0xf4, 0x58, 0x9f, 0x26, 0xe6, 0xb4, 0x31, 0xe4, 0x6f, 0xe2, 0x6a, 0xf3, 0xf2, 0xfb, 0xfc, 0x5b, 0x74, 0xb0, 0x85, 0x5c, 0xe7, 0x6b, 0x20, 0xc9, 0xf0, 0x02, 0x15, 0x13, 0x2d, 0xb7, 0xd2, 0xab, 0x4f, 0xef, 0xfc, 0xa0, 0xbf, 0xb7, 0x01, 0x81, 0x6a, 0x56, 0x1e, 0xbf, 0x04, 0xa2, 0xa2, 0x94, 0x7f, 0xe4, 0xa0, 0x39, 0x9e, 0x99, 0xa5, 0x7b, 0x59, 0x34, 0x44, 0x13, 0xeb, 0x1c, 0xba, 0x21, 0x5f, 0xaf, 0x67, 0xee, 0x67, 0x5d, 0xda, 0x79, 0x83, 0x95, 0xc8, 0xb0, 0x5b, 0x32, 0x44, 0xc3, 0x4a, 0x0c, 0x57, 0x77, 0x4f, 0xb0, 0xf4, 0x5e, 0x55, 0x1c, 0x08, 0x89, 0x06, 0x50, 0x50, 0x7e, 0x11, 0xcc, 0x9b, 0xfa, 0x92, 0xf0, 0xf6, 0x70, 0xd4, 0x83, 0x41, 0xc8, 0xc7, 0x8a, 0x42, 0x87, 0x6c, 0xa2, 0xf1, 0xaf, 0x10, 0x6b, 0x59, 0x2a, 0x70, 0xe9, 0xce, 0xbe, 0xa2, 0x4c, 0xa0, 0x0b, 0x36, 0xe7, 0x35, 0x50, 0x97, 0x37, 0x3e, 0xa1, 0xc1, 0x01, 0xd7, 0x4a, 0xa6, 0x1e, 0x87, 0x53, 0xeb, 0x6b, 0x91, 0xff, 0xa0, 0x78, 0x79, 0x2e, 0x8e, 0x82, 0x9c, 0xc4, 0x46, 0xf7, 0x95, 0xbc, 0x17, 0x7b, 0x88, 0x1f, 0xc3, 0xb9, 0x30, 0x86, 0x39, 0xe5, 0xd9, 0xf5, 0x10, 0x06, 0x46, 0x12, 0x44, 0xa8, 0x3d, 0x0d, 0x32, 0x02, 0xba, 0x25, 0xa2, 0x95, 0x69, 0x73, 0xf1, 0xe2, 0x6e, 0xca, 0x4d, 0xc3, 0x55, 0x08, 0x19, 0x94, 0xf4, 0xf7, 0xf0, 0xa3, 0x61, 0x33, 0xe3, 0x8a, 0x4b, 0xed, 0x23, 0xb0, 0xf1, 0x9c, 0x61, 0x64, 0xd3, 0x5b, 0xe1, 0x69, 0x4c, 0xdd, 0x2c, 0x5d, 0x00, 0x4c, 0xb5, 0xb8, 0x91, 0x04, 0x89, 0x30, 0x01, 0x2f, 0x8b, 0x1a, 0x3a, 0x13, 0xa5, 0xf4, 0x5b, 0x63, 0x26, 0x16, 0xc0, 0xa2, 0x73, 0x6a, 0xdc, 0x1c, 0xb1, 0xc5, 0x6c, 0x71, 0xab, 0x19, 0x3f, 0xbd, 0x0b, 0x50, 0x95, 0xf7, 0x01, 0x25, 0x33, 0x97, 0xd6, 0x77, 0xa1, 0x04, 0xef, 0xc2, 0x08, 0x07, 0xbf, 0x2d, 0x24, 0xcd, 0x1d, 0x4b, 0x1f, 0xa5, 0xd8, 0x0a, 0x30, 0xe6, 0x3c, 0x2a, 0xe7, 0x29, 0x91, 0x60, 0x43, 0xe4, 0xf5, 0x18, 0x45, 0x18, 0x27, 0x11, 0x06, 0xb8, 0x8b, 0xb5, 0xb9, 0x79, 0x24, 0xf6, 0x6c, 0xbe, 0xe5, 0x81, 0xd8, 0xbe, 0xd2, 0x96, 0x0e, 0x85, 0xd2, 0x36, 0xf6, 0x45, 0x7c, 0xeb, 0x9e, 0xbc, 0x37, 0xd0, 0x6c, 0x20, 0x13, 0xcb, 0xc4, 0x6d, 0x7e, 0xbd, 0x36, 0x05, 0x35, 0x8a, 0x6e, 0xa2, 0xa9, 0x7c, 0xf9, 0x6f, 0xa6, 0xe4, 0x05, 0x53, 0x53, 0x76, 0x75, 0x6c, 0x44, 0x22, 0x35, 0xed, 0xe9, 0xf8, 0xad, 0x0d, 0x16, 0x7d, 0x3c, 0x91, 0x87, 0x55, 0x9d, 0x4e, 0x8f, 0x20, 0x01, 0xdf, 0xd0, 0x00, 0x8a, 0x30, 0x71, 0x84, 0xb8, 0xf0, 0x61, 0x76, 0x7a, 0x9d, 0x87, 0xc6, 0x6f, 0xf9, 0x95, 0x40, 0x21, 0x3b, 0x78, 0x87, 0x94, 0xd0, 0x7c, 0x19, 0x8e, 0x15, 0xd2, 0x9e, 0x8a, 0xeb, 0x39, 0xd6, 0x2a, 0x1c, 0x54, 0x5b, 0xde, 0xda, 0x81, 0x67, 0x32, 0x33, 0xcd, 0xca, 0xea, 0xa8, 0x4f, 0xb8, 0xa9, 0xc7, 0x1e, 0x1f, 0x65, 0xcb, 0xa8, 0x10, 0x52, 0x08, 0xef, 0x76, 0xf4, 0x9c, 0x3d, 0x75, 0x68, 0x41, 0xb5, 0xf9, 0xea, 0x8a, 0xad, 0x53, 0x26, 0x98, 0xe2, 0xbc, 0x73, 0xc7, 0x59, 0x8d, 0x2b, 0x91, 0xf7, 0x78, 0x14, 0x61, 0xd2, 0x53, 0x31, 0xc8, 0xa1, 0xdc, 0xe7, 0xd2, 0x9d, 0x35, 0xe0, 0x9a, 0x14, 0xa7, 0xce, 0x96, 0xc4, 0xf1, 0x05, 0x54, 0x3b, 0x50, 0x35, 0x9b, 0x36, 0xb1, 0x31, 0x40, 0x73, 0x7a, 0xcc, 0xe2, 0x72, 0xa6, 0xdf, 0xf6, 0x82, 0xa4, 0x39, 0x1e, 0xe5, 0xb7, 0x2e, 0xaf, 0x72, 0x6f, 0x5e, 0x37, 0x2b, 0x3c, 0x4f, 0x7e, 0xcb, 0x8c, 0x99, 0x2d, 0x87, 0x8f, 0x6b, 0x21, 0x74, 0xae, 0xdb, 0xfd, 0xa6, 0x3f, 0x2b, 0x5a, 0xbf, 0x72, 0x04, 0x10, 0xf6, 0x7e, 0xdc, 0x6f, 0x01, 0x8b, 0x59, 0xb4, 0x40, 0x1b, 0x24, 0xb0, 0x8f, 0x8e, 0x23, 0x75, 0x5c, 0xc2, 0xa9, 0x5e, 0x89, 0x8b, 0xc2, 0x87, 0x21, 0x0e, 0x2e, 0x15, 0x1b, 0x7d, 0x38, 0x16, 0x77, 0xbd, 0xc3, 0xee, 0xde, 0xa3, 0x4e, 0x26, 0xa6, 0xe3, 0xa0, 0xd5, 0x21, 0x8c, 0xc6, 0x21, 0x4f, 0x37, 0x2b, 0xe1, 0xdd, 0x32, 0x1d, 0x20, 0x17, 0xdf, 0x6d, 0x2f, 0x8c, 0x7b, 0xab, 0x7b, 0x0e, 0x31, 0xda, 0x90, 0xb1, 0x36, 0x4b, 0x1e, 0xe5, 0x9a, 0xae, 0xbd, 0xec, 0x5a, 0x0d, 0x8a, 0x15, 0x15, 0xb3, 0x2e, 0xee, 0x0b, 0xb5, 0x82, 0xbe, 0xba, 0xef, 0x9c, 0x72, 0x07, 0x92, 0xce, 0xef, 0xde, 0x8a, 0x2c, 0xc6, 0xe7, 0x8d, 0x00, 0xe6, 0x64, 0xda, 0x4d, 0x01, 0x3f, 0x63, 0xe1, 0x5d, 0x9b, 0xdc, 0x0c, 0x65, 0x9c, 0xca, 0xb6, 0x4c, 0xa0, 0xcd, 0xe8, 0xbe, 0xbe, 0xf8, 0x11, 0x21, 0xfd, 0x59, 0xe1, 0xee, 0x3f, 0x71, 0xf4, 0x70, 0x2e, 0xb1, 0x23, 0x81, 0x77, 0x45, 0x9e, 0xd3, 0x48, 0xee, 0x2c, 0x5e, 0xcb, 0x85, 0x04, 0x43, 0xe6, 0xa2, 0x7c, 0xb1, 0xec, 0x26, 0xcf, 0x96, 0x10, 0x85, 0x3b, 0x43, 0xfb, 0xf1, 0x7a, 0x5c, 0xa6, 0x9a, 0x4d, 0x86, 0xa4, 0x01, 0x76, 0x4c, 0xa5, 0x0c, 0x5b, 0xd3, 0x07, 0x85, 0x2c, 0x10, 0x01, 0x47, 0xd8, 0xa9, 0x74, 0x39, 0xe4, 0x00, 0xba, 0x86, 0x07 }; static unsigned char expectedPtexttt_1024[] = { 0x5d, 0xec, 0x98, 0xeb, 0x0e, 0x5a, 0xa5, 0xc0, 0xd4, 0xb2, 0xae, 0xa1, 0x00, 0xc7, 0x20, 0xb0, 0x3f, 0xfd, 0x79, 0x43, 0x78, 0xbf, 0xe7, 0x1c, 0x71, 0x9a, 0x7c, 0x14, 0x6d, 0x32, 0xe9, 0x0a, 0xd5, 0xa4, 0x2e, 0x25, 0x6d, 0x05, 0x65, 0x50, 0xcb, 0x6a, 0x21, 0x43, 0xe7, 0x55, 0x6c, 0x6b, 0x81, 0x85, 0x32, 0x23, 0x7c, 0x17, 0x99, 0x06, 0x65, 0xbc, 0xe0, 0x3d, 0x4b, 0x9d, 0xb7, 0xc3, 0x48, 0xd6, 0x2f, 0x4d, 0xae, 0x44, 0x3a, 0xfa, 0x6a, 0xb7, 0x79, 0x9f, 0xe5, 0xf9, 0x4b, 0x14, 0x07, 0xda, 0x97, 0x64, 0x9d, 0xd7, 0xd1, 0xf1, 0x1a, 0x2f, 0xdd, 0x6a, 0xa9, 0xbc, 0xb2, 0x1e, 0x75, 0x37, 0x2f, 0xff, 0xb7, 0x8e, 0xc2, 0x77, 0x4d, 0xc0, 0x4d, 0xb6, 0xb3, 0xc5, 0xda, 0xdd, 0xaf, 0x67, 0x18, 0x6b, 0x79, 0x5e, 0x83, 0xe1, 0xaf, 0x49, 0xc6, 0xd8, 0xa3, 0x48, 0x2d, 0x5b, }; static unsigned char expectedPtexttt_2048[] = { 0x5d, 0xec, 0x98, 0xeb, 0x0e, 0x5a, 0xa5, 0xc0, 0xd4, 0xb2, 0xae, 0xa1, 0x00, 0xc7, 0x20, 0xb0, 0x3f, 0xfd, 0x79, 0x43, 0x78, 0xbf, 0xe7, 0x1c, 0x71, 0x9a, 0x7c, 0x14, 0x6d, 0x32, 0xe9, 0x0a, 0xd5, 0xa4, 0x2e, 0x25, 0x6d, 0x05, 0x65, 0x50, 0xcb, 0x6a, 0x21, 0x43, 0xe7, 0x55, 0x6c, 0x6b, 0x81, 0x85, 0x32, 0x23, 0x7c, 0x17, 0x99, 0x06, 0x65, 0xbc, 0xe0, 0x3d, 0x4b, 0x9d, 0xb7, 0xc3, 0x48, 0xd6, 0x2f, 0x4d, 0xae, 0x44, 0x3a, 0xfa, 0x6a, 0xb7, 0x79, 0x9f, 0xe5, 0xf9, 0x4b, 0x14, 0x07, 0xda, 0x97, 0x64, 0x9d, 0xd7, 0xd1, 0xf1, 0x1a, 0x2f, 0xdd, 0x6a, 0xa9, 0xbc, 0xb2, 0x1e, 0x75, 0x37, 0x2f, 0xff, 0xb7, 0x8e, 0xc2, 0x77, 0x4d, 0xc0, 0x4d, 0xb6, 0xb3, 0xc5, 0xda, 0xdd, 0xaf, 0x67, 0x18, 0x6b, 0x79, 0x5e, 0x83, 0xe1, 0xaf, 0x49, 0xc6, 0xd8, 0xa3, 0x48, 0x2d, 0x5b, 0xbc, 0xac, 0x67, 0x97, 0xf4, 0xde, 0x6a, 0x33, 0x93, 0xed, 0x77, 0xc2, 0xcc, 0xa4, 0xcf, 0xcb, 0x3e, 0xe8, 0x02, 0x3d, 0x7d, 0x73, 0xe3, 0xc3, 0x4c, 0xc4, 0x98, 0x17, 0x55, 0x56, 0x2b, 0xa3, 0x2e, 0xe2, 0xbe, 0x2a, 0x21, 0x03, 0xda, 0xe8, 0x44, 0xd2, 0x45, 0x1b, 0xfc, 0x4f, 0xb3, 0x14, 0x9c, 0xf4, 0xcb, 0x37, 0x23, 0x5f, 0x6a, 0x1e, 0x50, 0x7e, 0xa1, 0x72, 0x25, 0x73, 0xa4, 0x64, 0xe4, 0x9b, 0xe5, 0xe0, 0x75, 0x0f, 0x31, 0x01, 0x82, 0x0a, 0xdf, 0x5d, 0x22, 0xd1, 0x9f, 0x03, 0x95, 0x3c, 0x8b, 0x96, 0xb6, 0xe8, 0x95, 0x37, 0x7a, 0x9c, 0x53, 0x3d, 0xc1, 0xc7, 0xc0, 0xd2, 0x5f, 0x3c, 0x87, 0xce, 0xf4, 0x35, 0xff, 0x6e, 0x7d, 0x01, 0x83, 0x0c, 0x18, 0x06, 0xbb, 0x2a, 0x20, 0x29, 0xad, 0xfb, 0xd9, 0x62, 0xae, 0x49, 0x6c, 0xfa, 0x4c, 0xef, 0x6c, 0x56, 0xba, 0x9a }; static unsigned char expectedPtexttt_4096[] = { 0x5d, 0xec, 0x98, 0xeb, 0x0e, 0x5a, 0xa5, 0xc0, 0xd4, 0xb2, 0xae, 0xa1, 0x00, 0xc7, 0x20, 0xb0, 0x3f, 0xfd, 0x79, 0x43, 0x78, 0xbf, 0xe7, 0x1c, 0x71, 0x9a, 0x7c, 0x14, 0x6d, 0x32, 0xe9, 0x0a, 0xd5, 0xa4, 0x2e, 0x25, 0x6d, 0x05, 0x65, 0x50, 0xcb, 0x6a, 0x21, 0x43, 0xe7, 0x55, 0x6c, 0x6b, 0x81, 0x85, 0x32, 0x23, 0x7c, 0x17, 0x99, 0x06, 0x65, 0xbc, 0xe0, 0x3d, 0x4b, 0x9d, 0xb7, 0xc3, 0x48, 0xd6, 0x2f, 0x4d, 0xae, 0x44, 0x3a, 0xfa, 0x6a, 0xb7, 0x79, 0x9f, 0xe5, 0xf9, 0x4b, 0x14, 0x07, 0xda, 0x97, 0x64, 0x9d, 0xd7, 0xd1, 0xf1, 0x1a, 0x2f, 0xdd, 0x6a, 0xa9, 0xbc, 0xb2, 0x1e, 0x75, 0x37, 0x2f, 0xff, 0xb7, 0x8e, 0xc2, 0x77, 0x4d, 0xc0, 0x4d, 0xb6, 0xb3, 0xc5, 0xda, 0xdd, 0xaf, 0x67, 0x18, 0x6b, 0x79, 0x5e, 0x83, 0xe1, 0xaf, 0x49, 0xc6, 0xd8, 0xa3, 0x48, 0x2d, 0x5b, 0xbc, 0xac, 0x67, 0x97, 0xf4, 0xde, 0x6a, 0x33, 0x93, 0xed, 0x77, 0xc2, 0xcc, 0xa4, 0xcf, 0xcb, 0x3e, 0xe8, 0x02, 0x3d, 0x7d, 0x73, 0xe3, 0xc3, 0x4c, 0xc4, 0x98, 0x17, 0x55, 0x56, 0x2b, 0xa3, 0x2e, 0xe2, 0xbe, 0x2a, 0x21, 0x03, 0xda, 0xe8, 0x44, 0xd2, 0x45, 0x1b, 0xfc, 0x4f, 0xb3, 0x14, 0x9c, 0xf4, 0xcb, 0x37, 0x23, 0x5f, 0x6a, 0x1e, 0x50, 0x7e, 0xa1, 0x72, 0x25, 0x73, 0xa4, 0x64, 0xe4, 0x9b, 0xe5, 0xe0, 0x75, 0x0f, 0x31, 0x01, 0x82, 0x0a, 0xdf, 0x5d, 0x22, 0xd1, 0x9f, 0x03, 0x95, 0x3c, 0x8b, 0x96, 0xb6, 0xe8, 0x95, 0x37, 0x7a, 0x9c, 0x53, 0x3d, 0xc1, 0xc7, 0xc0, 0xd2, 0x5f, 0x3c, 0x87, 0xce, 0xf4, 0x35, 0xff, 0x6e, 0x7d, 0x01, 0x83, 0x0c, 0x18, 0x06, 0xbb, 0x2a, 0x20, 0x29, 0xad, 0xfb, 0xd9, 0x62, 0xae, 0x49, 0x6c, 0xfa, 0x4c, 0xef, 0x6c, 0x56, 0xba, 0x9a, 0x77, 0x92, 0x45, 0xbf, 0x27, 0x73, 0x5f, 0x1f, 0x9d, 0x41, 0xa1, 0x7c, 0x1c, 0x7b, 0xff, 0x26, 0xe5, 0xda, 0x43, 0x08, 0x99, 0x7b, 0xb6, 0x30, 0xf5, 0x0f, 0xeb, 0x50, 0x46, 0xee, 0x92, 0x21, 0x86, 0xbd, 0xab, 0x78, 0xcf, 0xd4, 0xee, 0xb4, 0x09, 0x0d, 0x5a, 0x89, 0x8d, 0xe8, 0x4c, 0x23, 0xde, 0x67, 0x7f, 0xec, 0x12, 0xc5, 0xa5, 0xfb, 0xaa, 0xa7, 0x57, 0x49, 0xb5, 0x4b, 0xc0, 0x82, 0x63, 0x05, 0xab, 0x71, 0xec, 0x56, 0xaa, 0x7c, 0x43, 0xe8, 0xcb, 0xf1, 0x9c, 0xef, 0x13, 0xad, 0x29, 0x9c, 0x8c, 0xf9, 0x5d, 0x2b, 0xe8, 0x5a, 0x73, 0x44, 0x6e, 0x11, 0x9d, 0x6a, 0x51, 0xc2, 0xeb, 0x56, 0x67, 0xe2, 0xf1, 0xc7, 0xb7, 0x74, 0x7c, 0xc5, 0x37, 0x68, 0xbe, 0xb1, 0xd4, 0xea, 0x43, 0x5b, 0xfe, 0x6a, 0xea, 0xb8, 0xbf, 0xa8, 0xa7, 0xa9, 0x20, 0x3d, 0xcc, 0xfa, 0xb6, 0xb8, 0x63, 0x79, 0xf0, 0x10, 0x25, 0xfe, 0xae, 0xf1, 0xf2, 0xb1, 0x96, 0xf5, 0x53, 0x8b, 0x7e, 0x6d, 0x4e, 0x68, 0x67, 0xf1, 0x57, 0x81, 0x63, 0xde, 0x3c, 0xb0, 0xdd, 0xa1, 0x8e, 0xc1, 0xa9, 0x37, 0xfa, 0xfd, 0xaa, 0xdb, 0x49, 0x3a, 0xd1, 0x19, 0x92, 0xda, 0x60, 0x00, 0xf7, 0x04, 0x50, 0x83, 0x5a, 0xdf, 0xf3, 0xdb, 0xda, 0x4c, 0x38, 0xe4, 0x46, 0xf0, 0xe6, 0x5f, 0x9e, 0x50, 0x0f, 0x38, 0x7a, 0xd1, 0x28, 0x52, 0xdd, 0x5f, 0xfd, 0xe4, 0xab, 0xa3, 0x9b, 0x15, 0x7b, 0x92, 0xfe, 0x73, 0x3c, 0x45, 0x1a, 0x73, 0x4d, 0xa8, 0xf5, 0x74, 0x26, 0x81, 0xa5, 0x96, 0x7f, 0x65, 0x85, 0xe6, 0x1f, 0x47, 0xd4, 0x17, 0x20, 0xa0, 0x8b, 0x61, 0xfb, 0x3e, 0xa2, 0x86, 0x26, 0x27, 0x8a, 0x4b, 0xaf, 0x41, 0x67, 0x54, 0xd9, 0x80, 0xfc, 0xbd, 0xc3, 0x7b, 0x81, 0x7c, 0x33, 0x2f, 0x5d, 0x82 }; static unsigned char expectedPtexttt_8192[] = { 0x5d, 0xec, 0x98, 0xeb, 0x0e, 0x5a, 0xa5, 0xc0, 0xd4, 0xb2, 0xae, 0xa1, 0x00, 0xc7, 0x20, 0xb0, 0x3f, 0xfd, 0x79, 0x43, 0x78, 0xbf, 0xe7, 0x1c, 0x71, 0x9a, 0x7c, 0x14, 0x6d, 0x32, 0xe9, 0x0a, 0xd5, 0xa4, 0x2e, 0x25, 0x6d, 0x05, 0x65, 0x50, 0xcb, 0x6a, 0x21, 0x43, 0xe7, 0x55, 0x6c, 0x6b, 0x81, 0x85, 0x32, 0x23, 0x7c, 0x17, 0x99, 0x06, 0x65, 0xbc, 0xe0, 0x3d, 0x4b, 0x9d, 0xb7, 0xc3, 0x48, 0xd6, 0x2f, 0x4d, 0xae, 0x44, 0x3a, 0xfa, 0x6a, 0xb7, 0x79, 0x9f, 0xe5, 0xf9, 0x4b, 0x14, 0x07, 0xda, 0x97, 0x64, 0x9d, 0xd7, 0xd1, 0xf1, 0x1a, 0x2f, 0xdd, 0x6a, 0xa9, 0xbc, 0xb2, 0x1e, 0x75, 0x37, 0x2f, 0xff, 0xb7, 0x8e, 0xc2, 0x77, 0x4d, 0xc0, 0x4d, 0xb6, 0xb3, 0xc5, 0xda, 0xdd, 0xaf, 0x67, 0x18, 0x6b, 0x79, 0x5e, 0x83, 0xe1, 0xaf, 0x49, 0xc6, 0xd8, 0xa3, 0x48, 0x2d, 0x5b, 0xbc, 0xac, 0x67, 0x97, 0xf4, 0xde, 0x6a, 0x33, 0x93, 0xed, 0x77, 0xc2, 0xcc, 0xa4, 0xcf, 0xcb, 0x3e, 0xe8, 0x02, 0x3d, 0x7d, 0x73, 0xe3, 0xc3, 0x4c, 0xc4, 0x98, 0x17, 0x55, 0x56, 0x2b, 0xa3, 0x2e, 0xe2, 0xbe, 0x2a, 0x21, 0x03, 0xda, 0xe8, 0x44, 0xd2, 0x45, 0x1b, 0xfc, 0x4f, 0xb3, 0x14, 0x9c, 0xf4, 0xcb, 0x37, 0x23, 0x5f, 0x6a, 0x1e, 0x50, 0x7e, 0xa1, 0x72, 0x25, 0x73, 0xa4, 0x64, 0xe4, 0x9b, 0xe5, 0xe0, 0x75, 0x0f, 0x31, 0x01, 0x82, 0x0a, 0xdf, 0x5d, 0x22, 0xd1, 0x9f, 0x03, 0x95, 0x3c, 0x8b, 0x96, 0xb6, 0xe8, 0x95, 0x37, 0x7a, 0x9c, 0x53, 0x3d, 0xc1, 0xc7, 0xc0, 0xd2, 0x5f, 0x3c, 0x87, 0xce, 0xf4, 0x35, 0xff, 0x6e, 0x7d, 0x01, 0x83, 0x0c, 0x18, 0x06, 0xbb, 0x2a, 0x20, 0x29, 0xad, 0xfb, 0xd9, 0x62, 0xae, 0x49, 0x6c, 0xfa, 0x4c, 0xef, 0x6c, 0x56, 0xba, 0x9a, 0x77, 0x92, 0x45, 0xbf, 0x27, 0x73, 0x5f, 0x1f, 0x9d, 0x41, 0xa1, 0x7c, 0x1c, 0x7b, 0xff, 0x26, 0xe5, 0xda, 0x43, 0x08, 0x99, 0x7b, 0xb6, 0x30, 0xf5, 0x0f, 0xeb, 0x50, 0x46, 0xee, 0x92, 0x21, 0x86, 0xbd, 0xab, 0x78, 0xcf, 0xd4, 0xee, 0xb4, 0x09, 0x0d, 0x5a, 0x89, 0x8d, 0xe8, 0x4c, 0x23, 0xde, 0x67, 0x7f, 0xec, 0x12, 0xc5, 0xa5, 0xfb, 0xaa, 0xa7, 0x57, 0x49, 0xb5, 0x4b, 0xc0, 0x82, 0x63, 0x05, 0xab, 0x71, 0xec, 0x56, 0xaa, 0x7c, 0x43, 0xe8, 0xcb, 0xf1, 0x9c, 0xef, 0x13, 0xad, 0x29, 0x9c, 0x8c, 0xf9, 0x5d, 0x2b, 0xe8, 0x5a, 0x73, 0x44, 0x6e, 0x11, 0x9d, 0x6a, 0x51, 0xc2, 0xeb, 0x56, 0x67, 0xe2, 0xf1, 0xc7, 0xb7, 0x74, 0x7c, 0xc5, 0x37, 0x68, 0xbe, 0xb1, 0xd4, 0xea, 0x43, 0x5b, 0xfe, 0x6a, 0xea, 0xb8, 0xbf, 0xa8, 0xa7, 0xa9, 0x20, 0x3d, 0xcc, 0xfa, 0xb6, 0xb8, 0x63, 0x79, 0xf0, 0x10, 0x25, 0xfe, 0xae, 0xf1, 0xf2, 0xb1, 0x96, 0xf5, 0x53, 0x8b, 0x7e, 0x6d, 0x4e, 0x68, 0x67, 0xf1, 0x57, 0x81, 0x63, 0xde, 0x3c, 0xb0, 0xdd, 0xa1, 0x8e, 0xc1, 0xa9, 0x37, 0xfa, 0xfd, 0xaa, 0xdb, 0x49, 0x3a, 0xd1, 0x19, 0x92, 0xda, 0x60, 0x00, 0xf7, 0x04, 0x50, 0x83, 0x5a, 0xdf, 0xf3, 0xdb, 0xda, 0x4c, 0x38, 0xe4, 0x46, 0xf0, 0xe6, 0x5f, 0x9e, 0x50, 0x0f, 0x38, 0x7a, 0xd1, 0x28, 0x52, 0xdd, 0x5f, 0xfd, 0xe4, 0xab, 0xa3, 0x9b, 0x15, 0x7b, 0x92, 0xfe, 0x73, 0x3c, 0x45, 0x1a, 0x73, 0x4d, 0xa8, 0xf5, 0x74, 0x26, 0x81, 0xa5, 0x96, 0x7f, 0x65, 0x85, 0xe6, 0x1f, 0x47, 0xd4, 0x17, 0x20, 0xa0, 0x8b, 0x61, 0xfb, 0x3e, 0xa2, 0x86, 0x26, 0x27, 0x8a, 0x4b, 0xaf, 0x41, 0x67, 0x54, 0xd9, 0x80, 0xfc, 0xbd, 0xc3, 0x7b, 0x81, 0x7c, 0x33, 0x2f, 0x5d, 0x82, 0x77, 0xc2, 0xcc, 0xa4, 0xcf, 0xcb, 0x3e, 0xe8, 0x02, 0x3d, 0x7d, 0x73, 0xe3, 0xc3, 0x4c, 0xc4, 0x98, 0x17, 0x55, 0x56, 0x2b, 0xa3, 0x2e, 0xe2, 0xbe, 0x2a, 0x21, 0x03, 0xda, 0xe8, 0x44, 0xd2, 0x45, 0x1b, 0xfc, 0x4f, 0xb3, 0x14, 0x9c, 0xf4, 0xcb, 0x37, 0x23, 0x5f, 0x6a, 0x1e, 0x50, 0x7e, 0xa1, 0x72, 0x25, 0x73, 0x29, 0x9c, 0x8c, 0xf9, 0x5d, 0x2b, 0xe8, 0x5a, 0x73, 0x44, 0x6e, 0x11, 0x9d, 0x6a, 0x51, 0xc2, 0xeb, 0x56, 0x67, 0xe2, 0xf1, 0xc7, 0xb7, 0x74, 0x7c, 0xc5, 0x37, 0x68, 0xbe, 0xb1, 0xd4, 0xea, 0x43, 0x5b, 0xfe, 0x6a, 0xea, 0xb8, 0xbf, 0xa8, 0xa7, 0xa9, 0x20, 0x3d, 0xcc, 0xfa, 0xb6, 0xb8, 0x63, 0x79, 0xf0, 0x10, 0x25, 0xfe, 0xae, 0xf1, 0xf2, 0xb1, 0x96, 0xf5, 0x53, 0x8b, 0x7e, 0x6d, 0x4e, 0x68, 0x67, 0xf1, 0x57, 0x81, 0x63, 0xde, 0x3c, 0xb0, 0xdd, 0xa1, 0x8e, 0xc1, 0xa9, 0x37, 0xfa, 0xfd, 0xaa, 0xdb, 0x49, 0x3a, 0xd1, 0x19, 0x92, 0xda, 0x60, 0x00, 0xf7, 0x04, 0x50, 0x83, 0xea, 0xb8, 0xbf, 0xa8, 0xa7, 0xa9, 0x20, 0x3d, 0xcc, 0xfa, 0xb6, 0xb8, 0x63, 0x79, 0xf0, 0x10, 0x25, 0xfe, 0xae, 0xf1, 0xf2, 0xb1, 0x96, 0xf5, 0x53, 0x8b, 0x7e, 0x6d, 0x4e, 0x68, 0x67, 0xf1, 0x57, 0x81, 0x63, 0xde, 0x3c, 0xb0, 0xdd, 0xa1, 0x8e, 0xc1, 0xa9, 0x37, 0xfa, 0xfd, 0xaa, 0xdb, 0x49, 0x3a, 0xd1, 0x19, 0x92, 0xda, 0x60, 0x00, 0xf7, 0x04, 0x50, 0x83, 0x44, 0xd2, 0x45, 0x1b, 0xfc, 0x4f, 0xb3, 0x14, 0x9c, 0xf4, 0xcb, 0x37, 0x23, 0x5f, 0x6a, 0x1e, 0x50, 0x7e, 0xa1, 0x72, 0x25, 0x73, 0xa4, 0x64, 0xe4, 0x9b, 0xe5, 0xe0, 0x75, 0x0f, 0x31, 0x01, 0x82, 0x0a, 0xdf, 0x5d, 0x22, 0xd1, 0x9f, 0x03, 0x95, 0x3c, 0x8b, 0x96, 0xb6, 0xe8, 0x95, 0x37, 0x1f, 0x47, 0xd4, 0x17, 0x20, 0xa0, 0x8b, 0x61, 0xfb, 0x3e, 0xa2, 0x86, 0x26, 0x27, 0x8a, 0x4b, 0xaf, 0x41, 0x67, 0x54, 0xd9, 0x80, 0xfc, 0xbd, 0xc3, 0x7b, 0x81, 0x7c, 0x33, 0x2f, 0x5d, 0x82, 0x77, 0xc2, 0xcc, 0xa4, 0x9d, 0x41, 0xa1, 0x7c, 0x1c, 0x7b, 0xff, 0x26, 0xe5, 0xda, 0x43, 0x08, 0x99, 0x7b, 0xb6, 0x30, 0xf5, 0x0f, 0xeb, 0x50, 0x46, 0xee, 0x92, 0x21, 0x86, 0xbd, 0xab, 0x78, 0xcf, 0xd4, 0xee, 0xb4, 0x09, 0x0d, 0x5a, 0x89, 0x8d, 0xe8, 0x4c, 0x23, 0xde, 0x67, 0x7f, 0xec, 0x12, 0xc5, 0xa5, 0xfb, 0x7c, 0xc5, 0x37, 0x68, 0xbe, 0xb1, 0xd4, 0xea, 0x43, 0x5b, 0xfe, 0x6a, 0xea, 0xb8, 0xbf, 0xa8, 0xa7, 0xa9, 0x20, 0x3d, 0xcc, 0xfa, 0xb6, 0xb8, 0x63, 0x79, 0xf0, 0x10, 0x25, 0xfe, 0xae, 0xf1, 0xf2, 0xb1, 0x96, 0xf5, 0x53, 0x8b, 0x7e, 0x6d, 0x4e, 0x68, 0x67, 0xf1, 0x57, 0x81, 0x63, 0xde, 0x5a, 0xdf, 0xf3, 0xdb, 0xda, 0x4c, 0x38, 0xe4, 0x46, 0xf0, 0xe6, 0x5f, 0x9e, 0x50, 0x0f, 0x38, 0x7a, 0xd1, 0x28, 0x52, 0xdd, 0x5f, 0xfd, 0xe4, 0xab, 0xa3, 0x9b, 0x15, 0x7b, 0x92, 0xfe, 0x73, 0x3c, 0x45, 0x1a, 0x73, 0x4d, 0xa8, 0xf5, 0x74, 0x26, 0x81, 0xa5, 0x96, 0x7f, 0x65, 0x85, 0xe6, 0x1f, 0x47, 0xd4, 0x17, 0x20, 0xa0, 0x8b, 0x61, 0xfb, 0x3e, 0xa2, 0x86, 0x9d, 0x41, 0xa1, 0x7c, 0x1c, 0x7b, 0xff, 0x26, 0xe5, 0xda, 0x43, 0x08, 0x99, 0x7b, 0xb6, 0x30, 0xf5, 0x0f, 0xeb, 0x50, 0x46, 0xee, 0x92, 0x21, 0x86, 0xbd, 0xab, 0x78, 0xcf, 0xd4, 0xee, 0xb4, 0x09, 0x0d, 0x5a, 0x89, 0x8d, 0xe8, 0x4c, 0x23, 0xde, 0x67, 0x7f, 0xec, 0x12, 0xc5, 0xa5, 0xfb, 0x22, 0xd1, 0x9f, 0x03, 0x95, 0x3c, 0x8b, 0x96, 0xb6, 0xe8, 0x95, 0x37, 0x1f, 0x47, 0xd4, 0x17 }; #ifdef QAT_OPENSSL_PROVIDER static unsigned char test1024[] = { 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05, 0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5, 0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55, 0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9, 0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96, 0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37, 0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd, 0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24, 0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23, 0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37, 0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94, 0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b, 0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f, 0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0, 0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f, 0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f, 0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88, 0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba, 0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c, 0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43, 0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc, 0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee, 0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d, 0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed, 0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20, 0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c, 0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3, 0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02, 0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4, 0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a, 0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc, 0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2, 0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04, 0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52, 0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38, 0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7, 0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20, 0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4, 0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02, 0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b, 0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52, 0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde, 0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f, 0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66, 0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46, 0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad, 0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80, 0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf, 0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84, 0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60, 0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c, 0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b, 0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c, 0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7, 0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53, 0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9, 0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba, 0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14, 0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45, }; static unsigned char test2048[] = { 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f, 0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27, 0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f, 0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde, 0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a, 0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32, 0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f, 0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab, 0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33, 0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f, 0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4, 0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e, 0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29, 0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b, 0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0, 0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34, 0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1, 0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15, 0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c, 0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66, 0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2, 0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27, 0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15, 0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20, 0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1, 0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3, 0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa, 0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c, 0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac, 0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40, 0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3, 0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d, 0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01, 0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4, 0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5, 0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9, 0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6, 0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3, 0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e, 0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46, 0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53, 0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59, 0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab, 0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48, 0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca, 0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35, 0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9, 0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b, 0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f, 0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0, 0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33, 0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7, 0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50, 0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c, 0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8, 0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56, 0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f, 0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04, 0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14, 0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c, 0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06, 0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c, 0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28, 0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80, 0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1, 0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc, 0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63, 0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61, 0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94, 0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95, 0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4, 0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84, 0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94, 0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e, 0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11, 0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1, 0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb, 0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80, 0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5, 0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a, 0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29, 0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72, 0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54, 0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8, 0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d, 0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90, 0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27, 0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28, 0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82, 0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90, 0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81, 0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf, 0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01, 0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16, 0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5, 0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3, 0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc, 0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1, 0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8, 0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31, 0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c, 0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b, 0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32, 0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02, 0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9, 0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84, 0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04, 0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a, 0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd, 0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43, 0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46, 0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41, 0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5, 0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b, 0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55, 0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d, 0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4, 0x95, }; static unsigned char test3072[] = { 0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x81, 0x00, 0xbc, 0x3b, 0x23, 0xc0, 0x33, 0xa7, 0x8b, 0xaa, 0xca, 0xa3, 0x8c, 0x94, 0xf2, 0x4c, 0x52, 0x08, 0x85, 0x80, 0xfc, 0x36, 0x15, 0xfa, 0x03, 0x06, 0xb6, 0xd6, 0x3f, 0x60, 0x8a, 0x89, 0x0d, 0xba, 0x1a, 0x51, 0x0b, 0x12, 0xea, 0x71, 0x77, 0xf6, 0x3a, 0x30, 0x21, 0x3d, 0x24, 0xf8, 0x2e, 0xd0, 0x17, 0x3a, 0x85, 0x94, 0x25, 0x42, 0x89, 0xff, 0x6a, 0x68, 0xdf, 0x1f, 0x86, 0xae, 0xa5, 0xbb, 0x9a, 0x79, 0xf6, 0x69, 0x94, 0xfe, 0xde, 0xfe, 0xce, 0x1b, 0x2e, 0xae, 0x1d, 0x91, 0xcb, 0xb9, 0xf1, 0x2d, 0xd8, 0x00, 0x82, 0x51, 0x8e, 0xf9, 0xfd, 0xac, 0xf1, 0x0e, 0x7f, 0xb7, 0x95, 0x85, 0x35, 0xf9, 0xcb, 0xbe, 0x5f, 0xd3, 0x58, 0xe3, 0xa1, 0x54, 0x9e, 0x30, 0xb1, 0x8d, 0x01, 0x97, 0x82, 0x06, 0x8e, 0x77, 0xfb, 0xce, 0x50, 0x2f, 0xbf, 0xf1, 0xff, 0x57, 0x0a, 0x42, 0x03, 0xfd, 0x0e, 0xba, 0x1e, 0xca, 0x85, 0xc1, 0x9b, 0xa5, 0x9d, 0x09, 0x0e, 0xe9, 0xbb, 0xc5, 0x73, 0x47, 0x0d, 0x39, 0x3c, 0x64, 0x06, 0x9a, 0x79, 0x3f, 0x50, 0x87, 0x9c, 0x18, 0x2d, 0x62, 0x01, 0xfc, 0xed, 0xc1, 0x58, 0x28, 0x21, 0x94, 0x1e, 0xf9, 0x2d, 0x96, 0x4f, 0xd0, 0xbc, 0xf1, 0xe0, 0x8a, 0xfa, 0x4d, 0xb6, 0x78, 0x4a, 0xde, 0x17, 0x59, 0xb0, 0x22, 0xa0, 0x9a, 0xd3, 0x70, 0xb6, 0xc2, 0xbe, 0xbc, 0x96, 0xca, 0x41, 0x5f, 0x58, 0x4e, 0xce, 0xef, 0x64, 0x45, 0xdd, 0x3f, 0x81, 0x92, 0xcc, 0x40, 0x79, 0xfc, 0x19, 0xe2, 0xbc, 0x77, 0x2f, 0x43, 0xfb, 0x8e, 0xad, 0x82, 0x4a, 0x0b, 0xb1, 0xbc, 0x09, 0x8a, 0x80, 0xc3, 0x0f, 0xef, 0xd2, 0x06, 0xd3, 0x4b, 0x0c, 0x7f, 0xae, 0x60, 0x3f, 0x2e, 0x52, 0xb4, 0xe4, 0xc2, 0x5c, 0xa6, 0x71, 0xc0, 0x13, 0x9c, 0xca, 0xa6, 0x0d, 0x13, 0xd7, 0xb7, 0x14, 0x94, 0x3f, 0x0d, 0x8b, 0x06, 0x70, 0x2f, 0x15, 0x82, 0x8d, 0x47, 0x45, 0xa6, 0x00, 0x8a, 0x14, 0x91, 0xde, 0x2f, 0x50, 0x17, 0xe3, 0x1d, 0x34, 0x29, 0x8c, 0xe4, 0x57, 0x74, 0x2a, 0x3a, 0x82, 0x65, 0x26, 0xf7, 0x8d, 0xcc, 0x1b, 0x8f, 0xaf, 0xe5, 0x85, 0xe5, 0xbe, 0x85, 0xd6, 0xb7, 0x04, 0xe8, 0xf5, 0xd4, 0x74, 0xe2, 0x54, 0x14, 0xdd, 0x58, 0xcf, 0x1f, 0x11, 0x8a, 0x9f, 0x82, 0xa2, 0x01, 0xf9, 0xc2, 0xdf, 0x7b, 0x84, 0xb1, 0xd8, 0x5b, 0x70, 0xbb, 0x24, 0xe7, 0xd0, 0x2a, 0x75, 0x3d, 0x55, 0xac, 0x45, 0xe9, 0xab, 0xc6, 0x84, 0x8a, 0xe7, 0x6d, 0x26, 0x12, 0x89, 0xb5, 0x67, 0xe8, 0x46, 0x9d, 0x46, 0x1a, 0xfa, 0x2d, 0xc0, 0x5b, 0x60, 0x46, 0x8b, 0xb7, 0x32, 0x03, 0xff, 0x75, 0xee, 0x9f, 0x3c, 0xdd, 0xb6, 0x35, 0x4e, 0x82, 0xbd, 0x99, 0x73, 0x51, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x80, 0x42, 0xee, 0xa4, 0x9f, 0xcb, 0xbe, 0x60, 0x23, 0xb3, 0x3a, 0xc4, 0xda, 0x91, 0xee, 0x21, 0x9d, 0x76, 0x1b, 0x8f, 0x93, 0x8b, 0xed, 0x02, 0xf6, 0x78, 0x3d, 0x66, 0xfb, 0xe5, 0x47, 0x26, 0xe2, 0x6e, 0x49, 0x33, 0x2e, 0xde, 0xbe, 0xca, 0x71, 0x7b, 0xef, 0x71, 0x62, 0x54, 0xab, 0x0b, 0xba, 0x63, 0x08, 0x24, 0x47, 0xb1, 0x98, 0x1f, 0x89, 0xfb, 0x44, 0x9f, 0x52, 0x8e, 0x89, 0xbb, 0xd5, 0x21, 0xf1, 0x0c, 0x76, 0x2e, 0xcd, 0x12, 0x6e, 0x78, 0xcb, 0xa1, 0xa5, 0xb8, 0x4e, 0x07, 0xab, 0x6e, 0xdf, 0x66, 0x57, 0x87, 0xff, 0x88, 0x5f, 0xcc, 0x9c, 0x9a, 0x7b, 0x15, 0x5f, 0x2a, 0x83, 0xdb, 0xd5, 0x9f, 0x65, 0x6a, 0x9d, 0xb4, 0x95, 0xfc, 0xe0, 0x22, 0x00, 0x1e, 0xa2, 0x8d, 0x56, 0x5a, 0x9e, 0x0a, 0x3b, 0x10, 0x07, 0x24, 0xec, 0x55, 0xcc, 0xaf, 0x87, 0x3b, 0xd6, 0x8d, 0xa4, 0x86, 0x80, 0x18, 0x42, 0xdb, 0x9d, 0x24, 0xc3, 0x97, 0x3b, 0x89, 0x5a, 0x03, 0xb3, 0x0a, 0x72, 0xd1, 0x78, 0xf0, 0xc8, 0x80, 0xb0, 0x9d, 0x3c, 0xae, 0x5e, 0x0a, 0x5b, 0x6e, 0x87, 0xd3, 0x3d, 0x25, 0x2e, 0x03, 0x33, 0x01, 0xfd, 0xb1, 0xa5, 0xd9, 0x58, 0x01, 0xb9, 0xaf, 0xf6, 0x32, 0x6a, 0x38, 0xe7, 0x39, 0x63, 0x3c, 0xfc, 0x0c, 0x41, 0x90, 0x28, 0x40, 0x03, 0xcd, 0xfb, 0xde, 0x80, 0x74, 0x21, 0xaa, 0xae, 0x58, 0xe9, 0x97, 0x18, 0x85, 0x58, 0x3d, 0x2b, 0xd6, 0x61, 0xf6, 0xe8, 0xbc, 0x6d, 0x2a, 0xf3, 0xb8, 0xea, 0x8c, 0x64, 0x44, 0xc6, 0xd3, 0x9f, 0x00, 0x7b, 0xb2, 0x52, 0x18, 0x11, 0x04, 0x96, 0xb7, 0x05, 0xbb, 0xc2, 0x38, 0x5b, 0xa7, 0x0a, 0x84, 0xb6, 0x4f, 0x02, 0x63, 0xa4, 0x57, 0x00, 0xe3, 0xde, 0xe4, 0xf2, 0xb3, 0x55, 0xd9, 0x00, 0xa9, 0xd2, 0x5c, 0x69, 0x9f, 0xe5, 0x80, 0x4f, 0x23, 0x7c, 0xd9, 0xa7, 0x77, 0x4a, 0xbb, 0x09, 0x6d, 0x45, 0x02, 0xcf, 0x32, 0x90, 0xfd, 0x10, 0xb6, 0xb3, 0x93, 0xd9, 0x3b, 0x1d, 0x57, 0x66, 0xb5, 0xb3, 0xb1, 0x6e, 0x53, 0x5f, 0x04, 0x60, 0x29, 0xcd, 0xe8, 0xb8, 0xab, 0x62, 0x82, 0x33, 0x40, 0xc7, 0xf8, 0x64, 0x60, 0x0e, 0xab, 0x06, 0x3e, 0xa0, 0xa3, 0x62, 0x11, 0x3f, 0x67, 0x5d, 0x24, 0x9e, 0x60, 0x29, 0xdc, 0x4c, 0xd5, 0x13, 0xee, 0x3d, 0xb7, 0x84, 0x93, 0x27, 0xb5, 0x6a, 0xf9, 0xf0, 0xdd, 0x50, 0xac, 0x46, 0x3c, 0xe6, 0xd5, 0xec, 0xf7, 0xb7, 0x9f, 0x23, 0x39, 0x9c, 0x88, 0x8c, 0x5a, 0x62, 0x3f, 0x8d, 0x4a, 0xd7, 0xeb, 0x5e, 0x1e, 0x49, 0xf8, 0xa9, 0x53, 0x11, 0x75, 0xd0, 0x43, 0x1e, 0xc7, 0x29, 0x22, 0x80, 0x1f, 0xc5, 0x83, 0x8d, 0x20, 0x04, 0x87, 0x7f, 0x57, 0x8c, 0xf5, 0xa1, 0x02, 0x81, 0xc1, 0x00, 0xf7, 0xaa, 0xf5, 0xa5, 0x00, 0xdb, 0xd6, 0x11, 0xfc, 0x07, 0x6d, 0x22, 0x24, 0x2b, 0x4b, 0xc5, 0x67, 0x0f, 0x37, 0xa5, 0xdb, 0x8f, 0x38, 0xe2, 0x05, 0x43, 0x9a, 0x44, 0x05, 0x3f, 0xa9, 0xac, 0x4c, 0x98, 0x3c, 0x72, 0x38, 0xc3, 0x89, 0x33, 0x58, 0x73, 0x51, 0xcc, 0x5d, 0x2f, 0x8f, 0x6d, 0x3f, 0xa1, 0x22, 0x9e, 0xfb, 0x9a, 0xb4, 0xb8, 0x79, 0x95, 0xaf, 0x83, 0xcf, 0x5a, 0xb7, 0x14, 0x14, 0x0c, 0x51, 0x8a, 0x11, 0xe6, 0xd6, 0x21, 0x1e, 0x17, 0x13, 0xd3, 0x69, 0x7a, 0x3a, 0xd5, 0xaf, 0x3f, 0xb8, 0x25, 0x01, 0xcb, 0x2b, 0xe6, 0xfc, 0x03, 0xd8, 0xd4, 0xf7, 0x20, 0xe0, 0x21, 0xef, 0x1a, 0xca, 0x61, 0xeb, 0x8e, 0x96, 0x45, 0x8e, 0x5c, 0xe6, 0x81, 0x0b, 0x2d, 0x05, 0x32, 0xf9, 0x41, 0x62, 0xb4, 0x33, 0x98, 0x10, 0x3a, 0xcd, 0xf0, 0x7a, 0x8b, 0x1a, 0x48, 0xd7, 0x3b, 0x01, 0xf5, 0x18, 0x65, 0x8f, 0x3c, 0xc2, 0x31, 0x3b, 0xd3, 0xa7, 0x17, 0x5f, 0x7c, 0x0c, 0xe7, 0x25, 0x18, 0x5a, 0x08, 0xe1, 0x09, 0x89, 0x13, 0xa7, 0xc5, 0x12, 0xab, 0x88, 0x30, 0xcd, 0x06, 0xf9, 0xba, 0x6f, 0xca, 0x9c, 0x8a, 0xda, 0x3e, 0x53, 0x90, 0xd7, 0x16, 0x2e, 0xfc, 0xbc, 0xad, 0xd6, 0x3d, 0xc0, 0x66, 0x4c, 0x02, 0x3d, 0x31, 0xfd, 0x6c, 0xdb, 0x1c, 0xdf, 0x96, 0x33, 0x23, 0x02, 0x81, 0xc1, 0x00, 0xc2, 0x90, 0x47, 0xc4, 0xfb, 0x59, 0xf0, 0xc5, 0x14, 0x75, 0x29, 0xfa, 0x77, 0xa1, 0x8d, 0xd4, 0x90, 0xa1, 0x0d, 0x3f, 0x16, 0x88, 0xe3, 0x4c, 0x8f, 0x8f, 0x18, 0x8c, 0x9c, 0x8a, 0xd5, 0xa7, 0x41, 0x99, 0xf3, 0x80, 0x8e, 0xb1, 0xb8, 0x63, 0xd8, 0x3f, 0x95, 0xd0, 0xd0, 0x2b, 0xf5, 0xe6, 0x93, 0xe8, 0xfe, 0xd0, 0x73, 0xd5, 0xbd, 0xb4, 0xee, 0x51, 0x19, 0x6a, 0x10, 0xca, 0xc8, 0xba, 0xa4, 0x4d, 0x84, 0x54, 0x38, 0x17, 0xb5, 0xd0, 0xa8, 0x75, 0x22, 0xc5, 0x1b, 0x61, 0xa6, 0x51, 0x88, 0x63, 0xf0, 0x4f, 0xd1, 0x88, 0xd9, 0x16, 0x49, 0x30, 0xe1, 0xa8, 0x47, 0xc9, 0x30, 0x1d, 0x5c, 0x75, 0xd8, 0x89, 0xb6, 0x1d, 0x45, 0xd8, 0x0f, 0x94, 0x89, 0xb3, 0xe4, 0x51, 0xfa, 0x21, 0xff, 0x6f, 0xb6, 0x30, 0x6f, 0x33, 0x24, 0xbc, 0x09, 0x98, 0xe9, 0x20, 0x02, 0x0b, 0xde, 0xff, 0xc5, 0x06, 0xb6, 0x28, 0xa3, 0xa1, 0x07, 0xe8, 0xe1, 0xd2, 0xc2, 0xf1, 0xd1, 0x23, 0x6b, 0x4c, 0x3a, 0xae, 0x85, 0xec, 0xf9, 0xff, 0xa7, 0x9b, 0x25, 0xb8, 0x95, 0x1d, 0xa8, 0x14, 0x81, 0x4f, 0x79, 0x4f, 0xd6, 0x39, 0x5d, 0xe6, 0x5f, 0xd2, 0x34, 0x54, 0x8b, 0x1e, 0x40, 0x4c, 0x15, 0x5a, 0x45, 0xce, 0x0c, 0xb0, 0xdf, 0xa1, 0x17, 0xb8, 0xb0, 0x6a, 0x82, 0xa5, 0x97, 0x92, 0x70, 0xfb, 0x02, 0x81, 0xc0, 0x77, 0x46, 0x44, 0x2b, 0x04, 0xf0, 0xda, 0x75, 0xaa, 0xd4, 0xc0, 0xc0, 0x32, 0x7f, 0x0f, 0x6c, 0xb0, 0x27, 0x69, 0xfb, 0x5c, 0x73, 0xeb, 0x47, 0x1e, 0x95, 0xe2, 0x13, 0x64, 0x1b, 0xb6, 0xd1, 0x1d, 0xca, 0x2b, 0x42, 0x2f, 0x08, 0x2c, 0x69, 0x27, 0xed, 0xd1, 0xb5, 0x04, 0x23, 0xc5, 0x85, 0x2d, 0xa1, 0xa2, 0x94, 0xc2, 0x43, 0x4d, 0x49, 0x92, 0x74, 0x7e, 0x24, 0x92, 0x95, 0xf3, 0x99, 0x9d, 0xd6, 0x18, 0xe6, 0xcf, 0x9c, 0x45, 0xff, 0x89, 0x08, 0x40, 0x2a, 0x0e, 0xa0, 0x28, 0xf9, 0x83, 0xfe, 0xc1, 0xe6, 0x40, 0xa8, 0xe2, 0x29, 0xc9, 0xb0, 0xe8, 0x9a, 0x17, 0xb2, 0x23, 0x7e, 0xf4, 0x32, 0x08, 0xc9, 0x83, 0xb2, 0x15, 0xb8, 0xc5, 0xc9, 0x03, 0xd1, 0x9d, 0xda, 0x3e, 0xa8, 0xbf, 0xd5, 0xb7, 0x7d, 0x65, 0x63, 0x94, 0x5d, 0x5d, 0x94, 0xb4, 0xcf, 0x8d, 0x07, 0x0b, 0x70, 0x85, 0x8e, 0xce, 0x03, 0x0b, 0x2a, 0x8d, 0xb3, 0x3c, 0x46, 0xc0, 0x2f, 0xc7, 0x72, 0x6c, 0x9c, 0x5d, 0x07, 0x0f, 0x45, 0x3b, 0x6b, 0x66, 0x32, 0xab, 0x17, 0x83, 0xd8, 0x4c, 0x2c, 0x84, 0x71, 0x19, 0x8f, 0xaa, 0x0a, 0xff, 0xbc, 0xf7, 0x42, 0x10, 0xe8, 0xae, 0x4d, 0x26, 0xaf, 0xdd, 0x06, 0x33, 0x29, 0x66, 0x21, 0x5d, 0xf5, 0xae, 0x17, 0x07, 0x1f, 0x87, 0x9e, 0xae, 0x27, 0x1d, 0xd5, 0x02, 0x81, 0xc0, 0x56, 0x17, 0x4f, 0x9a, 0x8a, 0xf9, 0xde, 0x3e, 0xe6, 0x71, 0x7d, 0x94, 0xb5, 0xb0, 0xc7, 0xb8, 0x62, 0x12, 0xd1, 0x70, 0xb4, 0x00, 0xf8, 0x4a, 0xdd, 0x4f, 0x1d, 0x36, 0xc2, 0xe1, 0xef, 0xee, 0x25, 0x6a, 0x00, 0xc4, 0x46, 0xdf, 0xbe, 0xce, 0x77, 0x56, 0x93, 0x6d, 0x25, 0x5f, 0xfe, 0x5b, 0xfb, 0xe0, 0xe2, 0x37, 0xcc, 0xb9, 0xac, 0x4a, 0xce, 0x15, 0x16, 0xa0, 0xc7, 0x33, 0x63, 0xa4, 0xaa, 0xa5, 0x1e, 0x43, 0xc1, 0xda, 0x43, 0xfa, 0x43, 0x40, 0x29, 0x95, 0x7c, 0x2b, 0x36, 0x53, 0xe7, 0x7d, 0x09, 0x4d, 0xd8, 0x52, 0xac, 0x74, 0x5f, 0x08, 0x81, 0x21, 0x5c, 0x3a, 0x5a, 0xce, 0xf3, 0x25, 0xb6, 0x1e, 0x21, 0x76, 0x4c, 0x7c, 0x71, 0x50, 0x71, 0xaa, 0x27, 0x02, 0x5b, 0x23, 0x06, 0x0b, 0x21, 0x5b, 0xc7, 0x28, 0xa3, 0x3d, 0x8d, 0x25, 0x9b, 0x2a, 0x2d, 0x9d, 0xa1, 0x1c, 0x1d, 0xcb, 0x7d, 0x78, 0xf8, 0x06, 0x7e, 0x20, 0x7f, 0x24, 0x2a, 0x5c, 0xa4, 0x04, 0xff, 0x2a, 0x68, 0xe0, 0xe6, 0xa3, 0xd8, 0x6f, 0x56, 0x73, 0xa1, 0x3a, 0x4e, 0xc9, 0x23, 0xa1, 0x87, 0x22, 0x6a, 0x74, 0x78, 0x3f, 0x44, 0x1c, 0x77, 0x13, 0xe5, 0x51, 0xef, 0x89, 0x00, 0x3c, 0x6a, 0x4a, 0x5a, 0x8e, 0xf5, 0x30, 0xa2, 0x93, 0x7e, 0x92, 0x9b, 0x85, 0x55, 0xaf, 0xfe, 0x24, 0xaf, 0x57, 0x02, 0x81, 0xc1, 0x00, 0xa4, 0xc2, 0x6a, 0x59, 0x45, 0xea, 0x71, 0x7d, 0x4c, 0xaf, 0xaf, 0xd6, 0x55, 0x97, 0x73, 0xc5, 0xa1, 0x3c, 0xf6, 0x59, 0x23, 0xb6, 0x1f, 0x5e, 0x9c, 0x96, 0x0f, 0x97, 0x66, 0x82, 0x91, 0x48, 0x36, 0x70, 0x02, 0x67, 0xde, 0x34, 0xa6, 0x95, 0x7b, 0x51, 0x43, 0x66, 0xa4, 0x16, 0x45, 0x59, 0x12, 0xdb, 0x35, 0x19, 0x4b, 0xbf, 0x1d, 0xab, 0xf3, 0x3f, 0xb4, 0xb4, 0x6f, 0x66, 0xb0, 0x67, 0xc6, 0x77, 0x2c, 0x46, 0xa8, 0x03, 0x64, 0x9a, 0x13, 0x9d, 0x40, 0x22, 0x56, 0x76, 0x1a, 0x7c, 0x1e, 0xe2, 0xda, 0x7f, 0x09, 0xcf, 0x10, 0xe3, 0xf2, 0xf4, 0x2a, 0x3b, 0x46, 0xc7, 0x61, 0x9b, 0xef, 0x4a, 0x18, 0x60, 0x8c, 0x32, 0x71, 0xb9, 0xdd, 0xac, 0xa0, 0xc6, 0x8d, 0x3f, 0xab, 0xc3, 0x21, 0x2c, 0xeb, 0x91, 0x8f, 0xc7, 0x43, 0x0d, 0x0c, 0x67, 0x9e, 0xab, 0xe6, 0x8d, 0xb6, 0x2d, 0x41, 0xca, 0x43, 0xd8, 0xcb, 0x30, 0xfb, 0x3b, 0x40, 0x0d, 0x10, 0x9b, 0xb1, 0x55, 0x93, 0x73, 0x8b, 0x60, 0xef, 0xc0, 0xee, 0xc0, 0xa6, 0x7a, 0x79, 0x90, 0xfd, 0x4c, 0x25, 0xd4, 0x4f, 0x67, 0xbe, 0xf7, 0x86, 0x3c, 0x5d, 0x2b, 0x7d, 0x97, 0x3d, 0xa2, 0x91, 0xa5, 0x06, 0x69, 0xf6, 0x7a, 0xb8, 0x77, 0xe6, 0x70, 0xa9, 0xd8, 0x86, 0x4b, 0xa6, 0xcf, 0x67, 0x1d, 0x33, 0xcf, 0xfe, 0x3e }; static unsigned char test4096[] = { 0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, 0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43, 0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21, 0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44, 0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28, 0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41, 0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7, 0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd, 0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e, 0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b, 0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6, 0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf, 0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d, 0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e, 0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0, 0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99, 0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90, 0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8, 0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a, 0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda, 0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca, 0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28, 0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7, 0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb, 0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26, 0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c, 0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03, 0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1, 0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09, 0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83, 0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95, 0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc, 0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36, 0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5, 0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc, 0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8, 0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa, 0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca, 0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e, 0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56, 0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48, 0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46, 0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b, 0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe, 0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3, 0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69, 0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe, 0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3, 0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f, 0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed, 0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4, 0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3, 0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f, 0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb, 0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd, 0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5, 0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17, 0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52, 0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c, 0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f, 0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12, 0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61, 0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8, 0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4, 0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e, 0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50, 0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea, 0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16, 0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae, 0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6, 0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c, 0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a, 0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e, 0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb, 0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5, 0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6, 0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe, 0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14, 0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88, 0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7, 0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19, 0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40, 0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b, 0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69, 0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9, 0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c, 0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62, 0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2, 0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9, 0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25, 0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d, 0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab, 0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f, 0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c, 0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda, 0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd, 0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54, 0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41, 0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7, 0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1, 0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d, 0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65, 0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28, 0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d, 0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14, 0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc, 0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37, 0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81, 0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94, 0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e, 0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9, 0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c, 0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24, 0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc, 0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1, 0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc, 0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84, 0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77, 0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21, 0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6, 0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa, 0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14, 0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39, 0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06, 0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3, 0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35, 0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97, 0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed, 0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8, 0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4, 0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94, 0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4, 0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d, 0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c, 0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e, 0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1, 0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc, 0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55, 0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61, 0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92, 0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80, 0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13, 0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48, 0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed, 0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9, 0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a, 0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35, 0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7, 0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c, 0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47, 0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8, 0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7, 0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc, 0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82, 0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b, 0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef, 0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6, 0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80, 0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac, 0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b, 0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35, 0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c, 0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e, 0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a, 0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd, 0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5, 0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc, 0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30, 0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f, 0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c, 0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe, 0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f, 0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91, 0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9, 0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf, 0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76, 0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0, 0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78, 0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10, 0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82, 0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00, 0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25, 0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3, 0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b, 0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79, 0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94, 0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8, 0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38, 0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0, 0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44, 0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b, 0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf, 0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f, 0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28, 0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97, 0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f, 0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48, 0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35, 0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84, 0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a, 0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b, 0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e, 0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55, 0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16, 0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c, 0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82, 0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05, 0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3, 0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e, 0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43, 0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e, 0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a, 0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed, 0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7, 0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c, 0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b, 0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e, 0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95, 0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11, 0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb, 0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e, 0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a, 0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc, 0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35, 0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21, 0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a, 0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70, 0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01, 0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c, 0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26, 0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55, 0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17, }; static unsigned char test8192[] = { 0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, 0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43, 0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21, 0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44, 0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28, 0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41, 0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7, 0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd, 0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e, 0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b, 0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6, 0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf, 0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d, 0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e, 0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0, 0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99, 0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90, 0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8, 0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a, 0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda, 0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca, 0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28, 0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7, 0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb, 0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26, 0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c, 0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03, 0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1, 0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09, 0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83, 0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95, 0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc, 0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36, 0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5, 0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc, 0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8, 0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa, 0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca, 0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e, 0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56, 0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48, 0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46, 0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b, 0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe, 0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3, 0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69, 0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe, 0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3, 0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f, 0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed, 0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4, 0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3, 0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f, 0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb, 0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd, 0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5, 0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17, 0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52, 0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c, 0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f, 0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12, 0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61, 0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8, 0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4, 0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e, 0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50, 0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea, 0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16, 0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae, 0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6, 0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c, 0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a, 0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e, 0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb, 0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5, 0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6, 0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe, 0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14, 0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88, 0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7, 0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19, 0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40, 0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b, 0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69, 0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9, 0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c, 0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62, 0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2, 0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9, 0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25, 0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d, 0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab, 0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f, 0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c, 0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda, 0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd, 0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54, 0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41, 0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7, 0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1, 0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d, 0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65, 0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28, 0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d, 0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14, 0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc, 0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37, 0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81, 0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94, 0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e, 0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9, 0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c, 0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24, 0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc, 0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1, 0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc, 0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84, 0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77, 0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21, 0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6, 0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa, 0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14, 0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39, 0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06, 0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3, 0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35, 0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97, 0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed, 0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8, 0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4, 0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94, 0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4, 0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d, 0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c, 0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e, 0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1, 0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc, 0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55, 0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61, 0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92, 0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80, 0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13, 0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48, 0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed, 0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9, 0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a, 0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35, 0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7, 0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c, 0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47, 0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8, 0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7, 0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc, 0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82, 0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b, 0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef, 0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6, 0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80, 0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac, 0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b, 0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35, 0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c, 0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e, 0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a, 0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd, 0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5, 0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc, 0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30, 0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f, 0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c, 0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe, 0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f, 0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91, 0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9, 0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf, 0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76, 0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0, 0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78, 0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10, 0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82, 0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00, 0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25, 0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3, 0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b, 0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79, 0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94, 0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8, 0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38, 0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0, 0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44, 0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b, 0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf, 0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f, 0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28, 0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97, 0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f, 0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48, 0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35, 0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84, 0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a, 0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b, 0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e, 0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55, 0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16, 0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c, 0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82, 0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05, 0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3, 0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e, 0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43, 0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e, 0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a, 0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed, 0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7, 0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c, 0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b, 0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e, 0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95, 0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11, 0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb, 0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e, 0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a, 0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc, 0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35, 0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21, 0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a, 0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70, 0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01, 0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c, 0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26, 0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55, 0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17, 0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, 0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43, 0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21, 0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44, 0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28, 0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41, 0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7, 0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd, 0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e, 0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b, 0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6, 0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf, 0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d, 0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e, 0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0, 0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99, 0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90, 0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8, 0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a, 0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda, 0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca, 0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28, 0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7, 0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb, 0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26, 0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c, 0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03, 0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1, 0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09, 0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83, 0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95, 0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc, 0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36, 0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5, 0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc, 0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8, 0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa, 0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca, 0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e, 0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56, 0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48, 0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46, 0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b, 0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe, 0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3, 0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69, 0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe, 0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3, 0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f, 0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed, 0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4, 0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3, 0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f, 0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb, 0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd, 0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5, 0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17, 0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52, 0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c, 0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f, 0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12, 0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61, 0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8, 0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4, 0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e, 0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50, 0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea, 0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16, 0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae, 0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6, 0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c, 0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a, 0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e, 0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb, 0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5, 0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6, 0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe, 0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14, 0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88, 0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7, 0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19, 0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40, 0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b, 0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69, 0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9, 0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c, 0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62, 0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2, 0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9, 0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25, 0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d, 0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab, 0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f, 0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c, 0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda, 0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd, 0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54, 0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41, 0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7, 0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1, 0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d, 0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65, 0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28, 0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d, 0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14, 0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc, 0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37, 0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81, 0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94, 0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e, 0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9, 0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c, 0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24, 0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc, 0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1, 0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc, 0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84, 0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77, 0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21, 0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6, 0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa, 0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14, 0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39, 0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06, 0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3, 0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35, 0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97, 0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed, 0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8, 0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4, 0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94, 0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4, 0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d, 0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c, 0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e, 0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1, 0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc, 0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55, 0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61, 0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92, 0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80, 0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13, 0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48, 0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed, 0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9, 0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a, 0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35, 0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7, 0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c, 0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47, 0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8, 0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7, 0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc, 0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82, 0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b, 0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef, 0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6, 0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80, 0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac, 0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b, 0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35, 0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c, 0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e, 0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a, 0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd, 0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5, 0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc, 0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30, 0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f, 0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c, 0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe, 0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f, 0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91, 0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9, 0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf, 0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76, 0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0, 0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78, 0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10, 0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82, 0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00, 0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25, 0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3, 0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b, 0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79, 0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94, 0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8, 0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38, 0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0, 0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44, 0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b, 0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf, 0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f, 0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28, 0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97, 0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f, 0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48, 0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35, 0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84, 0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a, 0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b, 0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e, 0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55, 0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16, 0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c, 0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82, 0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05, 0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3, 0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e, 0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43, 0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e, 0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a, 0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed, 0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7, 0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c, 0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b, 0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e, 0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95, 0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11, 0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb, 0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e, 0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a, 0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc, 0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35, 0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21, 0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a, 0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70, 0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01, 0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c, 0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26, 0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55, 0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17, }; #endif static const char* get_padding_str(int padding) { char *pad_str; switch (padding) { case RSA_NO_PADDING: pad_str = "RSA_NO_PADDING"; break; case RSA_PKCS1_PADDING: pad_str = "RSA_PKCS1_PADDING"; break; case RSA_X931_PADDING: pad_str = "RSA_X931_PADDING"; break; case RSA_PKCS1_OAEP_PADDING: pad_str = "RSA_PKCS1_OAEP_PADDING"; break; default: pad_str = "UNKNOWN PADDING"; } return pad_str; } /****************************************************************************** * function: * run_rsa (void *args) * * @param args [IN] - the test parameters * * description: * the test application for RSA sign and verify using QAT engine. * The OpenSSL corresponding RSA_private_encrypt() and RSA_public_decrypt() * functions are used in this application. * The values of RSA key structures are passed from Intel API RSA test vector. ******************************************************************************/ static int run_rsa(void *args) { int i = 0; size_t sigLen = 0; #ifndef QAT_OPENSSL_PROVIDER int verLen = 0; #endif int ret = 1; int status = 0; TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int count = *(temp_args->count); int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int sign_only = temp_args->sign_only; int verify_only = temp_args->verify_only; int encrypt_only = temp_args->encrypt_only; int decrypt_only = temp_args->decrypt_only; #ifndef QAT_OPENSSL_PROVIDER int rsa_all = temp_args->rsa_all; #endif int pad = temp_args->padding; #ifdef QAT_OPENSSL_PROVIDER int enable_negative = temp_args->enable_negative; EVP_PKEY_CTX *rsa_sign_ctx = NULL; EVP_PKEY_CTX *rsa_verify_ctx = NULL; EVP_PKEY_CTX *enc_ctx = NULL; EVP_PKEY_CTX *dec_ctx = NULL; static unsigned int testnum = 1; unsigned char *wrong_HashData = OPENSSL_malloc(HASH_DATA_SIZE_NO_PADDING_8192); static const struct { const unsigned char *data; unsigned int length; unsigned int bits; } rsa_keys[] = { { test1024, sizeof(test1024), 1024 }, { test2048, sizeof(test2048), 2048 }, { test3072, sizeof(test3072), 3072 }, { test4096, sizeof(test4096), 4096 }, { test8192, sizeof(test8192), 8192 } }; #endif RSA *key = NULL; BIGNUM *n = NULL; BIGNUM *e = NULL; BIGNUM *d = NULL; BIGNUM *p = NULL; BIGNUM *q = NULL; BIGNUM *dmp1 = NULL; BIGNUM *dmq1 = NULL; BIGNUM *iqmp = NULL; unsigned char *sig = OPENSSL_malloc(RSA_SIZE); unsigned char *verMsg = OPENSSL_malloc(RSA_SIZE); int hash_length = 0; unsigned char *HashData = OPENSSL_malloc(HASH_DATA_SIZE_NO_PADDING_8192); unsigned char *ctext = NULL; #ifdef QAT_OPENSSL_PROVIDER unsigned char *dtext = NULL; #endif #ifndef QAT_OPENSSL_PROVIDER unsigned char *ptext = NULL; int plen = 0; #endif int expectedPlen = 0; size_t clen = 0; unsigned char * expectedPtext = NULL; const char* pad_str; if (sig == NULL || verMsg == NULL || HashData == NULL) { WARN("# FAIL RSA Initial mallocs failed\n"); ret = 0; goto err; } pad_str = get_padding_str(pad); DEBUG("[%s] Input:\n sign_only = %d \n verify_only = %d \n" "encrypt_only = %d \n decrypt_only = %d\n padding = %s\n --- \n", __func__, sign_only, verify_only, encrypt_only, decrypt_only, pad_str); /* setup input hash message */ for (i = 0; i < HASH_DATA_SIZE_NO_PADDING_8192; i++) HashData[i] = i % 16; /* setup new RSA key */ key = RSA_new(); /* * initialise RSA key components by copying intel testing vector to RSA key * structure * pass input size to support RSA module size */ if (size <= 1024) { /* bignumber format needed for RSA structure */ DEBUG("\n RSA module size 1024 \n"); if (pad == RSA_NO_PADDING) hash_length = HASH_DATA_SIZE_NO_PADDING_1024; else hash_length = HASH_DATA_SIZE_1024; expectedPtext = OPENSSL_malloc(sizeof(expectedPtexttt_1024)); if (expectedPtext == NULL) { WARN("# FAIL RSA expectedPtext malloc failed\n"); ret = 0; goto err; } memcpy(expectedPtext, expectedPtexttt_1024, sizeof(expectedPtexttt_1024)); if (pad == RSA_PKCS1_OAEP_PADDING) expectedPlen = sizeof(expectedPtexttt_1024) - RSA_PKCS1_OAEP_PADDING_SIZE; else if (pad == RSA_PKCS1_PADDING) expectedPlen = sizeof(expectedPtexttt_1024) - RSA_PKCS1_PADDING_SIZE; else expectedPlen = sizeof(expectedPtexttt_1024); if (((n = BN_bin2bn(rsaModulusN_1024, sizeof(rsaModulusN_1024), NULL)) == NULL) || ((e = BN_bin2bn(rsaPublicExponentE_1024, sizeof(rsaPublicExponentE_1024), NULL)) == NULL) || ((d = BN_bin2bn(rsaPrivateExponentD_1024, sizeof(rsaPrivateExponentD_1024), NULL)) == NULL) || ((p = BN_bin2bn(rsaPrimeP_1024_KeyPair, sizeof(rsaPrimeP_1024_KeyPair), NULL)) == NULL) || ((q = BN_bin2bn(rsaPrimeQ_1024_KeyPair, sizeof(rsaPrimeQ_1024_KeyPair), NULL)) == NULL) || ((dmp1 = BN_bin2bn(rsaCrtExpDp_1024_KeyPair, sizeof(rsaCrtExpDp_1024_KeyPair), NULL)) == NULL) || ((dmq1 = BN_bin2bn(rsaCrtExpDq_1024_KeyPair, sizeof(rsaCrtExpDq_1024_KeyPair), NULL)) == NULL) || ((iqmp = BN_bin2bn(rsaCrtCoefQInv_1024_KeyPair, sizeof(rsaCrtCoefQInv_1024_KeyPair), NULL)) == NULL)) { WARN("# FAIL RSA - Failed setting 1024 bit parameters\n"); ret = 0; if (n) BN_free(n); if (e) BN_free(e); if (d) BN_free(d); if (p) BN_free(p); if (q) BN_free(q); if (dmp1) BN_free(dmp1); if (dmq1) BN_free(dmq1); if (iqmp) BN_free(iqmp); goto err; } } if (size > 1024 && size <= 2048) { /* bignumber format needed for RSA structure */ DEBUG("\n RSA module size 2048 \n"); if (pad == RSA_NO_PADDING) hash_length = HASH_DATA_SIZE_NO_PADDING_2048; else hash_length = HASH_DATA_SIZE_2048; expectedPtext = OPENSSL_malloc(sizeof(expectedPtexttt_2048)); if (expectedPtext == NULL) { WARN("# FAIL RSA expectedPtext malloc failed\n"); ret = 0; goto err; } memcpy(expectedPtext, expectedPtexttt_2048, sizeof(expectedPtexttt_2048)); if (pad == RSA_PKCS1_OAEP_PADDING) expectedPlen = sizeof(expectedPtexttt_2048) - RSA_PKCS1_OAEP_PADDING_SIZE; else if (pad == RSA_PKCS1_PADDING) expectedPlen = sizeof(expectedPtexttt_2048) - RSA_PKCS1_PADDING_SIZE; else expectedPlen = sizeof(expectedPtexttt_2048); if (((n = BN_bin2bn(rsaModulusN_2048, sizeof(rsaModulusN_2048), NULL)) == NULL) || ((e = BN_bin2bn(rsaPublicExponentE_2048, sizeof(rsaPublicExponentE_2048), NULL)) == NULL) || ((d = BN_bin2bn(rsaPrivateExponentD_2048, sizeof(rsaPrivateExponentD_2048), NULL)) == NULL) || ((p = BN_bin2bn(rsaPrimeP_2048_KeyPair, sizeof(rsaPrimeP_2048_KeyPair), NULL)) == NULL) || ((q = BN_bin2bn(rsaPrimeQ_2048_KeyPair, sizeof(rsaPrimeQ_2048_KeyPair), NULL)) == NULL) || ((dmp1 = BN_bin2bn(rsaCrtExpDp_2048_KeyPair, sizeof(rsaCrtExpDp_2048_KeyPair), NULL)) == NULL) || ((dmq1 = BN_bin2bn(rsaCrtExpDq_2048_KeyPair, sizeof(rsaCrtExpDq_2048_KeyPair), NULL)) == NULL) || ((iqmp = BN_bin2bn(rsaCrtCoefQInv_2048_KeyPair, sizeof(rsaCrtCoefQInv_2048_KeyPair), NULL)) == NULL)) { WARN("# FAIL RSA - Failed setting 2048 bit parameters\n"); ret = 0; if (n) BN_free(n); if (e) BN_free(e); if (d) BN_free(d); if (p) BN_free(p); if (q) BN_free(q); if (dmp1) BN_free(dmp1); if (dmq1) BN_free(dmq1); if (iqmp) BN_free(iqmp); goto err; } } if (size > 2048 && size <= 4096) { /* bignumber format needed for RSA structure */ DEBUG("\n RSA module size 4096 \n"); if (pad == RSA_NO_PADDING) hash_length = HASH_DATA_SIZE_NO_PADDING_4096; else hash_length = HASH_DATA_SIZE_4096; expectedPtext = OPENSSL_malloc(sizeof(expectedPtexttt_4096)); if (expectedPtext == NULL) { WARN("# FAIL RSA expectedPtext malloc failed\n"); ret = 0; goto err; } memcpy(expectedPtext, expectedPtexttt_4096, sizeof(expectedPtexttt_4096)); if (pad == RSA_PKCS1_OAEP_PADDING) expectedPlen = sizeof(expectedPtexttt_4096) - RSA_PKCS1_OAEP_PADDING_SIZE; else if (pad == RSA_PKCS1_PADDING) expectedPlen = sizeof(expectedPtexttt_4096) - RSA_PKCS1_PADDING_SIZE; else expectedPlen = sizeof(expectedPtexttt_4096); if (((n = BN_bin2bn(rsaModulusN_4096, sizeof(rsaModulusN_4096), NULL)) == NULL) || ((e = BN_bin2bn(rsaPublicExponentE_4096, sizeof(rsaPublicExponentE_4096), NULL)) == NULL) || ((d = BN_bin2bn(rsaPrivateExponentD_4096, sizeof(rsaPrivateExponentD_4096), NULL)) == NULL) || ((p = BN_bin2bn(rsaPrimeP_4096_KeyPair, sizeof(rsaPrimeP_4096_KeyPair), NULL)) == NULL) || ((q = BN_bin2bn(rsaPrimeQ_4096_KeyPair, sizeof(rsaPrimeQ_4096_KeyPair), NULL)) == NULL) || ((dmp1 = BN_bin2bn(rsaCrtExpDp_4096_KeyPair, sizeof(rsaCrtExpDp_4096_KeyPair), NULL)) == NULL) || ((dmq1 = BN_bin2bn(rsaCrtExpDq_4096_KeyPair, sizeof(rsaCrtExpDq_4096_KeyPair), NULL)) == NULL) || ((iqmp = BN_bin2bn(rsaCrtCoefQInv_4096_KeyPair, sizeof(rsaCrtCoefQInv_4096_KeyPair), NULL)) == NULL)) { WARN("# FAIL RSA - Failed setting 4096 bit parameters\n"); ret = 0; if (n) BN_free(n); if (e) BN_free(e); if (d) BN_free(d); if (p) BN_free(p); if (q) BN_free(q); if (dmp1) BN_free(dmp1); if (dmq1) BN_free(dmq1); if (iqmp) BN_free(iqmp); goto err; } } if (size >4096) { /* bignumber format needed for RSA structure */ DEBUG("\n RSA module size 8192 \n"); if (pad == RSA_NO_PADDING) hash_length = HASH_DATA_SIZE_NO_PADDING_8192; else hash_length = HASH_DATA_SIZE_8192; expectedPtext = OPENSSL_malloc(sizeof(expectedPtexttt_8192)); if (expectedPtext == NULL) { WARN("# FAIL RSA expectedPtext malloc failed\n"); ret = 0; goto err; } memcpy(expectedPtext, expectedPtexttt_8192, sizeof(expectedPtexttt_8192)); if (pad == RSA_PKCS1_OAEP_PADDING) expectedPlen = sizeof(expectedPtexttt_8192) - RSA_PKCS1_OAEP_PADDING_SIZE; else if (pad == RSA_PKCS1_PADDING) expectedPlen = sizeof(expectedPtexttt_8192) - RSA_PKCS1_PADDING_SIZE; else expectedPlen = sizeof(expectedPtexttt_8192); if (((n = BN_bin2bn(rsaModulusN_8192, sizeof(rsaModulusN_8192), NULL)) == NULL) || ((e = BN_bin2bn(rsaPublicExponentE_8192, sizeof(rsaPublicExponentE_8192), NULL)) == NULL) || ((d = BN_bin2bn(rsaPrivateExponentD_8192, sizeof(rsaPrivateExponentD_8192), NULL)) == NULL) || ((p = BN_bin2bn(rsaPrimeP_8192_KeyPair, sizeof(rsaPrimeP_8192_KeyPair), NULL)) == NULL) || ((q = BN_bin2bn(rsaPrimeQ_8192_KeyPair, sizeof(rsaPrimeQ_8192_KeyPair), NULL)) == NULL) || ((dmp1 = BN_bin2bn(rsaCrtExpDp_8192_KeyPair, sizeof(rsaCrtExpDp_8192_KeyPair), NULL)) == NULL) || ((dmq1 = BN_bin2bn(rsaCrtExpDq_8192_KeyPair, sizeof(rsaCrtExpDq_8192_KeyPair), NULL)) == NULL) || ((iqmp = BN_bin2bn(rsaCrtCoefQInv_8192_KeyPair, sizeof(rsaCrtCoefQInv_8192_KeyPair), NULL)) == NULL)) { WARN("# FAIL RSA - Failed setting 8192 bit parameters\n"); ret = 0; if (n) BN_free(n); if (e) BN_free(e); if (d) BN_free(d); if (p) BN_free(p); if (q) BN_free(q); if (dmp1) BN_free(dmp1); if (dmq1) BN_free(dmq1); if (iqmp) BN_free(iqmp); goto err; } } RSA_set0_key(key, n, e, d); RSA_set0_factors(key, p, q); RSA_set0_crt_params(key, dmp1, dmq1, iqmp); #ifndef QAT_OPENSSL_PROVIDER /* the op buffer for pub enc needs to be the pub key size*/ ctext = OPENSSL_malloc(RSA_size(key)); ptext = OPENSSL_malloc(RSA_size(key)); for (i = 0; i < count; i++) { /* * For functional tests we need to run verify anyway, * i.e., even if sign only */ if ((!i || sign_only) && (!encrypt_only && !decrypt_only)) { DEBUG("\n----- RSA Sign ----- \n\n"); if (print_output) tests_hexdump("Hashdata:", HashData, hash_length); /* * the RSA_private_encrypt() function returns the length of * signature * a signature file contains all 0xFF will be returned if * RSA_private_encrypt() fails */ sigLen = RSA_private_encrypt(hash_length, /* length in bytes of input file */ HashData, /* input data pointer */ sig, /* output signature pointer */ key, /* RSA key structure */ pad); /* padding format */ if (sigLen <= 0) { WARN("# FAIL RSA - Sign Failed\n"); ret = 0; goto err; } else DEBUG("----- RSA Sign completed ----- \n"); if (print_output) tests_hexdump("Signature:", sig, sigLen); } /* (!i || sign_only) */ /*Sign*/ if ((!i || verify_only) && (!encrypt_only && !decrypt_only)) { DEBUG("\n----- RSA Verify ----- \n\n"); if (print_output) tests_hexdump("Signature:", sig, sigLen); verLen = RSA_public_decrypt(sigLen, /* length in bytes of input signature */ sig, /* input signature */ verMsg, /* output verify message pointer */ key, /* RSA key structure */ pad); /* padding format */ if (verLen <= 0) { WARN("# FAIL RSA - Verify Failed\n"); ret = 0; goto err; } else { DEBUG("----- RSA Verify completed ----- \n"); } if (print_output) tests_hexdump("Verify:", verMsg, verLen); } /*For functional tests we need to run encrypt anyway*/ if ((!i || encrypt_only) && (!sign_only && !verify_only)) { if (print_output) tests_hexdump("Plain text:", expectedPtext, expectedPlen); clen = RSA_public_encrypt(expectedPlen, /* length in bytes of input file */ expectedPtext, /* input data pointer */ ctext, /* output ciphertext pointer */ key, /* RSA key structure */ pad); /* padding format */ if (clen <= 0) { WARN("# FAIL RSA - Encrypt Failed\n"); ret = 0; goto err; } else { DEBUG("----- RSA Encrypt completed ----- \n"); } if (print_output) tests_hexdump("Cipher text:", ctext, clen); } if ((!i || decrypt_only) && (!sign_only && !verify_only)) { DEBUG("\n----- RSA Decrypt ----- \n\n"); if (print_output) tests_hexdump("Cipher text:", ctext, clen); plen = RSA_private_decrypt(clen, /* length in bytes of input file */ ctext, /* input data pointer */ ptext, /* output ciphertext pointer */ key, /* RSA key structure */ pad); /* padding format */ if (plen <= 0) { WARN("# FAIL RSA - Decrypt Failed\n"); ret = 0; goto err; } else DEBUG("----- RSA Decrypt completed ----- \n"); if (print_output) tests_hexdump("Plain text:", ptext, plen); } } /* count for-loop */ if (encrypt_only || decrypt_only || rsa_all) { /* Compare and verify the encrypted and decrypted message */ if (verify) { if (memcmp(ptext, expectedPtext, plen)) { INFO("# FAIL %s for RSA with %s\n", encrypt_only ? "encrypt" : "decrypt", pad_str); ret = 0; tests_hexdump("Actual plain text:", expectedPtext, expectedPlen); tests_hexdump("Decrypted plain text:", ptext, plen); } else INFO("# PASS %s for RSA with %s\n", encrypt_only ? "encrypt" : "decrypt", pad_str); } } if (sign_only || verify_only || status || rsa_all) { /* Compare and verify the signed and verified message */ if (verify) { if (memcmp(verMsg, HashData, verLen)) { INFO("# FAIL %s for RSA with %s\n", sign_only ? "sign" : "verify", pad_str); ret = 0; tests_hexdump("Verified actual:", verMsg, verLen); tests_hexdump("Signed expected:", HashData, hash_length); } else INFO("# PASS %s for RSA with %s\n", sign_only ? "sign" : "verify", pad_str); } } #endif #ifdef QAT_OPENSSL_PROVIDER EVP_PKEY *rsa_key = NULL; RAND_bytes(HashData, 36); RAND_bytes(expectedPtext, 36); for (i = 0; i < count; i++) { for (testnum = 0; testnum < 5; testnum++) { if (size == rsa_keys[testnum].bits) break; } const unsigned char *R = rsa_keys[testnum].data; if (size == 8192) { rsa_key=EVP_PKEY_new(); EVP_PKEY_assign_RSA(rsa_key, key); } else { rsa_key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &R, rsa_keys[testnum].length); } /* * For functional tests we need to run verify anyway, * i.e., even if sign only */ if ((!i || sign_only) && (!encrypt_only && !decrypt_only)) { if (print_output) tests_hexdump("Hashdata:", HashData, hash_length); rsa_sign_ctx = EVP_PKEY_CTX_new(rsa_key, NULL); if (rsa_sign_ctx == NULL || EVP_PKEY_sign_init(rsa_sign_ctx) != 1 || EVP_PKEY_sign(rsa_sign_ctx, NULL, &sigLen, HashData, 36) <= 0) { WARN("# FAIL RSA - SignInit Failed\n"); ret = 0; goto err; } status = EVP_PKEY_sign(rsa_sign_ctx, sig, &sigLen, HashData, 36); if (status <= 0) { WARN("# FAIL RSA - Sign Failed\n"); ret = 0; goto err; } else { DEBUG("----- RSA Sign completed ----- \n"); } if (print_output) tests_hexdump("Signature:", sig, sigLen); } /* (!i || sign_only) */ if ((!i || verify_only) && (!encrypt_only && !decrypt_only)) { rsa_verify_ctx = EVP_PKEY_CTX_new(rsa_key, NULL); if ((rsa_verify_ctx == 0) || (EVP_PKEY_verify_init(rsa_verify_ctx) <= 0)) { WARN("# FAIL RSA - VerifyInit Failed\n"); ret = 0; goto err; } if (enable_negative) { if (EVP_PKEY_verify(rsa_verify_ctx, sig, sigLen, wrong_HashData, 36) == 1) { fprintf(stderr, "FAIL: Negative test got Passed \n"); goto err; } } if (print_output) tests_hexdump("Signature:", sig, sigLen); status = EVP_PKEY_verify(rsa_verify_ctx, sig, sigLen, HashData, 36); if (status <= 0) { WARN("# FAIL RSA - Verify Failed\n"); ret = 0; goto err; } else { DEBUG("----- RSA Verify completed ----- \n"); } if (print_output) tests_hexdump("HashData:", HashData, hash_length); } /*(!i || verify_only)*/ /*For functional tests we need to run encrypt anyway*/ if ((!i || encrypt_only) && (!sign_only && !verify_only)) { if (print_output) tests_hexdump("Plain text:", expectedPtext, expectedPlen); enc_ctx = EVP_PKEY_CTX_new(rsa_key, NULL); if ((enc_ctx == NULL) || (EVP_PKEY_encrypt_init(enc_ctx) <=0) || (EVP_PKEY_encrypt(enc_ctx, NULL, &clen, expectedPtext, 36)) <=0 ) { WARN("RSA Encrypt_init Failed\n"); ret = 0; goto err; } if (clen <= 0) { WARN("Cipher length less than zero\n"); ret = 0; goto err; } ctext = OPENSSL_malloc(clen); if (ctext == NULL) { WARN("Failed to allocate memory for ctext\n"); ret = 0; goto err; } status = EVP_PKEY_encrypt(enc_ctx, ctext, &clen, expectedPtext, 36); if (status <= 0) { WARN("# FAIL RSA - Encrypt Failed\n"); ret = 0; goto err; } else { DEBUG("----- RSA Encrypt completed ----- \n"); } if (print_output) tests_hexdump("Cipher text:", ctext, clen); } /* (!i || encrypt_only)*/ if ((!i || decrypt_only) && (!sign_only && !verify_only)) { if (print_output) tests_hexdump("Cipher text:", ctext, clen); dec_ctx = EVP_PKEY_CTX_new(rsa_key, NULL); if ((dec_ctx == NULL) || (EVP_PKEY_decrypt_init(dec_ctx)) <= 0 || (EVP_PKEY_decrypt(dec_ctx, NULL, &clen, ctext, clen) <=0)) { WARN("RSA Decrypt_init Failed\n"); ret = 0; goto err; } dtext = OPENSSL_zalloc(clen); if (dtext == NULL) { WARN("Failed to allocate memory for dtext\n"); ret = 0; goto err; } status = EVP_PKEY_decrypt(dec_ctx, dtext, &clen, ctext, clen); if (status <= 0) { WARN("# FAIL RSA - Decrypt Failed\n"); ret = 0; goto err; } else { DEBUG("----- RSA Decrypt completed ----- \n"); } if (print_output) tests_hexdump("Plain text:", expectedPtext, expectedPlen); } /*(!i || decrypt_only)*/ } /* count for-loop */ if (sign_only || verify_only || status) { INFO("# PASS %s for RSA with %s\n", sign_only ? "sign" : "verify", pad_str); } if (encrypt_only || decrypt_only || status) { /* Compare and verify the encrypted and decrypted message */ if (verify) { INFO("# PASS %s for RSA with %s\n", encrypt_only ? "encrypt" : "decrypt", pad_str); } } if (rsa_key) EVP_PKEY_free(rsa_key); #endif err: #ifdef QAT_OPENSSL_PROVIDER if (wrong_HashData) OPENSSL_free(wrong_HashData); if (rsa_sign_ctx) EVP_PKEY_CTX_free(rsa_sign_ctx); if (rsa_verify_ctx) EVP_PKEY_CTX_free(rsa_verify_ctx); if (enc_ctx) EVP_PKEY_CTX_free(enc_ctx); if (dec_ctx) EVP_PKEY_CTX_free(dec_ctx); if (dtext) OPENSSL_free(dtext); #else if (ptext) OPENSSL_free(ptext); #endif if(size < 8192) RSA_free(key); if (sig) OPENSSL_free(sig); if (verMsg) OPENSSL_free(verMsg); if (HashData) OPENSSL_free(HashData); if (expectedPtext) OPENSSL_free(expectedPtext); if (ctext) OPENSSL_free(ctext); return ret; } /****************************************************************************** * function: * tests_run_rsa (TEST_PARAMS *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ void tests_run_rsa(TEST_PARAMS *args) { int i; if (!args->sign_only && !args->verify_only && !args->encrypt_only && !args->decrypt_only) { args->rsa_all = 1; } for (i = 0; i < sizeof(padding) / sizeof(padding[0]); i++) { args->padding = padding[i]; if (((padding[i] == RSA_PKCS1_OAEP_PADDING) && (args->sign_only || args->verify_only || args->rsa_all)) || ((padding[i] == RSA_X931_PADDING) && (args->encrypt_only || args->decrypt_only || args->rsa_all))) continue; if (!args->enable_async) run_rsa(args); else start_async_job(args, run_rsa); } } qatengine-1.9.0/test/tests_sha2.c000066400000000000000000000212221500416242000166670ustar00rootroot00000000000000 /*************************************************************************** * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define SHA2_224_DIGEST_LENGTH 28 #define SHA2_256_DIGEST_LENGTH 32 #define SHA2_384_DIGEST_LENGTH 48 #define SHA2_512_DIGEST_LENGTH 64 unsigned char sha2_224_expected[] = { 0x27, 0x1E, 0x41, 0xDB, 0x21, 0x89, 0xDC, 0x9D, 0xB9, 0x4E, 0x7A, 0x56, 0x41, 0xDB, 0xF6, 0x78, 0x9D, 0xB6, 0x61, 0xDA, 0xDC, 0x24, 0x86, 0xEA, 0xEF, 0xB5, 0xFF, 0xD6, }; unsigned char sha2_256_expected[] = { 0xC6, 0x22, 0x00, 0x54, 0x93, 0xC4, 0xCB, 0x75, 0xF3, 0xE0, 0x8E, 0xDA, 0x4C, 0xC0, 0xBF, 0xE1, 0x72, 0xE2, 0xC5, 0xEE, 0xCA, 0x66, 0x1E, 0xC4, 0x90, 0x8C, 0x54, 0x90, 0xFC, 0x3D, 0x69, 0x94, }; unsigned char sha2_384_expected[] = { 0x49, 0x13, 0x44, 0x2B, 0x8D, 0x4C, 0xA7, 0x39, 0x98, 0x22, 0x98, 0x03, 0xFB, 0x3E, 0xEE, 0x49, 0x55, 0x5C, 0x16, 0x62, 0x38, 0x44, 0x54, 0x9D, 0xA5, 0x4E, 0x2C, 0xA3, 0x00, 0x63, 0xE3, 0x70, 0x00, 0xBB, 0x66, 0x38, 0xED, 0x89, 0x59, 0xFA, 0xC9, 0x90, 0xD6, 0x35, 0xC9, 0xB8, 0x42, 0x28, }; unsigned char sha2_512_expected[] = { 0x87, 0x73, 0xF7, 0xF1, 0x90, 0x99, 0x33, 0xF5, 0x96, 0x6C, 0xAE, 0xC1, 0x8F, 0x5B, 0xB1, 0x20, 0x09, 0x22, 0x81, 0xC0, 0xCC, 0x47, 0x33, 0x44, 0xA0, 0x82, 0x21, 0xAF, 0x3A, 0x0D, 0x5E, 0xE3, 0xD6, 0x3F, 0xFD, 0xBD, 0xEA, 0x86, 0xB9, 0xE4, 0x25, 0x58, 0x3F, 0xFA, 0x7B, 0x11, 0x8A, 0xEE, 0xED, 0x90, 0x65, 0x14, 0x35, 0x46, 0xCA, 0xD0, 0x08, 0xA9, 0x3D, 0x3E, 0x7F, 0x03, 0x18, 0xB2, }; /****************************************************************************** * function: * run_sha2(void *args) * * @param args [IN] - the test parameters * * Description: Runs SHA-2 tests for corresponding digest length ******************************************************************************/ static int run_sha2(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int count = *(temp_args->count); int size = temp_args->size; /* If temp_args->explicit_engine is not set then set the engine to NULL to allow fallback to software if that engine under test does not support this operation. This relies on the engine we are testing being set as the default engine. */ ENGINE *e = temp_args->explicit_engine ? temp_args->e : NULL; int print_output = temp_args->print_output; int verify = temp_args->verify; int i = 0; int inLen = size; int ret = 1; unsigned int digest_len = 0; unsigned char md[SHA2_512_DIGEST_LENGTH]; unsigned char *expected = NULL; /* Use default input size in verify mode. */ if (verify) inLen = 4096; unsigned char *inData = OPENSSL_malloc(inLen); if (inData == NULL) { fprintf(stderr, "# FAIL: [%s] --- inData malloc failed! \n", __func__); exit(EXIT_FAILURE); } /* Setup the input and output data. */ memset(inData, 0xaa, inLen); memset(md, 0x00, SHA2_512_DIGEST_LENGTH); for (i = 0; i < count; i++) { switch (temp_args->type) { case TEST_SHA2_224: DEBUG("\n----- SHA2_224 digest ----- \n\n"); digest_len = SHA2_224_DIGEST_LENGTH; expected = (void *)&sha2_224_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha224(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; case TEST_SHA2_256: DEBUG("\n----- SHA2_256 digest ----- \n\n"); digest_len = SHA2_256_DIGEST_LENGTH; expected = (void *)&sha2_256_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha256(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; case TEST_SHA2_384: DEBUG("\n----- SHA2_384 digest ----- \n\n"); digest_len = SHA2_384_DIGEST_LENGTH; expected = (void *)&sha2_384_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha384(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; case TEST_SHA2_512: DEBUG("\n----- SHA2_512 digest ----- \n\n"); digest_len = SHA2_512_DIGEST_LENGTH; expected = (void *)&sha2_512_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha512(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; } if (ret != 1 || verify) { /* Compare the digest results with the expected results. */ if (memcmp(md, expected, digest_len)) { fprintf(stderr, "# FAIL verify for %s.\n", test_name(temp_args->type)); tests_hexdump("SHA2 actual :", md, digest_len); tests_hexdump("SHA2 expected:", expected, digest_len); ret = 0; break; } else { fprintf(stderr, "# PASS verify for %s.\n", test_name(temp_args->type)); } } } /* count for-loop */ if (print_output) tests_hexdump("SHA2 digest text:", md, digest_len); if (inData) OPENSSL_free(inData); return ret; } /****************************************************************************** * function: * tests_run_sha2(TEST_PARAMS *args) * * @param args [IN] - the test parameters * * Description: * This function is designed to test the QAT engine with variable message sizes * using the SHA2 algorithm. The higher level EVP interface function EVP_Digest() * is used inside of test application. * This is a boundary test, the application should return the expected digest hash value. * In verify mode a input size of 1024 bytes is used to generate a comparison digest. ******************************************************************************/ void tests_run_sha2(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_sha2(args); else start_async_job(args, run_sha2); } qatengine-1.9.0/test/tests_sha3.c000066400000000000000000000211051500416242000166700ustar00rootroot00000000000000 /*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #define SHA3_224_DIGEST_LENGTH 28 #define SHA3_256_DIGEST_LENGTH 32 #define SHA3_384_DIGEST_LENGTH 48 #define SHA3_512_DIGEST_LENGTH 64 unsigned char sha3_224_expected[] = { 0x7C, 0x96, 0x7A, 0xDB, 0xB3, 0x77, 0x92, 0x68, 0x94, 0x4A, 0x15, 0xE4, 0x29, 0xD2, 0x5A, 0x62, 0xAA, 0x19, 0x7F, 0xFD, 0x51, 0x28, 0x38, 0xC2, 0x23, 0x58, 0x31, 0xED, }; unsigned char sha3_256_expected[] = { 0x9C, 0x8F, 0xEE, 0x6B, 0x6A, 0x7C, 0x0B, 0xD3, 0x7E, 0xD6, 0x83, 0xFC, 0x40, 0x6A, 0x8C, 0x1B, 0x1C, 0x2D, 0xE6, 0x1C, 0x76, 0xE0, 0xE6, 0xD3, 0x95, 0xDB, 0x93, 0x5E, 0x86, 0x17, 0x0D, 0xEC, }; unsigned char sha3_384_expected[] = { 0x6A, 0x11, 0x7F, 0x2D, 0xF7, 0x1B, 0xE3, 0x49, 0x9E, 0x05, 0xDC, 0x72, 0x1A, 0x75, 0x82, 0xAE, 0x5B, 0x10, 0x03, 0xF8, 0xE9, 0x97, 0x68, 0xAF, 0x6E, 0x0B, 0x36, 0xA6, 0xCA, 0xDF, 0x5B, 0x10, 0xB1, 0x9F, 0xA8, 0x78, 0xFA, 0x61, 0x4A, 0x20, 0x17, 0xE0, 0xAA, 0x7F, 0x58, 0xA9, 0xB5, 0x80, }; unsigned char sha3_512_expected[] = { 0xE8, 0xAC, 0xFF, 0xFB, 0x33, 0xEF, 0x29, 0x3F, 0xE6, 0x23, 0xD8, 0xEA, 0x8E, 0x4E, 0x45, 0x72, 0xA3, 0xD9, 0x15, 0x1D, 0xC9, 0x1E, 0x87, 0x93, 0x6B, 0xF1, 0xB3, 0x8C, 0x18, 0x60, 0x1A, 0x40, 0xF7, 0x03, 0x79, 0x3D, 0x48, 0x51, 0x4C, 0xA2, 0x53, 0x29, 0x47, 0x82, 0x4C, 0x1D, 0x2F, 0xEF, 0x25, 0x9D, 0xA1, 0x9C, 0xAF, 0x75, 0xE3, 0xC8, 0x4C, 0x5B, 0x56, 0xBE, 0xF7, 0x1D, 0xD9, 0xE3, }; /****************************************************************************** * function: * run_sha3(void *args) * * @param args [IN] - the test parameters * * Description: Runs SHA-3 tests for corresponding digest length ******************************************************************************/ static int run_sha3(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int count = *(temp_args->count); int size = temp_args->size; /* If temp_args->explicit_engine is not set then set the engine to NULL to allow fallback to software if that engine under test does not support this operation. This relies on the engine we are testing being set as the default engine. */ ENGINE *e = temp_args->explicit_engine ? temp_args->e : NULL; int print_output = temp_args->print_output; int verify = temp_args->verify; int i = 0; int inLen = size; int ret = 1; unsigned int digest_len = 0; unsigned char md[SHA3_512_DIGEST_LENGTH]; unsigned char *expected = NULL; /* Use default input size in verify mode. */ if (verify) inLen = 4096; unsigned char *inData = OPENSSL_malloc(inLen); if (inData == NULL) { fprintf(stderr,"# FAIL: [%s] --- inData malloc failed! \n", __func__); exit(EXIT_FAILURE); } /* Setup the input and output data. */ memset(inData, 0xaa, inLen); memset(md, 0x00, SHA3_512_DIGEST_LENGTH); for (i = 0; i < count; i++) { switch(temp_args->type) { case TEST_SHA3_224: DEBUG("\n----- SHA3_224 digest ----- \n\n"); digest_len = SHA3_224_DIGEST_LENGTH; expected = (void*) &sha3_224_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha3_224(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; case TEST_SHA3_256: DEBUG("\n----- SHA3_256 digest ----- \n\n"); digest_len = SHA3_256_DIGEST_LENGTH; expected = (void*) &sha3_256_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha3_256(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; case TEST_SHA3_384: DEBUG("\n----- SHA3_384 digest ----- \n\n"); digest_len = SHA3_384_DIGEST_LENGTH; expected = (void*) &sha3_384_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha3_384(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; case TEST_SHA3_512: DEBUG("\n----- SHA3_512 digest ----- \n\n"); digest_len = SHA3_512_DIGEST_LENGTH; expected = (void*) &sha3_512_expected; ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sha3_512(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ break; } if (ret != 1 || verify) { /* Compare the digest results with the expected results. */ if (memcmp(md, expected, digest_len)) { fprintf(stderr,"# FAIL verify for %s.\n", test_name(temp_args->type)); tests_hexdump("SHA3 actual :", md, digest_len); tests_hexdump("SHA3 expected:", expected, digest_len); ret = 0; break; } else { fprintf(stderr,"# PASS verify for %s.\n", test_name(temp_args->type)); } } } /* count for-loop */ if (print_output) tests_hexdump("SHA3 digest text:", md, digest_len); if (inData) OPENSSL_free(inData); return ret; } /****************************************************************************** * function: * tests_run_sha3(TEST_PARAMS *args) * * @param args [IN] - the test parameters * * Description: * This function is designed to test the QAT engine with variable message sizes * using the SHA3 algorithm. The higher level EVP interface function EVP_Digest() * is used inside of test application. * This is a boundary test, the application should return the expected digest hash value. * In verify mode a input size of 1024 bytes is used to generate a comparison digest. ******************************************************************************/ void tests_run_sha3(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_sha3(args); else { start_async_job(args, run_sha3); } } qatengine-1.9.0/test/tests_sm2.c000066400000000000000000000367241500416242000165500ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #ifndef OPENSSL_NO_SM2_SM3 #define SM2_ID "TLSv1.3+GM+Cipher+Suite" #define SM2_ID_LEN sizeof("TLSv1.3+GM+Cipher+Suite") - 1 static const char rnd_seed[] = "string to make the random number generator think it has entropy"; EVP_PKEY *get_sm2_key(const int nid) { EVP_PKEY *sm2_key = NULL; EVP_PKEY_CTX *kctx = NULL; kctx = EVP_PKEY_CTX_new_id(nid, NULL); if (kctx == NULL) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *params = NULL; /* Create the context for parameter generation */ #ifdef QAT_OPENSSL_3 pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); #else pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); #endif if ((pctx == NULL) || EVP_PKEY_paramgen_init(pctx) <= 0 || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0 || EVP_PKEY_paramgen(pctx, ¶ms) <= 0) { fprintf(stderr, "SM2 params init failure.\n"); EVP_PKEY_CTX_free(pctx); return NULL; } EVP_PKEY_CTX_free(pctx); /* Create the context for the key generation */ kctx = EVP_PKEY_CTX_new(params, NULL); EVP_PKEY_free(params); } if (kctx == NULL || EVP_PKEY_keygen_init(kctx) <= 0 || EVP_PKEY_keygen(kctx, &sm2_key) <= 0) { fprintf(stderr, "# FAIL SM2 keygen init failed\n"); sm2_key = NULL; } EVP_PKEY_CTX_free(kctx); return sm2_key; } #ifndef QAT_OPENSSL_3 static int test_sm2_sign_verify(int count, int size, ENGINE *e, int print_output, int verify, int nid, const char *curveName) { unsigned char digest[size], wrong_digest[size]; unsigned char *signature = NULL; BIO *out = NULL; int ret = 0, i; char buf[256]; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *sm2_pctx = NULL; EVP_PKEY_CTX *sm2_vfy_pctx = NULL; EVP_PKEY *sm2_pkey = NULL; EVP_MD_CTX *sm2_ctx = EVP_MD_CTX_new(); EVP_MD_CTX *sm2_vfy_ctx = EVP_MD_CTX_new(); size_t sigsize = 0; out = BIO_new(BIO_s_file()); if (out == NULL) { WARN("# FAIL: Unable to create BIO\n"); exit(1); } BIO_set_fp(out, stdout, BIO_NOCLOSE); /* fill digest values with some random data */ if ((RAND_bytes(digest, size) <= 0) || (RAND_bytes(wrong_digest, size) <= 0)) { WARN("# FAIL: unable to get random data\n"); ret = -1; goto builtin_err; } /* SM2 keys are generated as normal EC keys with a special curve */ if (((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) || (EVP_PKEY_keygen_init(pctx) <= 0) || (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0) || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0) { ret = -1; EVP_PKEY_CTX_free(pctx); goto builtin_err; } EVP_PKEY_CTX_free(pctx); sigsize = ECDSA_size(EVP_PKEY_get0_EC_KEY(sm2_pkey)); if (!EVP_PKEY_set_alias_type(sm2_pkey, EVP_PKEY_SM2)) { ret = -1; WARN("# FAIL: EVP_PKEY set allias type Failed\n"); goto builtin_err; } sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); if (sm2_pctx == NULL) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX Alloc Failure\n"); goto builtin_err; } sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); if (sm2_vfy_pctx == NULL) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX Alloc Failure\n"); goto builtin_err; } if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX_set1_id Failure\n"); goto builtin_err; } if (EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX_set1_id Failure\n"); goto builtin_err; } EVP_MD_CTX_set_pkey_ctx(sm2_ctx, sm2_pctx); EVP_MD_CTX_set_pkey_ctx(sm2_vfy_ctx, sm2_vfy_pctx); if (!EVP_DigestSignInit(sm2_ctx, NULL, EVP_sm3(), NULL, sm2_pkey)) { ret = -1; WARN("# FAIL: EVP_DigestSignInit Failed\n"); goto builtin_err; } if (!EVP_DigestVerifyInit(sm2_vfy_ctx, NULL, EVP_sm3(), NULL, sm2_pkey)) { ret = -1; WARN("# FAIL: EVP_DigestVerifyInit Failed\n"); goto builtin_err; } if ((signature = OPENSSL_malloc(sigsize)) == NULL) { ret = -1; WARN("# FAIL: failed to malloc signature\n"); goto builtin_err; } if (print_output) printf("%s\n", OBJ_nid2sn(nid)); for (i = 0; i < count; ++i) { if (!EVP_DigestSign(sm2_ctx, signature, &sigsize, digest, 20)) { WARN("# FAIL: Failed to Sign\n"); ret = -1; goto builtin_err; } if (print_output) { BIO_puts(out, "SM2_sign signature: "); for (i = 0; i < sigsize; i++) { sprintf(buf, "%02X ", signature[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); } /* Verify Signature */ if (EVP_DigestVerify(sm2_vfy_ctx, signature, sigsize, digest, 20) != 1) { WARN("# FAIL: Failed to verify\n"); ret = -1; goto builtin_err; } } /* Verify Signature with a wrong digest */ if (EVP_DigestVerify(sm2_vfy_ctx, signature, sigsize, wrong_digest, 20) == 1) { WARN("# FAIL: Verified with wrong digest\n"); ret = -1; goto builtin_err; } builtin_err: if (sm2_pkey) EVP_PKEY_free(sm2_pkey); if (sm2_pctx) EVP_PKEY_CTX_free(sm2_pctx); if (sm2_vfy_pctx) EVP_PKEY_CTX_free(sm2_vfy_pctx); if (sm2_ctx) EVP_MD_CTX_free(sm2_ctx); if (sm2_vfy_ctx) EVP_MD_CTX_free(sm2_vfy_ctx); if (signature) OPENSSL_free(signature); BIO_free(out); if (0 == ret) INFO("# PASS SM2 Sign/Verify for nid %s\n", curveName); else INFO("# FAIL SM2 Sign/Verify for nid %s\n", curveName); return ret; } #else static int test_sm2_sign_verify(int count, int size, ENGINE *e, int print_output, int verify, int nid, const char *curveName) { unsigned char digest[size], wrong_digest[size]; unsigned char *signature = NULL; BIO *out = NULL; int ret = 0, i; char buf[256]; EVP_PKEY_CTX *pctx = NULL; EVP_PKEY_CTX *sm2_pctx = NULL; EVP_PKEY_CTX *sm2_vfy_pctx = NULL; EVP_PKEY *sm2_pkey = NULL; EVP_MD_CTX *sm2_ctx = EVP_MD_CTX_new(); EVP_MD_CTX *sm2_vfy_ctx = EVP_MD_CTX_new(); size_t sigsize = 0; out = BIO_new(BIO_s_file()); if (out == NULL) { WARN("# FAIL: Unable to create BIO\n"); exit(1); } BIO_set_fp(out, stdout, BIO_NOCLOSE); /* fill digest values with some random data */ if ((RAND_bytes(digest, size) <= 0) || (RAND_bytes(wrong_digest, size) <= 0)) { WARN("# FAIL: unable to get random data\n"); ret = -1; goto builtin_err; } /* SM2 keys are generated as normal EC keys with a special curve */ if (((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, NULL)) == NULL) || (EVP_PKEY_keygen_init(pctx) <= 0) || (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0) || EVP_PKEY_keygen(pctx, &sm2_pkey) <= 0) { ret = -1; EVP_PKEY_CTX_free(pctx); goto builtin_err; } EVP_PKEY_CTX_free(pctx); sigsize = EVP_PKEY_get_size(sm2_pkey); sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); if (sm2_pctx == NULL) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX Alloc Failure\n"); goto builtin_err; } sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL); if (sm2_vfy_pctx == NULL) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX Alloc Failure\n"); goto builtin_err; } if (EVP_PKEY_CTX_set1_id(sm2_pctx, SM2_ID, SM2_ID_LEN) != 1) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX_set1_id Failure\n"); goto builtin_err; } if (EVP_PKEY_CTX_set1_id(sm2_vfy_pctx, SM2_ID, SM2_ID_LEN) != 1) { ret = -1; WARN("# FAIL: EVP_PKEY_CTX_set1_id Failure\n"); goto builtin_err; } EVP_MD_CTX_set_pkey_ctx(sm2_ctx, sm2_pctx); EVP_MD_CTX_set_pkey_ctx(sm2_vfy_ctx, sm2_vfy_pctx); if (!EVP_DigestSignInit(sm2_ctx, NULL, EVP_sm3(), NULL, sm2_pkey)) { ret = -1; WARN("# FAIL: EVP_DigestSignInit Failed\n"); goto builtin_err; } if (!EVP_DigestVerifyInit(sm2_vfy_ctx, NULL, EVP_sm3(), NULL, sm2_pkey)) { ret = -1; WARN("# FAIL: EVP_DigestVerifyInit Failed\n"); goto builtin_err; } if ((signature = OPENSSL_malloc(sigsize)) == NULL) { ret = -1; WARN("# FAIL: failed to malloc signature\n"); goto builtin_err; } if (print_output) printf("%s\n", OBJ_nid2sn(nid)); for (i = 0; i < count; ++i) { if (!EVP_DigestSign(sm2_ctx, signature, &sigsize, digest, 20)) { WARN("# FAIL: Failed to Sign\n"); ret = -1; goto builtin_err; } if (print_output) { BIO_puts(out, "SM2_sign signature: "); for (i = 0; i < sigsize; i++) { sprintf(buf, "%02X ", signature[i]); BIO_puts(out, buf); } BIO_puts(out, "\n"); } /* Verify Signature */ if (EVP_DigestVerify(sm2_vfy_ctx, signature, sigsize, digest, 20) != 1) { WARN("# FAIL: Failed to verify\n"); ret = -1; goto builtin_err; } } /* Verify Signature with a wrong digest */ if (EVP_DigestVerify(sm2_vfy_ctx, signature, sigsize, wrong_digest, 20) == 1) { WARN("# FAIL: Verified with wrong digest\n"); ret = -1; goto builtin_err; } builtin_err: if (sm2_pkey) EVP_PKEY_free(sm2_pkey); if (sm2_pctx) EVP_PKEY_CTX_free(sm2_pctx); if (sm2_vfy_pctx) EVP_PKEY_CTX_free(sm2_vfy_pctx); if (sm2_ctx) EVP_MD_CTX_free(sm2_ctx); if (sm2_vfy_ctx) EVP_MD_CTX_free(sm2_vfy_ctx); if (signature) OPENSSL_free(signature); BIO_free(out); if (0 == ret) INFO("# PASS SM2 Sign/Verify for nid %s\n", curveName); else INFO("# FAIL SM2 Sign/Verify for nid %s\n", curveName); return ret; } #endif /****************************************************************************** * function: * test_sm2 (int count, * int size, * engine *e, * int print_output, * int verify, * int curveType, * int ne) * * @param count [IN] - number of iterations * @param size [IN] - the length of input message * @param e [IN] - OpenSSL engine pointer * @param print_output [IN] - print hex output flag * @param verify [IN] - verify flag * @param nid [IN] - nid to be used * @param curveName [IN] - curve name to be used * * description: * SM2 Sign and Verify Test * ******************************************************************************/ static int test_sm2(int count, int size, ENGINE *e, int print_output, int verify, int curveType, int ne) { BIO *out = NULL; int nid = NID_sm2; const char *curveName = "SM2 Curve"; out = BIO_new(BIO_s_file()); if (out == NULL) { WARN("# FAIL: Unable to create BIO\n"); exit(1); } BIO_set_fp(out, stdout, BIO_NOCLOSE); BIO_free(out); return test_sm2_sign_verify(count, size, e, print_output, verify, nid, curveName); } /****************************************************************************** * function: * tests_run_sm2(void *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ static int run_sm2(void *args) { int i = 0; int ret = 1; TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int count = *(temp_args->count); int size = temp_args->size; /* * If temp_args->explicit_engine is not set then set the * engine to NULL to allow fallback to software if * that engine under test does not support this operation. * This relies on the engine we are testing being * set as the default engine. */ ENGINE *e = temp_args->explicit_engine ? temp_args->e : NULL; int print = temp_args->print_output; int verify = temp_args->verify; int curve = temp_args->curve; int ne = 0; #if CPA_CY_API_VERSION_NUM_MAJOR < 3 ne = temp_args->enable_negative; #endif RAND_seed(rnd_seed, sizeof(rnd_seed)); if (!curve) { for (i = 1; i < CURVE_TYPE_MAX; i++) { if (test_sm2(count, size, e, print, verify, i, ne) < 0) ret = 0; } } else if (test_sm2(count, size, e, print, verify, curve, ne) < 0) { ret = 0; } return ret; } /****************************************************************************** * function: * tests_run_sm2(TEST_PARAMS *args) * * @param args [IN] - the test parameters * * description: * specify a test case * ******************************************************************************/ void tests_run_sm2(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) run_sm2(args); else start_async_job(args, run_sm2); } #endif /* OPENSSL_NO_SM2_SM3 */ qatengine-1.9.0/test/tests_sm3.c000066400000000000000000000251021500416242000165350ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2021-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #ifndef OPENSSL_NO_SM2_SM3 #define SM3_DIGEST_LENGTH 32 typedef struct DIGEST_CASE { int len; unsigned char expected[SM3_DIGEST_LENGTH]; } digest_case; static int run_sm3_msg_once(void *args, int inLen, unsigned char expected[]) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int count = *(temp_args->count); /* If temp_args->explicit_engine is not set then set the engine to NULL to allow fallback to software if that engine under test does not support this operation. This relies on the engine we are testing being set as the default engine. */ ENGINE *e = temp_args->explicit_engine ? temp_args->e : NULL; int print_output = temp_args->print_output; int verify = temp_args->verify; int i = 0; int ret = 1; unsigned char md[SM3_DIGEST_LENGTH]; unsigned char *inData = NULL; if (inLen) { inData = OPENSSL_malloc(inLen); memset(inData, 0xaa, inLen); } /* Setup the input and output data. */ memset(md, 0x00, SM3_DIGEST_LENGTH); for (i = 0; i < count; i++) { ret = EVP_Digest(inData, /* Input data pointer. */ inLen, /* Input data length. */ md, /* Output hash pointer. */ NULL, EVP_sm3(), /* Hash algorithm indicator. */ e); /* Engine indicator. */ if (ret != 1 || verify) { /* Compare the digest results with the expected results. */ if (memcmp(md, expected, SM3_DIGEST_LENGTH)) { fprintf(stderr, "# FAIL verify for SM3.\n"); ret = 0; tests_hexdump("SM3 actual :", md, SM3_DIGEST_LENGTH); tests_hexdump("SM3 expected:", expected, SM3_DIGEST_LENGTH); break; } else { fprintf(stderr, "# PASS verify for SM3 dgst %d bytes.\n", inLen); } } } /* count for-loop */ if (print_output) tests_hexdump("SM3 digest text:", md, SM3_DIGEST_LENGTH); if (inData) OPENSSL_free(inData); return ret; } static int run_sm3_hmac_once(void *args, int inLen, unsigned char expected[]) { TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int count = *(temp_args->count); int print_output = temp_args->print_output; int verify = temp_args->verify; int i = 0; int ret = 1; unsigned char *result = NULL; unsigned char md[SM3_DIGEST_LENGTH]; unsigned char *inData = NULL; unsigned int md_len = 0; static const unsigned char dummy_key[1] = { '\0' }; if (inLen) { inData = OPENSSL_malloc(inLen); memset(inData, 0xaa, inLen); } /* Setup the input and output data. */ memset(md, 0x00, SM3_DIGEST_LENGTH); for (i = 0; i < count; i++) { result = HMAC(EVP_sm3(), /* Hash function */ dummy_key, /* Key */ 0, /* Key length */ inData, /* Input data */ inLen, /* Input data length */ md, /* HMAC result */ &md_len /* HMAC result length */ ); if (result == NULL || verify) { /* Compare the digest results with the expected results. */ if (memcmp(md, expected, SM3_DIGEST_LENGTH)) { fprintf(stderr, "# FAIL verify for SM3.\n"); ret = 0; tests_hexdump("SM3 actual :", md, SM3_DIGEST_LENGTH); tests_hexdump("SM3 expected:", expected, SM3_DIGEST_LENGTH); break; } else { fprintf(stderr, "# PASS verify for SM3 HMAC %d bytes.\n", inLen); } } } /* count for-loop */ if (print_output) tests_hexdump("SM3 digest text:", md, SM3_DIGEST_LENGTH); if (inData) OPENSSL_free(inData); return ret; } /****************************************************************************** * function: * run_sm3_msg (void *args) * * @param args [IN] - the test parameters * * Description: ******************************************************************************/ static int run_sm3_msg(void *args) { digest_case cases[] = { {0, /* length = 0 */ { 0x1A, 0xB2, 0x1D, 0x83, 0x55, 0xCF, 0xA1, 0x7F, 0x8E, 0x61, 0x19, 0x48, 0x31, 0xE8, 0x1A, 0x8F, 0x22, 0xBE, 0xC8, 0xC7, 0x28, 0xFE, 0xFB, 0x74, 0x7E, 0xD0, 0x35, 0xEB, 0x50, 0x82, 0xAA, 0x2B, } }, {1024, /* length = 1024 */ { 0x69, 0xA5, 0xCF, 0x23, 0x25, 0x4A, 0x38, 0x54, 0x03, 0xA6, 0xA8, 0x98, 0x88, 0xCC, 0x3F, 0x9E, 0xC7, 0x03, 0x11, 0x7E, 0xD9, 0xFC, 0x06, 0xDE, 0x77, 0x1B, 0x31, 0x86, 0x02, 0x28, 0xA6, 0x69, } }, {1 * 1024 * 1024, /* length = 1M */ { 0x47, 0x8D, 0xA3, 0x3C, 0x71, 0xED, 0xC9, 0x50, 0x6D, 0x75, 0xE9, 0xDF, 0xA1, 0xD3, 0xDB, 0xA2, 0x8B, 0x12, 0x48, 0x7A, 0x38, 0x37, 0xEC, 0xC5, 0xA9, 0x58, 0xFE, 0x3B, 0xD2, 0x00, 0x06, 0x8D, } }, {-1, {}} /* end */ }; TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int verify = temp_args->verify; int inLen = temp_args->size; int ret = 1; DEBUG("\n----- SM3 digest msg ----- \n\n"); if (verify) { int i; for (i = 0; /* */ ; i++) { if (cases[i].len == -1) break; ret = run_sm3_msg_once(args, cases[i].len, cases[i].expected); if (ret != 1) break; } } else { ret = run_sm3_msg_once(args, inLen, NULL); } return ret; } /****************************************************************************** * function: * run_sm3_hmac (void *args) * * @param args [IN] - the test parameters * * Description: ******************************************************************************/ static int run_sm3_hmac(void *args) { digest_case cases[] = { {0, /* length = 0 */ { 0x0D, 0x23, 0xF7, 0x2B, 0xA1, 0x5E, 0x9C, 0x18, 0x9A, 0x87, 0x9A, 0xEF, 0xC7, 0x09, 0x96, 0xB0, 0x60, 0x91, 0xDE, 0x6E, 0x64, 0xD3, 0x1B, 0x7A, 0x84, 0x00, 0x43, 0x56, 0xDD, 0x91, 0x52, 0x61, } }, {1024, /* length = 1024 */ { 0x3C, 0xC4, 0xDA, 0x4C, 0xED, 0x9C, 0xD9, 0x71, 0xFE, 0x9C, 0x08, 0x4B, 0x43, 0x49, 0x02, 0x61, 0x4E, 0x21, 0xC7, 0x3F, 0x8D, 0xFF, 0x61, 0x51, 0x1F, 0x6F, 0x6B, 0x31, 0xC1, 0xE8, 0xBD, 0x55, } }, {1 * 1024 * 1024, /* length = 1M */ { 0x95, 0xC9, 0x06, 0xBE, 0x01, 0x21, 0x14, 0xA4, 0x0D, 0x3F, 0xFA, 0x9B, 0x1E, 0x50, 0x26, 0x6F, 0xDE, 0x2B, 0x30, 0x26, 0x81, 0x53, 0x98, 0x75, 0xC8, 0x47, 0x91, 0x1E, 0x74, 0x8A, 0x17, 0xC3, } }, {-1, {}} /* end */ }; TEST_PARAMS *temp_args = (TEST_PARAMS *) args; int verify = temp_args->verify; int inLen = temp_args->size; int ret = 1; DEBUG("\n----- SM3 HMAC msg ----- \n\n"); if (verify) { int i; for (i = 0; /* */ ; i++) { if (cases[i].len == -1) break; ret = run_sm3_hmac_once(args, cases[i].len, cases[i].expected); if (ret != 1) break; } } else { ret = run_sm3_hmac_once(args, inLen, NULL); } return ret; } /****************************************************************************** * function: * tests_run_sm3 (TEST_PARAMS *args) * * @param args [IN] - the test parameters * * Description: * This function is designed to test the QAT engine with variable message sizes * using the SM3 algorithm. The higher level EVP interface function EVP_Digest() * is used inside of test application. * This is a boundary test, the application should return the expected digest hash value. * In verify mode a input size of 1024 bytes is used to generate a comparison digest. ******************************************************************************/ void tests_run_sm3(TEST_PARAMS *args) { args->additional_args = NULL; if (!args->enable_async) { run_sm3_msg(args); run_sm3_hmac(args); } else { start_async_job(args, run_sm3_msg); start_async_job(args, run_sm3_hmac); } } #endif /* OPENSS_NOS_SM2_SM3 */ qatengine-1.9.0/test/tests_sm4_cbc.c000066400000000000000000001102561500416242000173520ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #ifdef QAT_OPENSSL_3 # include #endif #include "tests.h" #define ALGO_ENABLE_MASK_SM4 0x1000 extern char *sw_algo_bitmap; extern char *hw_algo_bitmap; #ifdef ENABLE_QAT_HW_SM4_CBC #include #include #include "../qat_utils.h" #endif #ifdef ENABLE_QAT_SW_SM4_CBC /* Crypto_mb includes */ #include "crypto_mb/sm4.h" #include "crypto_mb/cpu_features.h" #endif #ifdef ENABLE_QAT_SW_SM4_CBC #define SM4_CBC_KEY_SIZE (16) #define SM4_CBC_IV_SIZE (16) #define MULTIBUFF_SM4_BATCH (16) #endif #ifdef ENABLE_QAT_HW_SM4_CBC #define ENC 1 #define DEC 0 #define USE_ENGINE 1 #define USE_SW 0 #define NON_TLS 0 #define EVP_FAIL -1 #define TLS_HDR_MODIFY_SEQ 0x01 #define NO_HMAC_KEY 0x02 #define NO_AAD 0x04 #define DEF_CFG 0x00 #define ENCRYPT_BUFF_ERROR 0 #define ENCRYPT_BUFF_IDENTICAL 1 #define ENCRYPT_BUFF_DIFFERENT 2 #define FAIL_MSG(fmt, args...) WARN( "# FAIL " fmt, ##args) #define FAIL_MSG_END(fmt, args...) INFO( "# FAIL " fmt, ##args) #define PASS_MSG(fmt, args...) INFO( "# PASS " fmt, ##args) /* AES key, 256 bits long */ static const unsigned char _key16[] = { 0xEE, 0xE2, 0x7B, 0x5B, 0x10, 0xFD, 0xD2, 0x58, 0x49, 0x77, 0xF1, 0x22, 0xD7, 0x1B, 0xA4, 0xCA}; /* Initialization vector */ static const unsigned char _ivec[] = { 0x7E, 0x9B, 0x4C, 0x1D, 0x82, 0x4A, 0xC5, 0xDF, 0x99, 0x4C, 0xA1, 0x44, 0xAA, 0x8D, 0x37, 0x27}; typedef struct _sm4_alg_info { int testtype; /* Indicates the sm4 cipher algorithm */ const EVP_CIPHER *(*pfunc) (void); /* function to get cipher object */ const unsigned char *key; /* Key to use for cipher op */ const char *name; /* Name to use in console messages */ } sm4_alg_info; typedef struct _test_info_ { int bufsz; int count; ENGINE *e; sm4_alg_info *c; } test_info; static const sm4_alg_info alg_i[] = { {TEST_SM4_CBC, EVP_sm4_cbc, _key16, "SM4-CBC"}, }; /* get_alg_info: * for a given testtype, returns the related info structure. */ static const sm4_alg_info *get_alg_info(int testtype) { const int num = sizeof(alg_i) / sizeof(sm4_alg_info); int i; for (i = 0; i < num; i++) { if (alg_i[i].testtype == testtype) return &alg_i[i]; } return NULL; } /* * set_pkt_threshold: * Set the small packet threshold value for given cipher. * Buffers with size greater than the threshold value are * offloaded to QAT engine for processing. */ static inline int set_pkt_threshold(ENGINE *e, const char* cipher, int thr) { char thr_str[128]; int ret = 0; snprintf(thr_str, 128, "%s:%d", cipher, thr); ret = ENGINE_ctrl_cmd(e, "SET_CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD", 0, (void *)thr_str, NULL, 0); if (ret != 1) FAIL_MSG("Failed to set threshold %d for cipher %s\n", thr, cipher); return ret; } /* * setup_ctx: * Setup cipher context ready to be used in a cipher operation. * It also sets up additional information required i.e. tls headers. */ static EVP_CIPHER_CTX *setup_ctx(const test_info *t, int enc, int e) { EVP_CIPHER_CTX *ctx = NULL; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return NULL; if (EVP_CipherInit_ex(ctx, t->c->pfunc(), e == USE_ENGINE ? t->e : NULL, t->c->key, _ivec, enc) != 1) goto err; return ctx; err: EVP_CIPHER_CTX_free(ctx); return NULL; } /* * perform_op: * performs the following operations: * 1. Allocate buffers for input and output. * 2. Populate input buffer with sample data. * 3. Perform cipher operation (populates output buffer) * 4. Convey result, numbytes operated and allocated buffers */ static int perform_op(EVP_CIPHER_CTX *ctx, unsigned char **in, unsigned char **out, unsigned int size, int *nbytes) { int s, i; int ret = 0; unsigned char *inb = NULL; unsigned char *outb = NULL; int enc = EVP_CIPHER_CTX_encrypting(ctx); if (in == NULL || out == NULL || nbytes == NULL) return 0; *nbytes = 0; /* Allocate and fill src buffer if encrypting */ if (enc == 1 && *in == NULL) { *in = inb = OPENSSL_malloc(size); if (inb == NULL) return 0; /* setup input message values */ for (i = 0; i < size; i++) inb[i] = i % 16; } else { /* Decrypt the src buffer contents */ inb = *in; } if (*out == NULL) { *out = outb = inb; if (outb == NULL) goto err; } else { outb = *out; } /* perform the operation */ s = EVP_CipherUpdate(ctx, outb, nbytes, inb, size); if (s != 1) { ret = EVP_FAIL; goto err; } return 1; err: return ret; } /* * encrypt_buff : * For a given TLS version, allocate and encrypt * buffer. Return pointers to buffers along with * number of bytes encrypted and ivlen used. */ static int encrypt_buff(const test_info *t, int impl, unsigned char **buf, unsigned char **encbuf, int *num_encbytes, unsigned int *ivlen) { int ret = 0; int size = t->bufsz; char msgstr[128]; EVP_CIPHER_CTX *ctx = NULL; ctx = setup_ctx(t, ENC, impl); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } ret = perform_op(ctx, buf, encbuf, size, num_encbytes); if (ret == 1 && *num_encbytes != size) printf("%s: nbytes %d != outl %d\n", msgstr, *num_encbytes, size); EVP_CIPHER_CTX_free(ctx); return ret; } /* * decrypt_buff : * Given a pointer to encrypted buffer encbuf, decrypt using * implementation as specified by impl. */ static int decrypt_buff(const test_info *t, int impl, unsigned char **encbuf, unsigned char **decbuf, int len) { int ret = 0; int num_decbytes = 0; #if defined(QAT_WARN) || defined(QAT_DEBUG) char msgstr[128]; #endif EVP_CIPHER_CTX *ctx = NULL; ctx = setup_ctx(t, DEC, impl); if (ctx == NULL) { FAIL_MSG("%s failed to setup dec context\n", msgstr); return -1; } ret = perform_op(ctx, encbuf, decbuf, len, &num_decbytes); EVP_CIPHER_CTX_free(ctx); return ret; } /* * encrypt_and_compare : * Encrypt a test buffer using engine and openssl sw * implementation. Compare the output and return * ENCRYPT_BUFF_ERROR : Error * ENCRYPT_BUFF_IDENTICAL : ENC buffers are byte identical * ENCRYPT_BUFF_DIFFERENT : ENC buffers not byte identical * for first ivlen bytes and engine * enc buffer has explicit IV as plain text. */ static int encrypt_and_compare(const test_info *t, int *buflen) { int ret = ENCRYPT_BUFF_ERROR; unsigned char *textbuf = NULL; unsigned char *eng_buf = NULL; unsigned char *sw_buf = NULL; int eng_opbytes, sw_opbytes; unsigned int ivlen = 0; if ( t == NULL || buflen == NULL) return ret; *buflen = 0; if (encrypt_buff(t, USE_ENGINE, &textbuf, &eng_buf, &eng_opbytes, &ivlen) != 1) { FAIL_MSG("%s: failed to perform Encryption using Engine!\n", __func__); goto err; } if (encrypt_buff(t, USE_SW, &textbuf, &sw_buf, &sw_opbytes, &ivlen) != 1) { FAIL_MSG("%s: failed to perform Encryption using SW!\n", __func__); goto err; } if (eng_opbytes != sw_opbytes) { FAIL_MSG("%s: Num Encrypted bytes Engine[%d] != SW[%d]\n", __func__, eng_opbytes, sw_opbytes); goto err; } *buflen = eng_opbytes; /* * OpenSSL SW implementation encrypts the Explicit IV and PAYLOAD * using the IV placed in CTX which may or maynot be explicit IV. * whereas QAT engine encrypts the PAYLOAD alone using the * Explicit IV. Hence the encrypted bytes differ. * This is true for TLS >= 1.1 */ if (!memcmp(eng_buf, sw_buf, eng_opbytes)) { /* the buffers are byte identical for entire length */ ret = ENCRYPT_BUFF_IDENTICAL; } else { /* * explicit IV encoded is byte identical but encrypted payload is * different. This is an error condition. */ FAIL_MSG("[%s:%s]verify failed for ENGINE and SW Encrypt", __func__, t->c->name); tests_hexdump("SM4-CBC ENGINE :", eng_buf, eng_opbytes); tests_hexdump("SM4-CBC SW:", sw_buf, eng_opbytes); ret = ENCRYPT_BUFF_ERROR; } err: OPENSSL_free(textbuf); return ret; } /* * test_crypto_op : * test chained ciphers crypto operation. * depending on the enc_imp/dec_imp, use either a engine or * software implementation to perform encryption/decryption. * if DEC_imp(ENC_imp(text)) = text, then report success else * fail. */ static int test_crypto_op(const test_info *t, int enc_imp, int dec_imp) { int ret = 0; unsigned int ivlen = 0; int num_encbytes; #if defined(QAT_WARN) || defined(QAT_DEBUG) char msgstr[128]; #endif unsigned char *textbuf = NULL; unsigned char *encbuf = NULL; unsigned char *decbuf = NULL; /* Get an encrypted buffer along with it's plain text */ ret = encrypt_buff(t, enc_imp, &textbuf, &encbuf, &num_encbytes, &ivlen); if (ret != 1) { FAIL_MSG("%s failed to perform Encryption!\n", msgstr); goto err; } /* Decrypt the encrypted buffer above and get decrpyted contents */ ret = decrypt_buff(t, dec_imp, &encbuf, &decbuf, num_encbytes); if (ret != 1) { FAIL_MSG("%s failed to perform Decryption!\n", msgstr); goto err; } /* Compare and verify the decrypt and encrypt message. */ if (memcmp(decbuf, textbuf, t->bufsz)) { FAIL_MSG("verify failed for %s", msgstr); tests_hexdump("SM4-CBC actual :", decbuf , t->bufsz); tests_hexdump("SM4-CBC expected:", textbuf, t->bufsz); goto err; } ret = 1; err: OPENSSL_free(textbuf); return ret; } /* * test_multi_op : * Perform the cipher operation multiple times with the same ctx. */ static int test_multi_op(const test_info *t) { int ret = 0; int size = t->bufsz; char msgstr[128]; int i = 0; EVP_CIPHER_CTX *ctx = NULL; unsigned char *buf[6] = { NULL }; unsigned char *ebuf[6] = { NULL }; int num_encbytes[6] = { 0 }; ctx = setup_ctx(t, ENC, USE_SW); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } for (i = 0; i < 6; i++) { ret = perform_op(ctx, &buf[i], &ebuf[i], size, &num_encbytes[i]); if (ret != 1) { FAIL_MSG("%s: Failed to encrypt %d time", msgstr, i); goto err; } if (ret == 1 && num_encbytes[i] != size) printf("%s[%d time]: nbytes %d != outl %d\n", msgstr, i, num_encbytes[i], size); } err: EVP_CIPHER_CTX_free(ctx); for (i = 0; i < 6; i++) { OPENSSL_free(buf[i]); } return ret; } static int test_performance_encrypt(const test_info *t) { int ret = 0; int size = t->bufsz; char msgstr[128]; int i = 0; EVP_CIPHER_CTX *ctx = NULL; unsigned char *buf = NULL; unsigned char *ebuf = NULL; int num_encbytes = 0; ctx = setup_ctx(t, ENC, USE_ENGINE); if (ctx == NULL) { FAIL_MSG("%s failed to setup enc context\n", msgstr); return -1; } for (i = 0; i < t->count; i++) { ret = perform_op(ctx, &buf, &ebuf, size, &num_encbytes); if (ret != 1) { FAIL_MSG("%s: Failed to encrypt %d time", msgstr, i); goto err; } if (ret == 1 && num_encbytes != size) printf("%s[%d time]: nbytes %d != outl %d\n", msgstr, i, num_encbytes, size); } err: EVP_CIPHER_CTX_free(ctx); OPENSSL_free(buf); OPENSSL_free(ebuf); return ret; } /* * test_encrpted_buffer : * Encrypty buffer using ENGINE and Openssl SW * implementation and check if they are byte identical. */ static int test_encrypted_buffer(const test_info *t) { int ret = 0; int buflen = 0; ret = encrypt_and_compare(t, &buflen); if (ret == ENCRYPT_BUFF_IDENTICAL) { ret = 1; } else { FAIL_MSG("verify failed ENGINE and SW Encrypt" " does match for %s\n", t->c->name); } return ret; } static int test_small_pkt_offload(const test_info *t) { int ret = 0; #if defined(QAT_WARN) || defined(QAT_DEBUG) int run = 0; char msgstr[128]; #endif int buflen = 0; int status = 0; /* * Engine was configured at the start of test run to offload all packets * to engine */ ret = encrypt_and_compare(t, &buflen); /* Check if SW and Engine implementation are different and valid */ if (ret != ENCRYPT_BUFF_IDENTICAL) { FAIL_MSG("%s encrypted buffers not identical status:%d run:%d\n", msgstr, ret, ++run); return status; } /* * The threshold value is matched against the buffer length to decide * whether to offload the packet to engine or sw. The buffer length is * greater than the payload length as it also includes space for iv, hmac * and padding. * set threshold to the buflen. */ ret = set_pkt_threshold(t->e, t->c->name, buflen); if (ret != 1) goto end; /* * As buffers greater than threshold size are offloaded to Qat engine, * the engine will use the software implementation for all buffers less than * or equal to threshold. As a result, encrypting via engine or through * software will create byte identical encrypted buffers. */ ret = encrypt_and_compare(t, &buflen); /* check if SW and Engine implementation byte identical */ if (ret != ENCRYPT_BUFF_IDENTICAL) { FAIL_MSG("%s Encrypted buffers not identical status:%d run:%d\n", msgstr, ret, ++run); goto end; } /* * If negative values are send for threshold, the engine cntrl sets the * threshold back to zero. All buffers are then offloaded to qat. */ ret = set_pkt_threshold(t->e, t->c->name, -312); if (ret != 1) goto end; ret = encrypt_and_compare(t, &buflen); if (ret != ENCRYPT_BUFF_IDENTICAL) { FAIL_MSG("%s encrypted buffers not identical status:%d run:%d\n", msgstr, ret, ++run); goto end; } /* * The upper limit for threshold values is 16384. If a value greater than * upper limit is provided, the threshold is set to 16384. No buffers are * then offloaded to the engine as the maximum size of TLS payload is 16384. */ ret = set_pkt_threshold(t->e, t->c->name, 17000); if (ret != 1) goto end; ret = encrypt_and_compare(t, &buflen); if (ret != ENCRYPT_BUFF_IDENTICAL) { FAIL_MSG("%s Encrypted buffers not identical status:%d run:%d\n", msgstr, ret, ++run); goto end; } status = 1; end: /* Set the threshold back to 0 */ set_pkt_threshold(t->e, t->c->name, 0); return status; } static int run_sm4_cbc(void *pointer) { int cnt; int ret = 1; test_info ti; char msg[128]; TEST_PARAMS *args = (TEST_PARAMS *) pointer; ti.bufsz = args->size; ti.count = *(args->count); if ((ti.c = (sm4_alg_info *) get_alg_info(args->type)) == NULL) { FAIL_MSG("Unknown Test Type %d ti.c %p\n", args->type, ti.c); return 0; } /* * If temp_args->explicit_engine is not set then set the * engine to NULL to allow fallback to software if * that engine under test does not support this operation. * This relies on the engine we are testing being * set as the default engine. */ ti.e = args->e; if (ti.e) { EVP_CIPHER *cipher = (EVP_CIPHER *)ENGINE_get_cipher(ti.e, NID_sm4_cbc); /* Set Engine to NULL if this algorithm is disabled in configuration or disabled by the co-existence algorithm bitmap. */ if (cipher == NULL || cipher == EVP_sm4_cbc()) ti.e = NULL; } /* * For the qat engine, offload all packet sizes to engine * by setting the threshold sizes to 0 for the cipher under test. */ if (ti.e != NULL) { ret = set_pkt_threshold(ti.e, ti.c->name, 0); /* Set engine to NULL as threshold will fail if NID not supported*/ if (ret != 1) { return 0; } } if (args->performance) return test_performance_encrypt(&ti); /* If the inner run fails, abandon test */ for (cnt = 0; ret && cnt < *(args->count); cnt++) { if ( /* * Running the test with SW implementation to check if * the test logic is correct. */ (test_crypto_op(&ti, USE_SW, USE_SW) != 1) || ((ti.e != NULL) && ( /* Perform these tests only if engine is present */ (test_encrypted_buffer(&ti) != 1) || (test_crypto_op(&ti, USE_ENGINE, USE_SW) != 1) || (test_crypto_op(&ti, USE_SW, USE_ENGINE) != 1) || (test_crypto_op(&ti, USE_ENGINE, USE_ENGINE) != 1) || (test_multi_op(&ti) != 1) || (test_small_pkt_offload(&ti) != 1) ) ) ) { ret = 0; break; } } if (args->verify) { if (ret == 0) FAIL_MSG_END("verify failed %s%s", ti.c->name, cnt > 1 ? msg : "\n"); else PASS_MSG("verify %s%s", ti.c->name, cnt > 1 ? msg : "\n"); } /* Restore value to default */ if (ti.e != NULL) { ret = set_pkt_threshold(ti.e, ti.c->name, 2048); if (ret != 1) return 0; } return ret; } #endif /* ENABLE_QAT_HW_SM4_CBC */ #ifdef ENABLE_QAT_SW_SM4_CBC void tests_sm4_cbc_hexdump(const char *title, const unsigned char *s, int l) { #ifdef QAT_DEBUG int i = 0; printf("%s", title); for (i = 0; i < l; i++) { if ((i % 8) == 0) printf("\n "); printf("0x%02X, ", s[i]); } printf("\n\n"); #endif } static int test_sm4_cbc_encrypt(int num_buffers, ENGINE *e, int *len, int8u **engine_in, int8u **engine_out, int8u **openssl_in, int8u **openssl_out, int8u **mb_in, int8u **mb_out, int8u **iv, sm4_key **key) { mbx_sm4_key_schedule rkey; EVP_CIPHER_CTX *ctx[MULTIBUFF_SM4_BATCH]; EVP_CIPHER_CTX *ctx_engine[MULTIBUFF_SM4_BATCH]; EVP_CIPHER_CTX *ctx_mb[MULTIBUFF_SM4_BATCH]; int outl; int ret = 1; #ifdef QAT_OPENSSL_3 OSSL_PARAM params[4] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", ""); EVP_CIPHER *sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); #endif if (mbx_get_algo_info(MBX_ALGO_SM4)) { /* Use Engine to do the encryption. */ for (int i = 0; i < num_buffers; i++) { ctx[i] = EVP_CIPHER_CTX_new(); #ifdef QAT_OPENSSL_3 if (e == NULL) EVP_CipherInit_ex2(ctx[i], cipher, (int8u*)key[i], iv[i], 1, params); else #endif EVP_EncryptInit_ex(ctx[i], EVP_sm4_cbc(), e, (int8u*)key[i], iv[i]); } for (int i = 0; i < num_buffers; i++) { EVP_EncryptUpdate(ctx[i], engine_out[i], &outl, engine_in[i], len[i]); } for (int i = 0; i < num_buffers; i++) { EVP_EncryptFinal(ctx[i], engine_out[i] + len[i], &outl); EVP_CIPHER_CTX_free(ctx[i]); } /* crypto_mb encryption */ mbx_sm4_set_key_mb16(&rkey, (const sm4_key**)key); mbx_sm4_encrypt_cbc_mb16(mb_out, (const int8u**)mb_in, (const int*)len, &rkey, (const int8u**)iv); } else { for (int i = 0; i < num_buffers; i++) { ctx_engine[i] = EVP_CIPHER_CTX_new(); ctx_mb[i] = EVP_CIPHER_CTX_new(); #ifdef QAT_OPENSSL_3 EVP_CipherInit_ex2(ctx_engine[i], sw_cipher, (int8u*)key[i], iv[i], 1, NULL); EVP_CipherInit_ex2(ctx_mb[i], sw_cipher, (int8u*)key[i], iv[i], 1, NULL); #else EVP_EncryptInit(ctx_engine[i], EVP_sm4_cbc(), (int8u*)key[i], iv[i]); EVP_EncryptInit(ctx_mb[i], EVP_sm4_cbc(), (int8u*)key[i], iv[i]); #endif EVP_EncryptUpdate(ctx_engine[i], engine_out[i], &outl, engine_in[i], len[i]); EVP_EncryptFinal(ctx_engine[i], engine_out[i] + len[i], &outl); EVP_EncryptUpdate(ctx_mb[i], mb_out[i], &outl, mb_in[i], len[i]); EVP_EncryptFinal(ctx_mb[i], mb_out[i] + len[i], &outl); EVP_CIPHER_CTX_free(ctx_engine[i]); EVP_CIPHER_CTX_free(ctx_mb[i]); } } /* OpenSSL and crypto_mb are used as reference */ for (int i = 0; i < num_buffers; i++) { ctx[i] = EVP_CIPHER_CTX_new(); #ifdef QAT_OPENSSL_3 EVP_CipherInit_ex2(ctx[i], sw_cipher, (int8u*)key[i], iv[i], 1, NULL); #else EVP_EncryptInit(ctx[i], EVP_sm4_cbc(), (int8u*)key[i], iv[i]); #endif EVP_EncryptUpdate(ctx[i], openssl_out[i], &outl, openssl_in[i], len[i]); EVP_EncryptFinal(ctx[i], openssl_out[i] + len[i], &outl); EVP_CIPHER_CTX_free(ctx[i]); } /* Comparison with OpenSSL and crypto_mb */ for (int i = 0; i < num_buffers; i++) { tests_sm4_cbc_hexdump("mb_enc_txt", mb_out[i], len[i]); tests_sm4_cbc_hexdump("openssl_enc_txt", openssl_out[i], len[i]); tests_sm4_cbc_hexdump("engine_enc_txt", engine_out[i], len[i]); if (memcmp(mb_out[i], openssl_out[i], len[i])) { ret = 0; printf("encryption: openssl_sw vs crypto_mb, not matched\n"); } if (memcmp(mb_out[i], engine_out[i], len[i])) { ret = 0; printf("encryption: engine vs crypto_mb, not matched\n"); } if (memcmp(openssl_out[i], engine_out[i], len[i])) { ret = 0; printf("encryption: engine vs openssl_sw, not matched\n"); } } if (ret) printf("encryption test successful\n"); #ifdef QAT_OPENSSL_3 EVP_CIPHER_free(cipher); EVP_CIPHER_free(sw_cipher); #endif return ret; } static int test_sm4_cbc_decrypt(int num_buffers, ENGINE *e, int *len, int8u **engine_in, int8u **engine_out, int8u **openssl_in, int8u **openssl_out, int8u **mb_in, int8u **mb_out, int8u **iv, sm4_key **key) { mbx_sm4_key_schedule rkey; EVP_CIPHER_CTX *ctx[MULTIBUFF_SM4_BATCH]; EVP_CIPHER_CTX *ctx_engine[MULTIBUFF_SM4_BATCH]; EVP_CIPHER_CTX *ctx_mb[MULTIBUFF_SM4_BATCH]; int outl; int ret = 1; #ifdef QAT_OPENSSL_3 OSSL_PARAM params[4] = {OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END}; unsigned int pad = 0; params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pad); EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", ""); EVP_CIPHER *sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); #endif if (mbx_get_algo_info(MBX_ALGO_SM4)) { /* Use Engine to do the decryption. */ for (int i = 0; i < num_buffers; i++) { ctx[i] = EVP_CIPHER_CTX_new(); #ifdef QAT_OPENSSL_3 if (e == NULL) EVP_CipherInit_ex2(ctx[i], cipher, (int8u*)key[i], iv[i], 0, params); else #endif EVP_DecryptInit_ex(ctx[i], EVP_sm4_cbc(), e, (int8u*)key[i], iv[i]); } for (int i = 0; i < num_buffers; i++) { EVP_DecryptUpdate(ctx[i], engine_out[i], &outl, engine_in[i], len[i]); } for (int i = 0; i < num_buffers; i++) { EVP_DecryptFinal(ctx[i], engine_out[i] + len[i], &outl); EVP_CIPHER_CTX_free(ctx[i]); } /* crypto_mb decryption */ mbx_sm4_set_key_mb16(&rkey, (const sm4_key**)key); mbx_sm4_decrypt_cbc_mb16(mb_out, (const int8u**)mb_in, (const int*)len, &rkey, (const int8u**)iv); } else { for (int i = 0; i < num_buffers; i++) { ctx_engine[i] = EVP_CIPHER_CTX_new(); ctx_mb[i] = EVP_CIPHER_CTX_new(); #ifdef QAT_OPENSSL_3 EVP_CipherInit_ex2(ctx_engine[i], sw_cipher, (int8u*)key[i], iv[i], 0, params); EVP_CipherInit_ex2(ctx_mb[i], sw_cipher, (int8u*)key[i], iv[i], 0, params); #else EVP_DecryptInit(ctx_engine[i], EVP_sm4_cbc(), (int8u*)key[i], iv[i]); EVP_DecryptInit(ctx_mb[i], EVP_sm4_cbc(), (int8u*)key[i], iv[i]); #endif EVP_DecryptUpdate(ctx_engine[i], engine_out[i], &outl, engine_in[i], len[i]); EVP_DecryptFinal(ctx_engine[i], engine_out[i] + len[i], &outl); EVP_DecryptUpdate(ctx_mb[i], mb_out[i], &outl, mb_in[i], len[i]); EVP_DecryptFinal(ctx_mb[i], mb_out[i] + len[i], &outl); EVP_CIPHER_CTX_free(ctx_engine[i]); EVP_CIPHER_CTX_free(ctx_mb[i]); } } /* OpenSSL and crypto_mb are used as reference */ for (int i = 0; i < num_buffers; i++) { ctx[i] = EVP_CIPHER_CTX_new(); #ifdef QAT_OPENSSL_3 EVP_CipherInit_ex2(ctx[i], sw_cipher, (int8u*)key[i], iv[i], 0, params); #else EVP_DecryptInit(ctx[i], EVP_sm4_cbc(), (int8u*)key[i], iv[i]); #endif EVP_DecryptUpdate(ctx[i], openssl_out[i], &outl, openssl_in[i], len[i]); EVP_DecryptFinal(ctx[i], openssl_out[i] + len[i], &outl); EVP_CIPHER_CTX_free(ctx[i]); } /* Comparison with OpenSSL and crypto_mb */ for (int i = 0; i < num_buffers; i++) { tests_sm4_cbc_hexdump("mb_dec_txt", mb_out[i], len[i]); tests_sm4_cbc_hexdump("openssl_dec_txt", openssl_out[i], len[i]); tests_sm4_cbc_hexdump("engine_dec_txt", engine_out[i], len[i]); if (memcmp(mb_out[i], openssl_out[i], len[i])) { ret = 0; printf("decryption: openssl_sw vs crypto_mb, not matched\n"); } if (memcmp(mb_out[i], engine_out[i], len[i])) { ret = 0; printf("decryption: engine vs crypto_mb, not matched\n"); } if (memcmp(openssl_out[i], engine_out[i], len[i])) { ret = 0; printf("decryption: engine vs openssl_sw, not matched\n"); } } if (ret) printf("decryption test successful\n"); #ifdef QAT_OPENSSL_3 EVP_CIPHER_free(cipher); EVP_CIPHER_free(sw_cipher); #endif return ret; } static int test_sm4_cbc(ENGINE *e, int count, int size) { int len[MULTIBUFF_SM4_BATCH]; int8u* mb_txt[MULTIBUFF_SM4_BATCH]; int8u* mb_enc_txt[MULTIBUFF_SM4_BATCH]; int8u* mb_dec_txt[MULTIBUFF_SM4_BATCH]; int8u* mb_iv[MULTIBUFF_SM4_BATCH]; sm4_key* mb_key[MULTIBUFF_SM4_BATCH]; int8u* engine_enc_txt[MULTIBUFF_SM4_BATCH]; int8u* engine_dec_txt[MULTIBUFF_SM4_BATCH]; int8u* openssl_enc_txt[MULTIBUFF_SM4_BATCH]; int8u* openssl_dec_txt[MULTIBUFF_SM4_BATCH]; int num_buffers = MULTIBUFF_SM4_BATCH; int ret = 1; printf("\nStart %d round test, size: %d\n", count, size); /* Init random data for testing */ for (int i = 0; i < num_buffers; i++) { len[i] = size; mb_key[i] = (sm4_key*)OPENSSL_zalloc(SM4_CBC_KEY_SIZE); if (mbx_get_algo_info(MBX_ALGO_SM4)) { mb_enc_txt[i] = (int8u*)OPENSSL_zalloc(len[i]); mb_dec_txt[i] = (int8u*)OPENSSL_zalloc(len[i]); } else { mb_enc_txt[i] = OPENSSL_zalloc(len[i] + SM4_CBC_KEY_SIZE); mb_dec_txt[i] = OPENSSL_zalloc(len[i] + SM4_CBC_KEY_SIZE); } mb_txt[i] = (int8u*)OPENSSL_zalloc(len[i]); mb_iv[i] = (int8u*)OPENSSL_zalloc(SM4_CBC_IV_SIZE); engine_enc_txt[i] = OPENSSL_zalloc(len[i] + SM4_CBC_KEY_SIZE); engine_dec_txt[i] = OPENSSL_zalloc(len[i] + SM4_CBC_KEY_SIZE); openssl_enc_txt[i] = OPENSSL_zalloc(len[i] + SM4_CBC_KEY_SIZE); openssl_dec_txt[i] = OPENSSL_zalloc(len[i] + SM4_CBC_KEY_SIZE); RAND_bytes(*mb_key[i], SM4_CBC_KEY_SIZE); RAND_bytes(mb_txt[i], len[i]); RAND_bytes(mb_iv[i], SM4_CBC_IV_SIZE); tests_sm4_cbc_hexdump("mb_key", *mb_key[i], SM4_CBC_KEY_SIZE); tests_sm4_cbc_hexdump("mb_txt", mb_txt[i], len[i]); tests_sm4_cbc_hexdump("mb_iv", mb_iv[i], SM4_CBC_IV_SIZE); } /* out-of-place operation */ printf("out-of-place operation tests: \n"); /* Encryption */ if (!test_sm4_cbc_encrypt(num_buffers, e, len, mb_txt, engine_enc_txt, mb_txt, openssl_enc_txt, mb_txt, mb_enc_txt, mb_iv, mb_key)) { ret = 0; } /* Decryption */ if (!test_sm4_cbc_decrypt(num_buffers, e, len, engine_enc_txt, engine_dec_txt, openssl_enc_txt, openssl_dec_txt, mb_enc_txt, mb_dec_txt, mb_iv, mb_key)) { ret = 0; } if (ret) printf("out-of-place tests are successful\n"); else { printf("out-of-place tests failed\n"); } /* in-place operation */ printf("\nin-place operation tests: \n"); /* Encryption */ for (int i = 0; i < num_buffers; i++) { memset(engine_enc_txt[i], 0, len[i] + SM4_CBC_KEY_SIZE); memcpy(engine_enc_txt[i], mb_txt[i], len[i]); memset(openssl_enc_txt[i], 0, len[i] + SM4_CBC_KEY_SIZE); memcpy(openssl_enc_txt[i], mb_txt[i], len[i]); memcpy(mb_enc_txt[i], mb_txt[i], len[i]); } if (!test_sm4_cbc_encrypt(num_buffers, e, len, engine_enc_txt, engine_enc_txt, openssl_enc_txt, openssl_enc_txt, mb_enc_txt, mb_enc_txt, mb_iv, mb_key)) { ret = 0; } /* Decryption */ for (int i = 0; i < num_buffers; i++) { memset(engine_dec_txt[i], 0, len[i] + SM4_CBC_KEY_SIZE); memcpy(engine_dec_txt[i], engine_enc_txt[i], len[i]); memset(openssl_dec_txt[i], 0, len[i] + SM4_CBC_KEY_SIZE); memcpy(openssl_dec_txt[i], openssl_enc_txt[i], len[i]); memcpy(mb_dec_txt[i], mb_enc_txt[i], len[i]); } if (!test_sm4_cbc_decrypt(num_buffers, e, len, engine_dec_txt, engine_dec_txt, openssl_dec_txt, openssl_dec_txt, mb_dec_txt, mb_dec_txt, mb_iv, mb_key)) { ret = 0; } if (ret) printf("in-place tests are successful\n"); else { printf("in-place tests failed\n"); } /* Free memory */ for (int i = 0; i < num_buffers; i++) { if (openssl_enc_txt[i]) OPENSSL_free(openssl_enc_txt[i]); if (openssl_dec_txt[i]) OPENSSL_free(openssl_dec_txt[i]); if (engine_enc_txt[i]) OPENSSL_free(engine_enc_txt[i]); if (engine_dec_txt[i]) OPENSSL_free(engine_dec_txt[i]); if (mb_enc_txt[i]) OPENSSL_free(mb_enc_txt[i]); if (mb_dec_txt[i]) OPENSSL_free(mb_dec_txt[i]); if (mb_txt[i]) OPENSSL_free(mb_txt[i]); if (mb_iv[i]) OPENSSL_free(mb_iv[i]); if (mb_key[i]) OPENSSL_free(mb_key[i]); } return ret; } /* message length list for test */ static const int test_size[] = { 16, 64, 256, 1024, 2048, 4096, 8192, 16384 }; static int run_sm4_cbc_msg(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; int count = *(temp_args->count); int ns = sizeof(test_size)/ sizeof(int); int i = 0, cnt = 0; int ret = 1; /* If temp_args->explicit_engine is not set then set the engine to NULL to allow fallback to software if that engine under test does not support this operation. This relies on the engine we are testing being set as the default engine. */ #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #else ENGINE *e = NULL; #endif /* If the inner run fails, abandon test */ for (cnt = 0; ret && cnt < count; cnt++) { for (i = 0; i < ns; i++) { ret = test_sm4_cbc(e, cnt, test_size[i]); } } if (ret) printf("\nAll tests passed\n"); return ret; } #endif /* ENABLE_QAT_SW_SM4_CBC */ /****************************************************************************** * function: * tests_run_sm4_cbc (TEST_PARAMS *args) * * @param args [IN] - the test parameters * * Description: * This function is designed to test the QAT engine with all message sizes * using the SM4_CBC algorithm. The higher level EVP interface function * EVP_Encrypt*() and EVP_Decrypt*() are used inside of test application. * This is a boundary test, the application should return the expected cipher value. ******************************************************************************/ void tests_run_sm4_cbc(TEST_PARAMS *args) { args->additional_args = NULL; #if (defined ENABLE_QAT_SW_SM4_CBC) && (defined ENABLE_QAT_HW_SM4_CBC) int sw_bitmap = strtol(sw_algo_bitmap, NULL, 16); int hw_bitmap = strtol(hw_algo_bitmap, NULL, 16); if(((hw_bitmap & ALGO_ENABLE_MASK_SM4) == 0) && ((sw_bitmap & ALGO_ENABLE_MASK_SM4) != 0)) { if (!args->enable_async) run_sm4_cbc_msg(args); else start_async_job(args, run_sm4_cbc_msg); } else { if (!args->enable_async) run_sm4_cbc(args); else start_async_job(args, run_sm4_cbc); } #endif #if (defined ENABLE_QAT_SW_SM4_CBC) && (!defined ENABLE_QAT_HW_SM4_CBC) if (!args->enable_async) run_sm4_cbc_msg(args); else start_async_job(args, run_sm4_cbc_msg); #endif #if (defined ENABLE_QAT_HW_SM4_CBC) && (!defined ENABLE_QAT_SW_SM4_CBC) if (!args->enable_async) run_sm4_cbc(args); else start_async_job(args, run_sm4_cbc); #endif } qatengine-1.9.0/test/tests_sm4_ccm.c000066400000000000000000000311561500416242000173660ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2023-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #ifdef ENABLE_QAT_SW_SM4_CCM # define SM4_BLOCKSIZE 16 # define QAT_SM4_TAG_MAX_LEN 16 static const unsigned char key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD}; /****************************************************************************** * function: * run_sm4ccm_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * --------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * *****************************************************************************/ static int run_sm4ccm_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int ret = 0; /* 16 bytes additional authentication data. * AAD is not to be encrypted. It is passed along with the plaintext * and ciphertext to the recipient. */ /* const unsigned char aad[] = { 0xFE,0xED,0xFA,0xCE,0xDE,0xAD,0xBE,0xEF,0xFE,0xED, 0xFA,0xCE,0xDE,0xAD,0xBE,0xEF,0xAB,0xAD,0xDA,0xD2}; */ unsigned char plaintext[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}; unsigned char *ciphertext = OPENSSL_malloc(size + (SM4_BLOCKSIZE * 4)); unsigned char tag[EVP_CCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = OPENSSL_malloc(size + (SM4_BLOCKSIZE * 4)); unsigned char *enc_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int enc_cipher_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (!temp_args->enable_async) { e = NULL; } #endif if (ciphertext == NULL || dec_cipher == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } enc_cipher = ciphertext; if (print_output) tests_hexdump("SM4-CCM: input message", plaintext, /*size*/sizeof(plaintext)); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed while creating ctx\n", __func__); goto err; } /* Initialize encryption context for sm4-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_sm4_ccm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_sm4_ccm() , e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() encryption failed while setting context: ret %d\n", __func__, ret); goto err; } /* * Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting IVLEN: ret %d\n", __func__, ret); goto err; } ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, QAT_SM4_TAG_MAX_LEN, NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting EVP_CTRL_AEAD_SET_TAG: ret %d\n", __func__, ret); goto err; } /* * Initialise the sm4-ccm encryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting key: ret %d\n", __func__, ret); goto err; } ret = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed while setting iv: ret %d\n", __func__, ret); goto err; } /* Pass AAD to the encryption context before encrypting the input plaintext.*/ /* ret = EVP_EncryptUpdate(ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } */ /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, sizeof(plaintext)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("SM4-CCM ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; enc_cipher_len = ciphertext_len; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for sm4-ccm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_sm4_ccm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_sm4_ccm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* * Initialise the sm4-ccm decryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, enc_cipher, enc_cipher_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len += tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_CCM_SET_TAG, EVP_CCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("SM4-CCM enc tag:", tag, EVP_CCM_TLS_TAG_LEN); if (print_output) tests_hexdump("SM4-CCM decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, /*size*/sizeof(plaintext))) { INFO("# FAIL verify for SM4 CCM update\n"); ret = 0; tests_hexdump("SM4CCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("SM4CCM expected:", plaintext, size); } else INFO("# PASS verify for SM4 CCM update\n"); } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (ciphertext) OPENSSL_free(ciphertext); if (dec_cipher) OPENSSL_free(dec_cipher); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } void tests_run_sm4_ccm(TEST_PARAMS *args) { args->additional_args = NULL; if (args->enable_async) start_async_job(args, run_sm4ccm_update); else run_sm4ccm_update(args); } #endif /* ENABLE_QAT_SW_SM4_CCM */ qatengine-1.9.0/test/tests_sm4_gcm.c000066400000000000000000000305761500416242000173770ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2024-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ #include #include #include #include #include #include #include #include #include #include #include "tests.h" #include "../qat_utils.h" #ifdef ENABLE_QAT_SW_SM4_GCM #define SM4_BLOCKSIZE 16 static const unsigned char key[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}; /* 12 bytes initialisation vector */ static const unsigned char iv[] = { 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xCD}; /****************************************************************************** * function: * run_sm4gcm_update (void *args) * * @param args [IN] - the test parameters * * SW engine differs from the QAT engine in the following ways: * EVP Function SW Engine QAT Engine * --------------------------------------------------------------------------- * Encrypt Update Encrypt the payload Encrypt the payload AND * compute the tag * * Encrypt Final Compute the tag Does nothing * * Decrypt Update Decrypt the payload Decrpyt the payload and * verify the TAG. Return failure * if the TAG is not correct * * Decrypt Final Verify the TAG and Does nothing * return failure if not correct * * This doesn't impact the TLS case because Update and Final are considered * a single operation like in the QAT engine. *****************************************************************************/ static int run_sm4gcm_update(void *args) { TEST_PARAMS *temp_args = (TEST_PARAMS *)args; #ifndef QAT_OPENSSL_PROVIDER ENGINE *e = temp_args->e; #endif int size = temp_args->size; int print_output = temp_args->print_output; int verify = temp_args->verify; int ret = 0; /* 16 bytes additional authentication data. * AAD is not to be encrypted. It is passed along with the plaintext * and ciphertext to the recipient. */ const unsigned char aad[] = { 0xFE,0xED,0xFA,0xCE,0xDE,0xAD,0xBE,0xEF,0xFE,0xED, 0xFA,0xCE,0xDE,0xAD,0xBE,0xEF,0xAB,0xAD,0xDA,0xD2}; unsigned char plaintext[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}; unsigned char *ciphertext = OPENSSL_malloc(size + (SM4_BLOCKSIZE * 4)); unsigned char tag[EVP_GCM_TLS_TAG_LEN] = { 0 }; unsigned char *dec_cipher = OPENSSL_malloc(size + (SM4_BLOCKSIZE * 4)); unsigned char *enc_cipher = NULL; int ciphertext_len = 0; int tmpout_len = 0; int enc_cipher_len = 0; int dec_cipher_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *dec_ctx = NULL; #ifndef QAT_OPENSSL_PROVIDER if (!temp_args->enable_async) { e = NULL; } #endif if (ciphertext == NULL || dec_cipher == NULL) { INFO("# FAIL: [%s] --- Initial parameters malloc failed ! \n", __func__); exit(EXIT_FAILURE); } enc_cipher = ciphertext; if (print_output) tests_hexdump("SM4-GCM: input message", plaintext, /*size*/sizeof(plaintext)); /* Create context for encrypt operation */ ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for ctx\n", __func__); goto err; } /* Initialize encryption context for sm4-gcm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, EVP_sm4_gcm(), NULL, NULL); #else ret = EVP_EncryptInit_ex(ctx, EVP_sm4_gcm() , e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* * Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* * Initialise the sm4-gcm encryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_EncryptInit(ctx, NULL, key, iv); #else ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Pass AAD to the encryption context before encrypting the input plaintext. */ ret = EVP_EncryptUpdate(ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } /* Encrypt the input plaintext. */ ret = EVP_EncryptUpdate(ctx, ciphertext, &tmpout_len, plaintext, sizeof(plaintext)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptUpdate() failed for inputtext: ret %d\n", __func__, ret); goto err; } else ciphertext_len = tmpout_len; /* Finalise the encryption - EVP_EncryptFinal_ex() * This operation is not needed for QAT Engine calculates and finalises * the ciphertext in EVP_EncryptUpdate() itself. * */ ret = EVP_EncryptFinal_ex(ctx, ciphertext + tmpout_len, &tmpout_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_EncryptFinal_ex() failed for ciphertext: ret %d\n", __func__, ret); goto err; } ciphertext_len += tmpout_len; if (print_output) tests_hexdump("SM4-GCM ciphertext:", ciphertext, ciphertext_len); /* Retrieve the 16 byte tag */ ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed for tag: ret %d\n", __func__, ret); goto err; } EVP_CIPHER_CTX_free(ctx); ctx = NULL; tmpout_len = 0; enc_cipher_len = ciphertext_len; /*----------------------- Decryption ------------------------ */ /* Create context for decrypt operation */ dec_ctx = EVP_CIPHER_CTX_new(); if (dec_ctx == NULL) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_new() failed for dec_ctx\n", __func__); goto err; } /* Initialize decryption context for sm4-gcm */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, EVP_sm4_gcm(), NULL, NULL); #else ret = EVP_DecryptInit_ex(dec_ctx, EVP_sm4_gcm(), e, NULL, NULL); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* Set IV length other than the default 12 bytes but QAT Engine supports * only 12 bytes. * Optional - The default is 12 bytes according to the TLS spec. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(iv), NULL); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed: ret %d\n", __func__, ret); goto err; } /* * Initialise the sm4-gcm decryption context with 16-byte key and * 12-byte IV. */ #ifdef QAT_OPENSSL_PROVIDER ret = EVP_DecryptInit(dec_ctx, NULL, key, iv); #else ret = EVP_DecryptInit_ex(dec_ctx, NULL, NULL, key, iv); #endif if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptInit_ex() failed: ret %d\n", __func__, ret); goto err; } /* QAT engine reads tag before starting the decrypt operation whereas * SW engine performs the decrypt op first and then reads the tag. */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } /* AAD is passed to EVP_DecryptUpdate() with output buffer set to NULL */ ret = EVP_DecryptUpdate(dec_ctx, NULL, &tmpout_len, aad, sizeof(aad)); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when adding aad: ret %d\n", __func__, ret); goto err; } /* Decrypt the ciphertext */ ret = EVP_DecryptUpdate(dec_ctx, dec_cipher, &tmpout_len, enc_cipher, enc_cipher_len); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_DecryptUpdate() failed when decrypting ciphertext: ret %d\n", __func__, ret); goto err; } else dec_cipher_len += tmpout_len; /* Read the tag after the decrypt operation */ ret = EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag); if (ret != 1) { INFO("# FAIL: [%s] --- EVP_CIPHER_CTX_ctrl() failed while setting the tag: ret %d\n", __func__, ret); goto err; } if (print_output) tests_hexdump("SM4-GCM enc tag:", tag, EVP_GCM_TLS_TAG_LEN); if (print_output) tests_hexdump("SM4-GCM decrypted plaintext:", dec_cipher, dec_cipher_len); /* Compare and verify the decrypt and encrypt message. */ if (verify) { if (memcmp(dec_cipher, plaintext, /*size*/sizeof(plaintext))) { INFO("# FAIL verify for SM4 GCM update\n"); ret = 0; tests_hexdump("SM4GCM actual :", dec_cipher, dec_cipher_len); tests_hexdump("SM4GCM expected:", plaintext, size); } else { INFO("# PASS verify for SM4 GCM update\n"); } } EVP_CIPHER_CTX_free(dec_ctx); dec_ctx = NULL; if (ciphertext) OPENSSL_free(ciphertext); if (dec_cipher) OPENSSL_free(dec_cipher); return ret; err: if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); if (dec_ctx != NULL) EVP_CIPHER_CTX_free(dec_ctx); return ret; } void tests_run_sm4_gcm(TEST_PARAMS *args) { args->additional_args = NULL; if (args->enable_async) start_async_job(args, run_sm4gcm_update); else run_sm4gcm_update(args); } #endif /* ENABLE_QAT_SW_SM4_GCM */ qatengine-1.9.0/test_bssl/000077500000000000000000000000001500416242000154705ustar00rootroot00000000000000qatengine-1.9.0/test_bssl/main.c000066400000000000000000000143031500416242000165610ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file main.c * * This file provides a QAT Engine test functions. * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* System Includes */ #include /* Local Includes */ #include "qat_bssl.h" #include "qat_utils.h" #include "test_bssl_utils.h" #include "test_bssl_rsa.h" #include "test_bssl_ecdsa.h" /* OpenSSL Includes */ #include char *key_path = NULL; char *bin_name = NULL; int flag = 0; static void process_test_job(void); static int parse_private_key(void); static int parse_user_option(int argc, char *argv[]); static void print_test_help(void); static const char *get_bin_name(const char *path); int main(int argc, char *argv[]) { if (!parse_user_option(argc, argv)) { process_test_job(); } return 0; } void process_test_job(void) { if (parse_private_key() <= 0) { T_DEBUG("Test Failed\n"); PRINT_TIPS(); return; } T_DEBUG("Test Success\n"); PRINT_TIPS(); if (bin_name) { OPENSSL_free(bin_name); } } int parse_private_key(void) { int ret = -1; EVP_PKEY *pkey = NULL; if (NULL == (pkey = (EVP_PKEY *)qat_load_priv_key(key_path))) { T_ERROR("Failed to load private key\n"); return ret; } switch(EVP_PKEY_id(pkey)) { case EVP_PKEY_RSA: ENGINE_load_qat(); ret = qat_rsa_test(pkey, flag); ENGINE_unload_qat(); break; case EVP_PKEY_EC: ENGINE_load_qat(); ret = qat_ecdsa_test(pkey, flag); ENGINE_unload_qat(); break; default: T_WARN("Unknown algorithm type, only RSA and ECDSA supported\n"); break; } return ret; } int parse_user_option(int argc, char *argv[]) { int input; if(!get_bin_name(argv[0])) { T_ERROR("Get executable binary name failed\n"); return 1; } while ((input = getopt(argc, argv, "a::d::h::k:")) != -1) { switch (input) { case 'k': { int slen = strlen(optarg); if (!optarg || access(optarg, F_OK) == -1 ) { T_ERROR("key_path not set or exist\n"); return 1; } if (NULL == key_path) key_path = (char *)OPENSSL_zalloc(slen + 1); if (NULL == key_path) { T_ERROR("Error: allocated memory failed\n"); return 1; } strncpy(key_path, optarg, slen); } break; case 'h': print_test_help(); return 1; case 'd': flag |= RSA_DECRYPT_TEST; break; case 'a': flag |= RSA_ASYNC_MODE; break; case '?': T_WARN("Unknown option: -%c\n",(char)optopt); print_test_help(); return 1; } } if (!key_path) { T_ERROR("private key path not set\n"); print_test_help(); return 1; } return 0; } const char *get_bin_name(const char *path) { char *p = strrchr(path, '/'); if (strstr(p, "lt-")) { p = strchr(p,'-'); } if (p) { /* Save executable binary name */ bin_name = OPENSSL_strdup(++p); } return bin_name; } void print_test_help(void) { printf("Usage: ./%s [-h/-d/-a] <-k>\n", bin_name); printf("\t-a : \tEnable async mode\n"); printf("\t-d : \tTest on rsa private decrypt \n"); printf("\t-h : \tPrint all available options\n"); printf("\t-k : \tSet private key file path for test purpose e.g. /opt/rsa_key.pmem\n"); printf("Test command lines for reference:\n"); printf("\t./%s -k /opt/rsa_private_2k.key\n", bin_name); printf("\t./%s -k /opt/rsa_private_2k.key -a\n", bin_name); printf("\t./%s -k /opt/rsa_private_2k.key -d\n", bin_name); printf("\t./%s -k /opt/rsa_private_4k.key\n", bin_name); printf("\t./%s -k /opt/ec-secp384r1-priv-key.pem\n", bin_name); printf("\t./%s -k /opt/ec-secp384r1-priv-key.pem -a\n", bin_name); } qatengine-1.9.0/test_bssl/test_bssl_ecdsa.c000066400000000000000000000154321500416242000210020ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file test_bssl_ecdsa.c * * This file provides a QAT Engine test functions. * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Local Includes */ #include "qat_bssl.h" #include "qat_utils.h" #include "test_bssl_utils.h" #include "test_bssl_ecdsa.h" /* OpenSSL Includes */ #include # define EVP_MAX_MD_SIZE 64 # define TEST_ECDSA_CURVE NID_X9_62_prime256v1 static pthread_t async_poll_thread; static uint8_t *sig_data = NULL; static size_t max_len = 0; static size_t sig_len = 0; static const char in_data[] = "IntelĀ® QuickAssist Technology (IntelĀ® QAT)"; static void qat_ecdsa_handle_async_ctx(async_ctx *ctx) { if (NULL == sig_data) { T_ERROR("sig_data is NULL\n"); goto err; } /* Copy data from async_ctx */ if (bssl_qat_async_ctx_copy_result(ctx, sig_data, (size_t *)&sig_len, max_len)) { T_ERROR("Fail to get output results\n"); goto err; } err: bssl_qat_async_finish_job(ctx); } static void *qat_ecdsa_polling_async_ctx(void *args) { async_ctx *ctx = (async_ctx *)args; T_DEBUG("ECDSA test polling result thread start\n"); while (*ctx->currjob_status != ASYNC_JOB_COMPLETE) { usleep(10); } T_DEBUG("ECDSA test polling result thread detect data ready\n"); qat_ecdsa_handle_async_ctx(ctx); T_DEBUG("ECDSA test polling result thread finished\n"); return (void*)0; } static async_ctx *qat_ecdsa_init_async_ctx(void) { async_ctx *ctx = bssl_qat_async_start_job(); ASYNC_JOB *job = ctx->currjob; T_DEBUG("ECDSA init async_ctx async ctx:%p, job:%p, job->status:%d \n", ctx, job, job->status); pthread_create(&async_poll_thread, NULL, qat_ecdsa_polling_async_ctx, ctx); return ctx; } static void qat_ecdsa_wait_async_ctx() { pthread_join(async_poll_thread, NULL); } int qat_ecdsa_test(const EVP_PKEY *pkey, int flag) { unsigned int mdlen = 0; unsigned char md[EVP_MAX_MD_SIZE]; EVP_MD_CTX *ctx; ECDSA_SIG *signature = NULL; EC_KEY *eckey = NULL; EC_KEY *defult_eckey = NULL; const EVP_PKEY *lpkey = pkey; EC_GROUP *group = NULL; int type; if (flag & ECDSA_ASYNC_MODE) { qat_ecdsa_init_async_ctx(); } if ((ctx = EVP_MD_CTX_new()) == NULL) { return -1; } if (!EVP_DigestInit(ctx, EVP_sha256()) || !EVP_DigestUpdate(ctx, (const void*)in_data, 3) || !EVP_DigestFinal(ctx, md, &mdlen)) { goto err; } /* create the eckey if local pkey is NULL*/ if (!lpkey && (eckey = EC_KEY_new_by_curve_name( TEST_ECDSA_CURVE)) == NULL) { T_ERROR("Failed to get EC key by curve name\n"); goto err; } if (!lpkey && !EC_KEY_generate_key(eckey)) { T_ERROR("Failed to generate new EC key\n"); goto err; } if (pkey) { defult_eckey = EVP_PKEY_get0_EC_KEY(lpkey); if (defult_eckey) { group = EC_GROUP_dup(EC_KEY_get0_group(defult_eckey)); if (group) { type = EC_GROUP_get_curve_name(group); } } } if (!group) { type = TEST_ECDSA_CURVE; if((group = EC_GROUP_new_by_curve_name(type)) == NULL) { T_ERROR("Failed to generate new EC group\n"); goto err; } } if (lpkey && NULL == (eckey = EC_KEY_new_method(ENGINE_QAT_PTR_GET()))) { T_ERROR("Failed to load local private key\n"); goto err; } if (!EC_KEY_set_group(eckey, group)) { T_ERROR("Failed to EC_KEY_set_group\n"); goto err; } if (!EC_KEY_generate_key(eckey)) { T_ERROR("Failed to EC_KEY_generate_key\n"); goto err; } max_len = ECDSA_size(eckey); if ((sig_data = (uint8_t *)OPENSSL_zalloc(max_len)) == NULL) { T_ERROR("Failed to allocate sig buffer\n"); return -1; } T_DUMP_ECDSA_SIGN_INPUT(in_data, strlen(in_data)); if (!ECDSA_sign(type, md, mdlen, sig_data, (unsigned int *) &sig_len, eckey)) { T_ERROR("ECDSA Sign: Failed\n"); goto err; } else { if (flag & ECDSA_ASYNC_MODE) { qat_ecdsa_wait_async_ctx(); } T_DEBUG("ECDSA Sign: OK\n"); T_DUMP_ECDSA_SIGN_OUTPUT(sig_data, (unsigned int) sig_len); } /* Verify */ signature = ECDSA_SIG_from_bytes(sig_data, (unsigned int) sig_len); if (ECDSA_do_verify(md, mdlen, signature, eckey) != 1) {\ T_ERROR("ECDSA Verify: Failed\n"); goto err; } else { T_DEBUG("ECDSA Verify: OK\n"); } err: if (!signature) { sig_len = 0; } if (sig_data) { OPENSSL_free(sig_data); } if (eckey) EC_KEY_free(eckey); EVP_MD_CTX_cleanup(ctx); return sig_len; } qatengine-1.9.0/test_bssl/test_bssl_ecdsa.h000066400000000000000000000042731500416242000210100ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file test_bssl_ecdsa.h * * This file provides a QAT Engine test functions. * *****************************************************************************/ #ifndef TEST_BSSL_ECDSA_H # define TEST_BSSL_ECDSA_H #define ECDSA_ASYNC_MODE 1 int qat_ecdsa_test(const EVP_PKEY *pkey, int flag); #endif /* TEST_BSSL_ECDSA_H */ qatengine-1.9.0/test_bssl/test_bssl_rsa.c000066400000000000000000000360431500416242000205110ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file test_bssl_rsa.c * * This file provides a QAT Engine test functions. * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif /* Local Includes */ #include "qat_bssl.h" #include "qat_utils.h" #include "test_bssl_utils.h" #include "test_bssl_rsa.h" /* OpenSSL Includes */ #include /* original data */ static unsigned char data_2048[] = { 0x11, 0x11, 0x82, 0x63, 0x33, 0x9b, 0x25, 0x14, 0xfd, 0x80, 0x30, 0xc2, 0x57, 0xa0, 0x79, 0x98, 0xd3, 0x66, 0x9d, 0x0e, 0x59, 0x2c, 0xc9, 0xd4, 0x79, 0x83, 0x7d, 0xc5, 0xf1, 0xe9, 0xda, 0xf1, 0xa2, 0x42, 0x1b, 0xb9, 0xac, 0xd0, 0xef, 0xce, 0x9a, 0x72, 0x41, 0xd6, 0xd0, 0xfb, 0xcc, 0xbb, 0x1d, 0x0d, 0x62, 0xac, 0x95, 0x1d, 0x67, 0xab, 0xe8, 0xd0, 0xff, 0xe0, 0x40, 0xb1, 0x3c, 0x25, 0xbf, 0xa4, 0xc0, 0xea, 0xdc, 0x0c, 0xdc, 0x37, 0x6a, 0x25, 0x7a, 0xd2, 0x03, 0xf6, 0x83, 0xf8, 0x99, 0x48, 0x55, 0x5e, 0x78, 0x0f, 0x39, 0x9c, 0xe0, 0xf9, 0x9c, 0x18, 0xe2, 0xbb, 0xd3, 0xa4, 0xe3, 0x4b, 0x4e, 0x1c, 0x45, 0x8e, 0x17, 0x42, 0xfc, 0x0c, 0x0c, 0x42, 0xcd, 0x29, 0x6c, 0x4f, 0x62, 0xd6, 0x86, 0xd7, 0x2f, 0x88, 0x76, 0x18, 0xf1, 0xc1, 0xab, 0xf0, 0x12, 0x4d, 0xbe, 0x32, 0x4e, 0xaa, 0xd1, 0xd4, 0x87, 0x9d, 0x25, 0xe2, 0xad, 0xc8, 0x26, 0xdc, 0xf8, 0xe8, 0x0c, 0xeb, 0x5d, 0x51, 0x8f, 0x84, 0x63, 0x28, 0x5e, 0xb5, 0x75, 0xfa, 0x99, 0x7b, 0xa3, 0xb7, 0x63, 0x98, 0xae, 0x4d, 0x76, 0x8f, 0x12, 0xee, 0xce, 0xcd, 0x35, 0xc9, 0x6b, 0xa5, 0x01, 0x99, 0x49, 0x38, 0xe0, 0x97, 0xac, 0x4b, 0x23, 0x62, 0x0d, 0x18, 0x3d, 0x20, 0xfc, 0xc1, 0x0e, 0x41, 0x49, 0x9e, 0x40, 0xd5, 0x76, 0x25, 0xbb, 0x55, 0x66, 0xf0, 0x79, 0xb2, 0x7c, 0x38, 0xa4, 0x07, 0x83, 0x97, 0xf0, 0x5d, 0x42, 0x89, 0x0f, 0x56, 0x36, 0x2c, 0xd5, 0x88, 0xed, 0x42, 0x7f, 0xfe, 0x82, 0x86, 0x65, 0xef, 0x5d, 0xc8, 0x18, 0x6c, 0x88, 0x6c, 0x50, 0x1b, 0xe9, 0x62, 0x85, 0x99, 0x7e, 0x8d, 0x3e, 0xac, 0x4b, 0x21, 0x92, 0xd0, 0x2a, 0xc5, 0x31, 0xad, 0xe9, 0xe8, 0x19, 0xfe, 0x6b, 0xa1 }; /* Original Data for 3K rsa test*/ static unsigned char data_3072[] = { 0x61 ,0x46 ,0xe0 ,0x3c ,0x38 ,0xc0 ,0x9b ,0xdf ,0x78 ,0x87 ,0xe3 ,0x5e ,0x08 ,0xa1 ,0x97 ,0x53, 0x41 ,0x90 ,0x8e ,0x34 ,0x1c ,0x91 ,0x73 ,0xd0 ,0xe1 ,0x08 ,0x2b ,0xf0 ,0x7d ,0xd1 ,0xa6 ,0x34, 0x84 ,0xc3 ,0xd9 ,0x53 ,0x2f ,0x8a ,0x6b ,0xb3 ,0xcc ,0x6f ,0x95 ,0xe5 ,0x93 ,0x55 ,0x78 ,0xe4, 0xd6 ,0x3b ,0x84 ,0x95 ,0xbf ,0xf9 ,0x38 ,0x30 ,0x5d ,0xbf ,0x00 ,0xe8 ,0xcd ,0xf2 ,0xfc ,0xbc, 0x38 ,0xe3 ,0x25 ,0x1b ,0x3f ,0xc6 ,0x6d ,0x52 ,0x4c ,0x58 ,0x1d ,0xbe ,0x3e ,0x2b ,0x1e ,0x48, 0x51 ,0xb5 ,0x38 ,0xed ,0x95 ,0xe9 ,0x1a ,0x07 ,0xfb ,0x2c ,0x29 ,0x0e ,0x87 ,0xa1 ,0xec ,0x12, 0x2d ,0x75 ,0xfa ,0x99 ,0x76 ,0x0f ,0xd3 ,0x5b ,0xf8 ,0x10 ,0xeb ,0x52 ,0xf0 ,0x58 ,0x9c ,0x78, 0xf7 ,0xb5 ,0xf7 ,0x84 ,0xc0 ,0xa1 ,0x6c ,0x99 ,0xce ,0x05 ,0xe3 ,0xaf ,0x60 ,0x92 ,0xc8 ,0x59, 0x8b ,0x59 ,0xcf ,0x18 ,0xc5 ,0xfd ,0x57 ,0x2f ,0xd1 ,0x1c ,0x7b ,0x59 ,0x57 ,0x96 ,0x81 ,0xc8, 0x7c ,0x67 ,0x24 ,0x8f ,0xdc ,0xc6 ,0x75 ,0x29 ,0x46 ,0xda ,0xab ,0x6c ,0x9c ,0xb4 ,0xce ,0xd9, 0x18 ,0xb8 ,0xe3 ,0x9e ,0x83 ,0xb3 ,0x97 ,0x24 ,0x74 ,0x42 ,0x10 ,0x54 ,0xc6 ,0x54 ,0xac ,0xfa, 0xcf ,0xbc ,0xe1 ,0x43 ,0xab ,0xcf ,0x38 ,0x94 ,0x69 ,0x52 ,0xdd ,0xb7 ,0xb1 ,0xdf ,0xb8 ,0xc9, 0x9b ,0xcb ,0xe5 ,0x3f ,0x39 ,0x9c ,0x8f ,0x5d ,0x8e ,0x5f ,0xba ,0xc2 ,0x86 ,0x29 ,0xcd ,0x3e, 0x76 ,0xae ,0x80 ,0x60 ,0xce ,0x1a ,0x7f ,0x33 ,0xef ,0x0a ,0x1e ,0x9f ,0xeb ,0xa9 ,0x1e ,0x43, 0xb0 ,0xdf ,0x91 ,0xf4 ,0x3f ,0x1c ,0x84 ,0x6f ,0x43 ,0x57 ,0xc8 ,0xa6 ,0xd0 ,0x75 ,0x4e ,0xcc, 0x34 ,0xaf ,0x36 ,0x08 ,0x23 ,0xef ,0x7d ,0x97 ,0x97 ,0xbf ,0x5d ,0x21 ,0xce ,0x14 ,0xa8 ,0xe3, 0x4b ,0x5e ,0x4a ,0xe1 ,0x61 ,0xcf ,0x0a ,0xca ,0x37 ,0x5e ,0x00 ,0xc7 ,0x95 ,0xee ,0xc5 ,0x13, 0xe5 ,0x4d ,0x9e ,0x73 ,0xdf ,0xd3 ,0x29 ,0xa6 ,0x53 ,0x43 ,0x64 ,0x50 ,0x26 ,0xbc ,0x2a ,0x68, 0xb0 ,0x19 ,0x06 ,0xb1 ,0xdd ,0x20 ,0x72 ,0xd8 ,0xa7 ,0xd9 ,0x19 ,0x5b ,0x93 ,0xff ,0x01 ,0x0f, 0x71 ,0x14 ,0xfa ,0x9f ,0xa5 ,0x92 ,0x37 ,0x31 ,0x8b ,0x6f ,0x3b ,0x04 ,0x64 ,0x8e ,0x14 ,0xb8, 0x08 ,0x49 ,0xbe ,0x47 ,0x8a ,0x12 ,0xd8 ,0x42 ,0x93 ,0x20 ,0x54 ,0x20 ,0x8a ,0x3a ,0xe1 ,0xd5, 0xfc ,0xf8 ,0x07 ,0x71 ,0x98 ,0x58 ,0x24 ,0xbc ,0x30 ,0x06 ,0xe2 ,0x8d ,0x7a ,0xd0 ,0xe9 ,0xc2, 0x4a ,0x4e ,0x0e ,0xd2 ,0x3e ,0xdf ,0x5e ,0x1b ,0x2b ,0xdb ,0xfb ,0x19 ,0x10 ,0x07 ,0x33 ,0x72, 0xe9 ,0x1c ,0x6c ,0x0f ,0x71 ,0x60 ,0x07 ,0x55 ,0x15 ,0x35 ,0x97 ,0x06 ,0x82 ,0x76 ,0xe9 ,0x10 }; /* Original Data for 4K rsa test*/ static unsigned char data_4096[] = { 0x61 ,0x46 ,0xe0 ,0x3c ,0x38 ,0xc0 ,0x9b ,0xdf ,0x78 ,0x87 ,0xe3 ,0x5e ,0x08 ,0xa1 ,0x97 ,0x53, 0x41 ,0x90 ,0x8e ,0x34 ,0x1c ,0x91 ,0x73 ,0xd0 ,0xe1 ,0x08 ,0x2b ,0xf0 ,0x7d ,0xd1 ,0xa6 ,0x34, 0x84 ,0xc3 ,0xd9 ,0x53 ,0x2f ,0x8a ,0x6b ,0xb3 ,0xcc ,0x6f ,0x95 ,0xe5 ,0x93 ,0x55 ,0x78 ,0xe4, 0xd6 ,0x3b ,0x84 ,0x95 ,0xbf ,0xf9 ,0x38 ,0x30 ,0x5d ,0xbf ,0x00 ,0xe8 ,0xcd ,0xf2 ,0xfc ,0xbc, 0x38 ,0xe3 ,0x25 ,0x1b ,0x3f ,0xc6 ,0x6d ,0x52 ,0x4c ,0x58 ,0x1d ,0xbe ,0x3e ,0x2b ,0x1e ,0x48, 0x51 ,0xb5 ,0x38 ,0xed ,0x95 ,0xe9 ,0x1a ,0x07 ,0xfb ,0x2c ,0x29 ,0x0e ,0x87 ,0xa1 ,0xec ,0x12, 0x2d ,0x75 ,0xfa ,0x99 ,0x76 ,0x0f ,0xd3 ,0x5b ,0xf8 ,0x10 ,0xeb ,0x52 ,0xf0 ,0x58 ,0x9c ,0x78, 0xf7 ,0xb5 ,0xf7 ,0x84 ,0xc0 ,0xa1 ,0x6c ,0x99 ,0xce ,0x05 ,0xe3 ,0xaf ,0x60 ,0x92 ,0xc8 ,0x59, 0x8b ,0x59 ,0xcf ,0x18 ,0xc5 ,0xfd ,0x57 ,0x2f ,0xd1 ,0x1c ,0x7b ,0x59 ,0x57 ,0x96 ,0x81 ,0xc8, 0x7c ,0x67 ,0x24 ,0x8f ,0xdc ,0xc6 ,0x75 ,0x29 ,0x46 ,0xda ,0xab ,0x6c ,0x9c ,0xb4 ,0xce ,0xd9, 0x18 ,0xb8 ,0xe3 ,0x9e ,0x83 ,0xb3 ,0x97 ,0x24 ,0x74 ,0x42 ,0x10 ,0x54 ,0xc6 ,0x54 ,0xac ,0xfa, 0xcf ,0xbc ,0xe1 ,0x43 ,0xab ,0xcf ,0x38 ,0x94 ,0x69 ,0x52 ,0xdd ,0xb7 ,0xb1 ,0xdf ,0xb8 ,0xc9, 0x9b ,0xcb ,0xe5 ,0x3f ,0x39 ,0x9c ,0x8f ,0x5d ,0x8e ,0x5f ,0xba ,0xc2 ,0x86 ,0x29 ,0xcd ,0x3e, 0x76 ,0xae ,0x80 ,0x60 ,0xce ,0x1a ,0x7f ,0x33 ,0xef ,0x0a ,0x1e ,0x9f ,0xeb ,0xa9 ,0x1e ,0x43, 0xb0 ,0xdf ,0x91 ,0xf4 ,0x3f ,0x1c ,0x84 ,0x6f ,0x43 ,0x57 ,0xc8 ,0xa6 ,0xd0 ,0x75 ,0x4e ,0xcc, 0x34 ,0xaf ,0x36 ,0x08 ,0x23 ,0xef ,0x7d ,0x97 ,0x97 ,0xbf ,0x5d ,0x21 ,0xce ,0x14 ,0xa8 ,0xe3, 0x4b ,0x5e ,0x4a ,0xe1 ,0x61 ,0xcf ,0x0a ,0xca ,0x37 ,0x5e ,0x00 ,0xc7 ,0x95 ,0xee ,0xc5 ,0x13, 0xe5 ,0x4d ,0x9e ,0x73 ,0xdf ,0xd3 ,0x29 ,0xa6 ,0x53 ,0x43 ,0x64 ,0x50 ,0x26 ,0xbc ,0x2a ,0x68, 0xb0 ,0x19 ,0x06 ,0xb1 ,0xdd ,0x20 ,0x72 ,0xd8 ,0xa7 ,0xd9 ,0x19 ,0x5b ,0x93 ,0xff ,0x01 ,0x0f, 0x71 ,0x14 ,0xfa ,0x9f ,0xa5 ,0x92 ,0x37 ,0x31 ,0x8b ,0x6f ,0x3b ,0x04 ,0x64 ,0x8e ,0x14 ,0xb8, 0x08 ,0x49 ,0xbe ,0x47 ,0x8a ,0x12 ,0xd8 ,0x42 ,0x93 ,0x20 ,0x54 ,0x20 ,0x8a ,0x3a ,0xe1 ,0xd5, 0xfc ,0xf8 ,0x07 ,0x71 ,0x98 ,0x58 ,0x24 ,0xbc ,0x30 ,0x06 ,0xe2 ,0x8d ,0x7a ,0xd0 ,0xe9 ,0xc2, 0x4a ,0x4e ,0x0e ,0xd2 ,0x3e ,0xdf ,0x5e ,0x1b ,0x2b ,0xdb ,0xfb ,0x19 ,0x10 ,0x07 ,0x33 ,0x72, 0xe9 ,0x1c ,0x6c ,0x0f ,0x71 ,0x60 ,0x07 ,0x55 ,0x15 ,0x35 ,0x97 ,0x06 ,0x82 ,0x76 ,0xe9 ,0x10, 0x30 ,0x53 ,0x5a ,0xf8 ,0x5e ,0x2c ,0x3b ,0xd3 ,0xe7 ,0x07 ,0xc9 ,0xfc ,0x10 ,0x43 ,0xac ,0xb1, 0xd7 ,0x03 ,0xdb ,0x08 ,0xa0 ,0x9e ,0x54 ,0xe2 ,0xa4 ,0x6e ,0x43 ,0xfe ,0xe4 ,0x6a ,0xe2 ,0xd2, 0x8c ,0x0d ,0xb7 ,0xf7 ,0x75 ,0x5a ,0x2b ,0x68 ,0x99 ,0x97 ,0xf7 ,0xf9 ,0x22 ,0xa3 ,0x8a ,0xdc, 0x67 ,0xf2 ,0x62 ,0x80 ,0x03 ,0xd6 ,0x4b ,0x41 ,0xe4 ,0xdf ,0x05 ,0x9b ,0x64 ,0xb0 ,0xaf ,0x73, 0x4b ,0x54 ,0x42 ,0xdd ,0x95 ,0x01 ,0x46 ,0xa8 ,0xb2 ,0x90 ,0xb4 ,0xf1 ,0xf4 ,0x74 ,0x79 ,0x13, 0x18 ,0xe5 ,0xcb ,0xe7 ,0xde ,0x48 ,0x2a ,0xbe ,0xf6 ,0xbe ,0x13 ,0x13 ,0x67 ,0x17 ,0xd9 ,0x74, 0x38 ,0x07 ,0x76 ,0xa4 ,0x8f ,0x9a ,0x79 ,0xdb ,0x63 ,0x68 ,0x65 ,0xa6 ,0x8b ,0xa0 ,0x6c ,0xa9, 0x35 ,0xf3 ,0xe4 ,0xa1 ,0xb9 ,0x37 ,0xdf ,0x1c ,0x92 ,0x2d ,0xc5 ,0x7b ,0xfd ,0xef ,0xa9 ,0x17 }; static pthread_t async_poll_thread; static uint8_t *out_data = NULL; static size_t out_len = 0; static size_t max_len = 0; static int qat_rsa_sign_test(RSA_METHOD *meth, RSA *rsa, const uint8_t *in_data, size_t in_len, int async_mode); static int qat_rsa_decrypt_test(RSA_METHOD *meth, RSA *rsa, const uint8_t *in_data, size_t in_len, int async_mode); static void qat_rsa_handle_async_ctx(async_ctx *ctx) { if (NULL == out_data) { T_ERROR("out_data is NULL\n"); goto err; } /* Copy data from async_ctx */ if (bssl_qat_async_ctx_copy_result(ctx, out_data, &out_len, max_len)) { T_ERROR("Fail to get output results\n"); goto err; } err: bssl_qat_async_finish_job(ctx); } static void *qat_rsa_polling_async_ctx(void *args) { async_ctx *ctx = (async_ctx *)args; T_DEBUG("RSA test polling result thread start\n"); while (*ctx->currjob_status != ASYNC_JOB_COMPLETE) { usleep(10); } T_DEBUG("RSA test polling result thread detect data ready\n"); qat_rsa_handle_async_ctx(ctx); T_DEBUG("RSA test polling result thread finished\n"); return (void*)0; } static async_ctx *qat_rsa_init_async_ctx(void) { async_ctx *ctx = bssl_qat_async_start_job(); ASYNC_JOB *job = ctx->currjob; T_DEBUG("RSA init async_ctx async ctx:%p, job:%p, job->status:%d \n", ctx, job, job->status); pthread_create(&async_poll_thread, NULL, qat_rsa_polling_async_ctx, ctx); return ctx; } static void qat_rsa_wait_async_ctx(size_t *out_len) { pthread_join(async_poll_thread, NULL); } /* async_mode 0: sync mode 1: async mode */ int qat_rsa_test(const EVP_PKEY *pkey, int flag) { RSA *rsa; RSA_METHOD *meth; size_t rsa_size; uint8_t *in_data; rsa = EVP_PKEY_get0_RSA(pkey); rsa_size = RSA_size(rsa); /* bytes */ switch(rsa_size) { case 256: in_data = data_2048; break; case 384: in_data = data_3072; break; case 512: in_data = data_4096; break; default: T_WARN("RSA size %ld bits not supported, 2k/3k/4k suggested\n", rsa_size * 8); return -1; } if (NULL == (meth = bssl_engine_get_rsa_method())) { return -1; } if (flag & RSA_ASYNC_MODE) { max_len = rsa_size; qat_rsa_init_async_ctx(); } if (flag & RSA_DECRYPT_TEST) { qat_rsa_decrypt_test(meth, rsa, in_data, rsa_size, flag & RSA_ASYNC_MODE); } else { qat_rsa_sign_test(meth, rsa, in_data, rsa_size, flag & RSA_ASYNC_MODE); } return out_len; } int qat_rsa_sign_test(RSA_METHOD *meth, RSA *rsa, const uint8_t *in_data, size_t in_len, int async_mode) { uint8_t *ver_data = NULL; if (!meth || !rsa) { return 1; /* error */ } if (NULL == (out_data = (unsigned char *)OPENSSL_zalloc(in_len))) { T_ERROR("Failed to allocate buffer\n"); return 1; /* error */ } if (!meth->sign_raw) { T_ERROR("QAT RSA sign_raw function is NULL.\n"); OPENSSL_free(out_data); return 1; /* error */ } /* Signing */ T_DUMP_RSA_SIGN_INPUT(in_data, in_len); meth->sign_raw(rsa, &out_len, out_data, in_len, in_data, in_len, RSA_NO_PADDING); if (async_mode) { qat_rsa_wait_async_ctx(&out_len); } T_DUMP_RSA_SIGN_OUTPUT(out_data, out_len); if (in_len != out_len) { T_ERROR("RSA Sign: wrong length\n"); return 1; /* fail */ } else { T_DEBUG("RSA Sign(%s mode): OK\n", async_mode?"Async":"Sync"); } /* Verifying */ if (NULL == (ver_data = (unsigned char *)OPENSSL_zalloc(in_len))) { T_ERROR("Failed to allocate buffer\n"); return 1; /* fail */ } out_len = RSA_meth_get_pub_dec(RSA_PKCS1_OpenSSL())(in_len, out_data, ver_data, rsa, RSA_NO_PADDING); if (in_len != out_len) { T_ERROR("RSA Verify: wrong length\n"); } else { T_DEBUG("RSA Verify: OK\n"); } OPENSSL_free(ver_data); return 0; } int qat_rsa_decrypt_test(RSA_METHOD *meth, RSA *rsa, const uint8_t *in_data, size_t in_len, int async_mode) { uint8_t *enc_data = NULL; /* for public encryption */ if (!meth || !rsa) { return 1; /* error */ } if (NULL == (enc_data = (unsigned char *)OPENSSL_zalloc(in_len))) { T_ERROR("Failed to allocate buffer\n"); return 1; /* fail */ } /* Pub encrypt */ out_len = RSA_meth_get_pub_enc(RSA_PKCS1_OpenSSL())(in_len, in_data, enc_data, rsa, RSA_NO_PADDING); if (in_len != out_len) { T_ERROR("RSA pub encrypt: wrong length\n"); } else { T_DEBUG("RSA pub encrypt: OK\n"); } /* Decrypting */ if (NULL == (out_data = (unsigned char *)OPENSSL_zalloc(in_len))) { T_ERROR("Failed to allocate buffer\n"); OPENSSL_free(enc_data); return 1; /* error */ } T_DUMP_RSA_DECRYPT_INPUT(enc_data, out_len); meth->decrypt(rsa, &out_len, out_data, in_len, enc_data, in_len, RSA_NO_PADDING); if (async_mode) { qat_rsa_wait_async_ctx(&out_len); } T_DUMP_RSA_DECRYPT_OUTPUT(out_data, out_len); if (in_len != out_len) { T_ERROR("RSA Decrypt: wrong length\n"); OPENSSL_free(enc_data); OPENSSL_free(out_data); return 1; /* fail */ } else { T_DEBUG("RSA Decrypt(%s mode): OK\n", async_mode?"Async":"Sync"); } OPENSSL_free(enc_data); return 0; } qatengine-1.9.0/test_bssl/test_bssl_rsa.h000066400000000000000000000043311500416242000205110ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file test_bssl_rsa.h * * This file provides a QAT Engine test functions. * *****************************************************************************/ #ifndef TEST_BSSL_RSA_H # define TEST_BSSL_RSA_H enum { RSA_ASYNC_MODE = 1, RSA_DECRYPT_TEST = 2, }; int qat_rsa_test(const EVP_PKEY *pkey, int async_mode); #endif /* TEST_BSSL_RSA_H */ qatengine-1.9.0/test_bssl/test_bssl_utils.c000066400000000000000000000063731500416242000210670ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file test_bssl_utils.c * * This file provides a QAT Engine test functions. * *****************************************************************************/ /* macros defined to allow use of the cpu get and set affinity functions */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #ifndef __USE_GNU # define __USE_GNU #endif #ifndef QAT_DEBUG # define TEST_DEBUG #endif #include #include "qat_utils.h" /* OpenSSL Includes */ #include #include #include void *qat_load_priv_key(const char *key_path) { EVP_PKEY *pkey = NULL; BIO *bp; if (access(key_path, F_OK)) { printf("-- File %s does not exist\n", key_path); return NULL; } bp = BIO_new_file(key_path, "r"); if (!bp) { printf("-- BIO new failed\n"); return NULL; } pkey = PEM_read_bio_PrivateKey(bp, NULL, 0, NULL); if (!pkey) { printf("-- Error in PEM_read_bio_PrivateKey\n"); return NULL; } return pkey; } void qat_hex_dump2(const unsigned char p[], int l) { int i; if (NULL != p && l > 0) { for (i = 0; i < l; i++) { if (i > 0 && i % 16 == 0) puts(""); else if (i > 0 && i % 8 == 0) { putc('-', stdout); putc(' ', stdout); } printf("%02x ", p[i]); } } puts(""); } qatengine-1.9.0/test_bssl/test_bssl_utils.h000066400000000000000000000162051500416242000210670ustar00rootroot00000000000000/* ==================================================================== * * * BSD LICENSE * * Copyright(c) 2022-2025 Intel Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * ==================================================================== */ /***************************************************************************** * @file test_bssl_utils.h * * This file provides a QAT Engine test functions. * *****************************************************************************/ #ifndef TEST_BSSL_UTILS_H # define TEST_BSSL_UTILS_H #ifndef QAT_DEBUG # define PRINT_TIPS() printf("To get more debug information, enable \ QATEngine option: --enable-qat_debug\n"); #else # define PRINT_TIPS() #endif # define T_DEBUG(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ printf("[DEBUG][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(stdout); \ } while (0) # define T_ERROR(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ printf("[ERROR][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(stdout); \ } while (0) # define T_WARN(fmt_str, ...) \ do { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC, &ts); \ printf("[WARN][%lld.%06ld] PID [%d]" \ " Thread [%lx][%s:%d:%s()] "fmt_str, \ (long long)ts.tv_sec, \ ts.tv_nsec / NANO_TO_MICROSECS, \ getpid(), (long)pthread_self(), __FILE__, \ __LINE__,__func__,##__VA_ARGS__); \ fflush(stdout); \ } while (0) #ifdef QAT_DEBUG # define T_DUMP_ALGO_INPUT_DATA(data, size, tag) \ do { \ printf("=========================\n"); \ printf("%s Input(Bytes: %ld):\n", #tag, size); \ qat_hex_dump2(data, size); \ printf("=========================\n"); \ fflush(stdout); \ } while (0) # define T_DUMP_ALGO_OUTPUT_DATA(data, size, tag) \ do { \ printf("=========================\n"); \ printf("%s Output(Bytes: %ld):\n", #tag, size); \ qat_hex_dump2(data, size); \ printf("=========================\n"); \ fflush(stdout); \ } while (0) # define T_DUMP_ECDSA_SIGN_INPUT(data, size) \ do { \ printf("=========================\n"); \ printf("ECDSA Sign Input Message(Bytes: %ld):\n", size);\ printf("%s\n", data); \ printf("=========================\n"); \ fflush(stdout); \ } while (0) # define T_DUMP_ECDSA_SIGN_OUTPUT(data, size) \ do { \ printf("=========================\n"); \ printf("ECDSA Sign Output(Bytes: %d):\n", size); \ qat_hex_dump2(data, size); \ printf("=========================\n"); \ fflush(stdout); \ } while (0) # define T_DUMP_RSA_SIGN_INPUT(data, size) \ T_DUMP_ALGO_INPUT_DATA(data, size, RSA Sign) # define T_DUMP_RSA_SIGN_OUTPUT(data, size) \ T_DUMP_ALGO_OUTPUT_DATA(data, size, RSA Sign) # define T_DUMP_RSA_DECRYPT_INPUT(data, size) \ T_DUMP_ALGO_INPUT_DATA(data, size, RSA Decrypt) # define T_DUMP_RSA_DECRYPT_OUTPUT(data, size) \ T_DUMP_ALGO_OUTPUT_DATA(data, size, RSA Decrypt) #else # define T_DUMP_ECDSA_SIGN_INPUT(data, size) # define T_DUMP_ECDSA_SIGN_OUTPUT(data, size) # define T_DUMP_RSA_SIGN_INPUT(data, size) # define T_DUMP_RSA_SIGN_OUTPUT(data, size) # define T_DUMP_RSA_DECRYPT_INPUT(data, size) # define T_DUMP_RSA_DECRYPT_OUTPUT(data, size) #endif void *qat_load_priv_key(const char *key_path); void qat_hex_dump2(const unsigned char p[], int l); #endif /* TEST_BSSL_UTILS_H */ qatengine-1.9.0/testapp.sh000077500000000000000000000060471500416242000155140ustar00rootroot00000000000000#!/usr/bin/env bash #run testapp date > testapp.log echo $1 if [ -z $1 ] then echo "Parameter QAT_SW or QAT_HW required." echo "usage : ./testapp.sh QAT_HW | QAT_SW" exit 1 fi if [ ! -f "testapp" ]; then echo "testapp does not exist. make test" make test fi ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa2048 -sign >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa2048 -verify >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa2048 -encrypt >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa2048 -decrypt >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa3072 -sign >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa3072 -verify >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa3072 -encrypt >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa3072 -decrypt >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa4096 -sign >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa4096 -verify >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa4096 -encrypt >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v rsa4096 -decrypt >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdhp256 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdhp384 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdhx25519 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdhx448 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdsap256 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdsap384 >> testapp.log if [ $1 = QAT_SW ] then ./testapp -engine qatengine -c 1 -n 1 -nc 1 -v aes128gcm >> testapp.log ./testapp -engine qatengine -c 1 -n 1 -nc 1 -v aes256gcm >> testapp.log fi if [ $1 = QAT_HW ] then ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdhp521 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v ecdsap521 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v dsa1024 -sign >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v dsa2048 -verify >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v dsa4096 -verify >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v dh >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v prf >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v aes128_cbc_hmac_sha1 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v aes256_cbc_hmac_sha1 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v aes128_cbc_hmac_sha256 >> testapp.log ./testapp -engine qatengine -async_jobs 8 -c 1 -n 1 -nc 1 -v aes256_cbc_hmac_sha256 >> testapp.log fi