diff --git a/.gitignore b/.gitignore index 2e602122..0d786d62 100644 --- a/.gitignore +++ b/.gitignore @@ -36,10 +36,13 @@ qat_contig_mem_test *.lib *.la testapp +qatengine_test # Autotools generated files test/.deps +test_bssl/.deps test/.dirstamp +test_bssl/.dirstamp /.deps /.libs /m4 diff --git a/LICENSE.BORINGSSL b/LICENSE.BORINGSSL new file mode 100644 index 00000000..ae1de2be --- /dev/null +++ b/LICENSE.BORINGSSL @@ -0,0 +1,251 @@ +BoringSSL 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. diff --git a/Makefile.am b/Makefile.am index 10d16727..d462d2a0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,10 @@ ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = subdir-objects lib_LTLIBRARIES = @LIBQATNAME@.la +if QAT_BORINGSSL +bin_PROGRAMS = qatengine_test +endif if QAT_HW if QAT_HW_CONTIG_MEM @@ -18,7 +22,8 @@ if QAT_HW_USDM endif endif -QAT_COMMON_SRC = e_qat.c \ +if !QAT_BORINGSSL + QAT_COMMON_SRC = e_qat.c \ qat_fork.c \ qat_events.c \ qat_utils.c \ @@ -89,6 +94,28 @@ 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_ERR_SRC = e_qat_err.c + +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_rsa.c \ + qat_hw_rsa_crt.c \ + qat_hw_ec.c +endif +endif @LIBQATNAME@_la_SOURCES = ${QAT_COMMON_SRC} \ ${QAT_PROV_SRC} \ @@ -103,6 +130,7 @@ AM_CPPFLAGS = $(includes_openssl) $(includes_qat_hw_usdm) \ AM_CFLAGS = $(cflags) $(cflags_cc_opt) $(cflags_qat_debug_file) \ $(cflags_mem_driver) $(cflags_openssl_3) \ + $(cflags_boringssl) \ $(cflags_qat_engine_id) $(cflags_qat_hw_intree) \ $(cflags_qat_hw) $(cflags_qat_sw) $(cflags_qat_sw_ipsec) \ $(cflags_qat_rsa) $(cflags_qat_ecx) $(cflags_qat_ecdsa) \ @@ -125,10 +153,25 @@ AM_CFLAGS = $(cflags) $(cflags_cc_opt) $(cflags_qat_debug_file) \ -shared $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) \ $(QAT_HW_MEM_LIB) $(QAT_SW_CRYPTO_MB_LIB) \ $(QAT_SW_IPSEC_MB_LIB) +if QAT_BORINGSSL +override @LIBQATNAME@_la_LDFLAGS := $(subst -module, ,${@LIBQATNAME@_la_LDFLAGS}) $(QAT_BORINGSSL_LIB) +override @LIBQATNAME@_la_LDFLAGS := $(subst -shared, ,${@LIBQATNAME@_la_LDFLAGS}) $(QAT_BORINGSSL_LIB) +endif + +if QAT_BORINGSSL +qatengine_test_LDFLAGS = $(QAT_LD_LIB) $(QAT_HW_DRIVER_LIB) \ + $(QAT_HW_MEM_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 +endif mostlyclean-generic: - -rm -f *.obj lib tags core .pure .nfs* \ - *.old *.bak fluff *.so *.sl *.dll test/*.obj testapp + -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 if QAT_ERR_FILES_BUILD MAKE = make err-files && make diff --git a/README.md b/README.md index 7ea5fa69..da756a21 100644 --- a/README.md +++ b/README.md @@ -377,6 +377,13 @@ algorithms and IPSec_mb library for AES-GCM). +
+[For BoringSSL Support only] Build the Intel® QuickAssist Technology BoringSSL* Library + +Please refer [BoringSSL section](docs/bssl_support.md) for steps to build the Intel® QuickAssist Technology BoringSSL* library which supports RSA and ECDSA QAT Hardware Acceleration using BoringSSL. + +
+
Copy the Intel® QuickAssist Technology Driver config file(s) diff --git a/configure.ac b/configure.ac index 4245b3f4..0ba33c62 100644 --- a/configure.ac +++ b/configure.ac @@ -176,7 +176,7 @@ 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])) + [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, @@ -280,26 +280,50 @@ AS_IF([test "$host_cpu" = "x86_64"], [AC_SUBST([openssl3_lib], "lib64")], [AC_SU # OpenSSL install dir or set system openssl install dir if not provided if test "x$with_openssl_install_dir" != "x" then - ac_default_prefix=$with_openssl_install_dir - if test "`grep "define OPENSSL_VERSION_MAJOR" $with_openssl_install_dir/include/openssl/opensslv.h | awk '{print $4}'`" = "3" + if test -f $with_openssl_install_dir/include/openssl/base.h then - if test "x$enable_qat_provider" = "xyes" + if test "`grep "define BORINGSSL_API_VERSION" $with_openssl_install_dir/include/openssl/base.h | wc -l`" = "1" then - AC_MSG_NOTICE([Build QAT Provider against OpenSSL 3.0]) - 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.0]) - 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"]) + AC_MSG_NOTICE([Build QAT engine against BoringSSL]) + AC_SUBST([cflags_boringssl], ["-DQAT_BORINGSSL"]) + if test ! -d "$with_openssl_install_dir/lib" + then + AC_MSG_ERROR([$with_openssl_install_dir/lib not exist]) + else + if test "x`find $with_openssl_install_dir/lib -name '*.so' -o -name '*.a'`" == "x" + then + AC_MSG_ERROR([Not found any librares in $with_openssl_install_dir/lib]) + fi + fi + AC_SUBST([QAT_BORINGSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/lib -L\$(with_openssl_install_dir)/lib -ldecrepit -lcrypto -lssl"]) + AC_SUBST([LIBQATNAME], "libqatengine") + if test -d "$with_openssl_install_dir/crypto" + then + AC_SUBST([cflags_boringssl], ["-DQAT_BORINGSSL -DBSSL_SOURCE"]) + fi fi else - AC_MSG_NOTICE([Build QAT engine against OpenSSL 1.1.1]) - libdir="\$(with_openssl_install_dir)/lib/engines-1.1" - AC_SUBST([OPENSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/lib -L\$(with_openssl_install_dir)/lib -lcrypto"]) + ac_default_prefix=$with_openssl_install_dir + if test "`grep "define OPENSSL_VERSION_MAJOR" $with_openssl_install_dir/include/openssl/opensslv.h | awk '{print $4}'`" = "3" + then + if test "x$enable_qat_provider" = "xyes" + then + AC_MSG_NOTICE([Build QAT Provider against OpenSSL 3.0]) + 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.0]) + 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 + else + AC_MSG_NOTICE([Build QAT engine against OpenSSL 1.1.1]) + libdir="\$(with_openssl_install_dir)/lib/engines-1.1" + AC_SUBST([OPENSSL_LIB], ["-Wl,-rpath,\$(with_openssl_install_dir)/lib -L\$(with_openssl_install_dir)/lib -lcrypto"]) + fi fi AC_SUBST([includes_openssl], ["-I\$(with_openssl_install_dir)/include"]) else @@ -328,6 +352,7 @@ else 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"]) # If both QAT HW and QAT SW configured, then check the libraries from standard location and use accordingly. if test "x$cflags_qat_hw_intree" = "x" @@ -402,6 +427,28 @@ then fi AM_CONDITIONAL([QAT_ERR_FILES_BUILD], [test "x$with_openssl_dir" != "x"]) +# Disabled unsupported algorithms with BoringSSl enabled +if test "x$cflags_boringssl" != "x" +then + # Disabled all HW methods that not supported + if test "x$cflags_qat_hw" != "x" + then + AC_SUBST([enable_qat_hw_ciphers], ["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"]) + fi + # Show error when both QAT SW enabled and BoringSSl enabled + if test "x$cflags_qat_sw" != "x" + then + AC_MSG_ERROR([Not supported for QAT SW acceleration with BoringSSl enabled]) + fi +fi + # Checking the parameters given and parsing the relevant flags if test "x$cflags_qat_hw" != "x" -a "x$cflags_qat_sw" != "x" @@ -522,8 +569,14 @@ then AC_MSG_NOTICE([Accelerating ECDSA P256 &P384 to Software (Multi-buffer)]) else if test "x$enable_qat_hw_ecdsa" != "xno" -a "x$cflags_qat_hw" != "x" then + if test "x$cflags_boringssl" != "x" -a "x$enable_qat_hw_ecdsa" != "xyes" + then + AC_SUBST([cflags_qat_ecdsa], ["-DDISABLE_QAT_HW_ECDSA"]) + AC_MSG_NOTICE([Not Accelerating ECDSA to QAT_HW]) + else AC_SUBST([cflags_qat_ecdsa], ["-DENABLE_QAT_HW_ECDSA"]) AC_MSG_NOTICE([Accelerating ECDSA to Hardware]) + fi fi fi fi @@ -745,13 +798,13 @@ case "$host_os" in *linux*) if test "`cc --version | head -1 | awk '{print $3>=4.9}' 2>/dev/null`" = "1" then - AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong -fno-strict-overflow"]) + AC_SUBST([cflags], ["-fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong -fno-strict-overflow"]) else - AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector -fno-strict-overflow"]) + AC_SUBST([cflags], ["-fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector -fno-strict-overflow"]) fi ;; *freebsd*) - AC_SUBST([cflags], ["-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong"]) + AC_SUBST([cflags], ["-fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong"]) ;; *) ;; esac diff --git a/docs/bssl_support.md b/docs/bssl_support.md new file mode 100644 index 00000000..29044aba --- /dev/null +++ b/docs/bssl_support.md @@ -0,0 +1,102 @@ +# 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) + +## Limitations +Some limitations specific for the current BoringSSL* Library: +* NIST Binary Curves and NIST Koblitz Curves are not supported by BoringSSL. +* Supports QAT_HW on Linux Only. QAT_SW and QAT_HW FreeBSD is not supported. +* `RSA_padding_add_PKCS1_OAEP` fucntion 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 +### Install Prerequisites +Refer to the [Install Prerequisites](../README.md##installation-instructions) + +**Note:** Replace the OpenSSL with BoringSSL installation described below. + +### Build BoringSSL + +Clone BoringSSL* from Github* at the following location: +```bash +git clone https://github.com/google/boringssl.git +``` + +Navigate to BoringSSL directory: +```bash +cd +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. + ```bash + 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. + ```bash + 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/ + ``` + +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. + ```bash + cd + ./autogen.sh + ``` + Note: autogen.sh will regenerate autoconf tools files. + + To build and install the Intel® QAT BoringSSL* Library: + ```bash + ./configure --with-openssl_install_dir= --with-qat_hw_dir= + make + make install + ``` + 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 + ```bash + # ./qatengine_test -h + Usage: ./qatengine_test [-h/-d/-a] <-k> + -a : Enable async mode + -d : Test on rsa private decrypt + -h : Print all avaliable 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 is 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. diff --git a/docs/features.md b/docs/features.md index 5c3b68e2..f9fbe8c9 100644 --- a/docs/features.md +++ b/docs/features.md @@ -42,3 +42,5 @@ Note: RSA Padding schemes are handled by OpenSSL\* rather than accelerated, so the engine supports the same padding schemes as OpenSSL does natively. + +## [BoringSSL Support](bssl_support.md) \ No newline at end of file diff --git a/docs/licensing.md b/docs/licensing.md index cb58f27b..4c360a40 100644 --- a/docs/licensing.md +++ b/docs/licensing.md @@ -5,5 +5,6 @@ The Licensing of the files within this project is split as follows: | Component |License | Details | |---|---|---| | Intel® QuickAssist Technology(QAT) OpenSSL* Engine | BSD-3-Clause | Intel® QuickAssist Technology(QAT) OpenSSL\* Engine - BSD-3-Clause. This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/). Please see the `LICENSE` and `LICENSE.OPENSSL` file contained in the top level folder. Further details can be found in the file headers of the relevant files. | +| Intel® QuickAssist Technology(QAT) BoringSSL* Library | BSD License |Intel® QuickAssist Technology(QAT) BoringSSL* Library - BSD License. This product includes software developed by the BoringSSL Project (https://boringssl.googlesource.com/boringssl/). Please see the LICENSE.BORINGSSL contained in the top-level folder. Further details can be found in the file headers of the relevant files. | | Example Intel® Contiguous Memory Driver contained within the folder `qat_contig_mem` | GPLv2 License | Please see the file headers within the `qat_contig_mem` folder, and the full GPLv2 license contained in the file `LICENSE.GPL` within the `qat_contig_mem` folder. | |Example Intel® QuickAssist Technology Driver Configuration Files contained within the folder hierarchy `qat` | 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` folder. | diff --git a/docs/limitations.md b/docs/limitations.md index 252479b9..14c1bd57 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -47,4 +47,4 @@ 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. + implications. \ No newline at end of file diff --git a/docs/software_requirements.md b/docs/software_requirements.md index 79c84f84..577b0fca 100644 --- a/docs/software_requirements.md +++ b/docs/software_requirements.md @@ -2,7 +2,7 @@ ## qat_hw Requirements Successful operation of QAT Hardware acceleration requires a software tool chain -that supports OpenSSL\* 1.1.1 or OpenSSL\* 3.0 and Intel® QuickAssist +that supports OpenSSL\* 1.1.1 or OpenSSL\* 3.0 or BoringSSL\* and Intel® QuickAssist Technology Driver for Linux or Intel® QuickAssist Technology Driver for FreeBSD. This release was validated on the following: @@ -11,16 +11,17 @@ Driver for FreeBSD. This release was validated on the following: * Intel® Communications Chipset C62X Series Software for Linux\*, version **4.18** * Intel® Communications Chipset C62X Series Software for FreeBSD\*, version **3.12** * OpenSSL\* 1.1.1o & 3.0.3 +* BoringSSL\* commit - [fa3fbda07b] [1] ## qat_sw Requirements Successful operation of the Intel® QAT Software acceleration requires a software tool chain that supports OpenSSL\* 1.1.1 or OpenSSL\* 3.0 and Intel® -Crypto Multi-buffer library(for Asymmetric PKE) cloned from the [ipp-crypto][1] repo. +Crypto Multi-buffer library(for Asymmetric PKE) cloned from the [ipp-crypto][2] repo. The crypto_mb library needs to be installed using the instructions from the -[Crypto Multi-buffer Library][2] Readme. +[Crypto Multi-buffer Library][3] Readme. For QAT SW AES-GCM acceleration, prequisite is to have Intel® -Multi-Buffer crypto for IPsec Library cloned from the [intel-ipsec-mb][3] +Multi-Buffer crypto for IPsec Library cloned from the [intel-ipsec-mb][4] repo and installed using the instructions from the intel-ipsec-mb README. The Intel® QAT Engine supports QAT SW AES-GCM from OpenSSL\* 1.1.1d. @@ -28,11 +29,12 @@ This release was validated on the following: * Operating system: Ubuntu 20.04.2 LTS * Kernel: 5.4.0-62-generic -* Intel® Crypto Multi-buffer library from the [ipp-crypto][1] release +* Intel® Crypto Multi-buffer library from the [ipp-crypto][2] release version **IPP Crypto 2021.5** * Intel® Multi-Buffer crypto for IPsec Library release version **v1.2** * OpenSSL\* 1.1.1o & 3.0.3 -[1]:https://github.com/intel/ipp-crypto -[2]:https://github.com/intel/ipp-crypto/tree/develop/sources/ippcp/crypto_mb -[3]:https://github.com/intel/intel-ipsec-mb +[1]:https://github.com/google/boringssl/tree/fa3fbda07bbf70925453d6a3c25a7aa455aa1cef +[2]:https://github.com/intel/ipp-crypto +[3]:https://github.com/intel/ipp-crypto/tree/develop/sources/ippcp/crypto_mb +[4]:https://github.com/intel/intel-ipsec-mb diff --git a/e_qat.c b/e_qat.c index 92a3652b..bc4b8817 100644 --- a/e_qat.c +++ b/e_qat.c @@ -84,12 +84,16 @@ #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" +#endif /* QAT_BORINGSSL */ /* QAT includes */ # include "cpa.h" @@ -114,7 +118,7 @@ /* OpenSSL Includes */ #include -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined QAT_BORINGSSL # include #endif #include @@ -252,6 +256,7 @@ static int bind_qat(ENGINE *e, const char *id); Use this flag to distinguish it from the other cases. */ int qat_reload_algo = 0; +#ifndef QAT_BORINGSSL const ENGINE_CMD_DEFN qat_cmd_defns[] = { { QAT_CMD_ENABLE_EXTERNAL_POLLING, @@ -384,6 +389,7 @@ const ENGINE_CMD_DEFN qat_cmd_defns[] = { {0, NULL, NULL, 0} }; +#endif /* QAT_BORINGSSL */ /****************************************************************************** * function: @@ -400,19 +406,25 @@ 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(); +#endif /* QAT_BORINGSSL */ #endif #if defined(QAT_SW_IPSEC) || defined(QAT_HW) +#ifndef QAT_BORINGSSL qat_free_ciphers(); #endif +#endif #ifdef QAT_SW_IPSEC # ifdef ENABLE_QAT_SW_GCM @@ -690,6 +702,8 @@ int qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 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"); @@ -711,6 +725,7 @@ int qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 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, @@ -718,6 +733,7 @@ int qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 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") @@ -764,6 +780,7 @@ int qat_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) retVal = 0; # endif break; +#endif /* QAT_BORINGSSL */ #endif case QAT_CMD_ENABLE_HEURISTIC_POLLING: @@ -1020,14 +1037,17 @@ static int bind_qat(ENGINE *e, const char *id) } # endif +#ifndef QAT_BORINGSSL qat_create_digest_meth(); if (!ENGINE_set_digests(e, qat_digest_methods)) { WARN("ENGINE_set_digests failed\n"); goto end; } +#endif /* QAT_BORINGSSL */ #endif +#ifndef QAT_BORINGSSL #ifdef QAT_SW_IPSEC if (hw_support()) { # ifdef ENABLE_QAT_SW_GCM @@ -1052,6 +1072,10 @@ static int bind_qat(ENGINE *e, const char *id) pthread_atfork(engine_finish_before_fork_handler, NULL, engine_init_child_at_fork_handler); +#else + /* Set handler to ENGINE_unload_qat and ENGINE_load_qat */ + pthread_atfork(ENGINE_unload_qat, NULL, ENGINE_load_qat); +#endif /* QAT_BORINGSSL */ ret = 1; ret &= ENGINE_set_destroy_function(e, qat_engine_destroy); @@ -1103,7 +1127,16 @@ 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 gobal 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"); @@ -1114,6 +1147,7 @@ static ENGINE *engine_qat(void) if (!bind_qat(ret, engine_qat_id)) { fprintf(stderr, "Qat Engine bind failed\n"); ENGINE_free(ret); + ENGINE_QAT_PTR_RESET(); return NULL; } @@ -1138,9 +1172,30 @@ void ENGINE_load_qat(void) } 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 diff --git a/e_qat.h b/e_qat.h index d551e774..98834613 100644 --- a/e_qat.h +++ b/e_qat.h @@ -53,6 +53,10 @@ # include # include +#ifdef QAT_BORINGSSL +# include "qat_bssl.h" +#endif /* QAT_BORINGSSL */ + # ifdef QAT_OPENSSL_3 # include "qat_prov_err.h" # else @@ -495,6 +499,14 @@ extern mb_req_rates mb_sm3_final_req_rates; # 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 /****************************************************************************** * function: diff --git a/e_qat_err.c b/e_qat_err.c index 46b70693..0f4e5d5a 100644 --- a/e_qat_err.c +++ b/e_qat_err.c @@ -11,6 +11,10 @@ #include #include "e_qat_err.h" +#ifdef QAT_BORINGSSL +# define OPENSSL_NO_ERR +#endif + #ifndef OPENSSL_NO_ERR static ERR_STRING_DATA QAT_str_functs[] = { diff --git a/e_qat_err.h b/e_qat_err.h index f964ca7f..5a81f6c3 100644 --- a/e_qat_err.h +++ b/e_qat_err.h @@ -11,10 +11,16 @@ #ifndef HEADER_QATERR_H # define HEADER_QATERR_H +#ifndef QAT_BORINGSSL # include # define QATerr(f, r) ERR_QAT_error((f), (r), OPENSSL_FILE, OPENSSL_LINE) +#else +/* macros redefined to do noting */ +# 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) +#endif # ifdef __cplusplus extern "C" { diff --git a/qat_bssl.c b/qat_bssl.c new file mode 100644 index 00000000..c4d2c35b --- /dev/null +++ b/qat_bssl.c @@ -0,0 +1,993 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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_hw_callback.h" +# include "qat_utils.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)); +} + +/* 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)) +{ + 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); + } +} + +/* 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; + job->copy_op_done = bssl_qat_copy_op_done; + job->free_op_done = bssl_qat_free_op_done; + /* 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; + } + } +} + +int bssl_qat_async_ctx_copy_result(const async_ctx *ctx, unsigned char *buffer, + unsigned long *size, unsigned long max_size) +{ + unsigned int bytes_len = 0; + CpaFlatBuffer *from; + + /* Decrease num_requests_in_flight by 1 to + * avoid high cpu load from polling thread + */ + QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, + qat_check_create_local_variables()); + + /* Change fds state from add to del */ + bssl_qat_async_reset_fds(ctx); + + if (ctx && + ctx->currjob && + ctx->currjob->waitctx && + ctx->currjob->waitctx->data && + ctx->currjob->status == ASYNC_JOB_COMPLETE) { + 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->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); + + 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); + return 1; /* Fail */ +} + +/* 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); +} + +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; + } + + privkey->pkey.rsa->meth->sign_raw = rsa_method->sign_raw; + privkey->pkey.rsa->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; + } + privkey->pkey.ec->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(); + } +} + +#endif /* QAT_BORINGSSL */ diff --git a/qat_bssl.h b/qat_bssl.h new file mode 100644 index 00000000..1344532a --- /dev/null +++ b/qat_bssl.h @@ -0,0 +1,523 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 (*tlv_destructor)(void *); + void (*free_op_done)(void *); + void *(*copy_op_done)(const void *, unsigned int, void (*)(void *, void *)); +}; +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 defination in BoringSSL + */ +/* Status of Async Jobs */ +#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) +#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 defination in BoringSSL + */ +# define ENGINE_DEFAULT (1) +#ifdef QAT_HW +# 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() +#endif + +# 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 bssl_engine_get_rsa_method() \ + ENGINE_get_RSA_method(ENGINE_QAT_PTR_GET()) +# 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() NULL +# 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() NULL +# 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) \ + *(sign_sig_pfunc) = bssl_default_ecdsa_sign +#ifdef ENABLE_QAT_HW_ECDSA +# define EC_KEY_METHOD_set_sign(meth, \ + sign_pfunc, sign_setup_pfunc, \ + sign_sig_pfunc) \ + bssl_ecdsa_meth_set_do_sign(meth, sign_pfunc) +#else +/* Dismiss compile warning when disabled hw ecdsa */ +# define EC_KEY_METHOD_set_sign(meth, \ + sign_pfunc, sign_setup_pfunc, \ + sign_sig_pfunc) \ + EC_KEY_NULL_METHOD(meth, sign_pfunc, sign_setup_pfunc, sign_sig_pfunc) +#endif +/* 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 inalid 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); + +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)); + +#endif diff --git a/qat_events.c b/qat_events.c index 1ec2b535..6178938b 100644 --- a/qat_events.c +++ b/qat_events.c @@ -183,6 +183,12 @@ int qat_clear_async_event_notification(volatile ASYNC_JOB *job) 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; diff --git a/qat_events.h b/qat_events.h index 467384c1..e58a2527 100644 --- a/qat_events.h +++ b/qat_events.h @@ -49,7 +49,7 @@ # include # include -# if OPENSSL_VERSION_NUMBER >= 0x10100000L +# if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined QAT_BORINGSSL # include # endif diff --git a/qat_evp.c b/qat_evp.c index 35aef329..f73065f7 100644 --- a/qat_evp.c +++ b/qat_evp.c @@ -50,7 +50,9 @@ #include #include #include "openssl/ossl_typ.h" +#ifndef QAT_BORINGSSL #include "openssl/kdf.h" +#endif #include "openssl/evp.h" #include "e_qat.h" @@ -59,11 +61,15 @@ #ifdef QAT_HW # include "qat_hw_rsa.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_sha3.h" # include "qat_hw_chachapoly.h" +# endif /* QAT_BORINGSSL */ #endif #ifdef QAT_SW_IPSEC @@ -72,10 +78,12 @@ #ifdef QAT_SW # include "qat_sw_rsa.h" +# ifndef QAT_BORINGSSL # include "qat_sw_ecx.h" # include "qat_sw_ec.h" # include "qat_sw_sm3.h" # include "crypto_mb/cpu_features.h" +# endif /* QAT_BORINGSSL */ #endif #ifdef QAT_HW_INTREE @@ -83,6 +91,7 @@ # define ENABLE_QAT_HW_CHACHAPOLY #endif +# ifndef QAT_BORINGSSL typedef struct _chained_info { const int nid; EVP_CIPHER *cipher; @@ -210,9 +219,11 @@ static int pkt_threshold_table_size = (sizeof(qat_pkt_threshold_table) / sizeof(qat_pkt_threshold_table[0])); # endif #endif +#endif /* QAT_BORINGSSL */ static EC_KEY_METHOD *qat_ec_method = NULL; static RSA_METHOD *qat_rsa_method = NULL; +#ifndef QAT_BORINGSSL static EVP_PKEY_METHOD *_hidden_x25519_pmeth = NULL; /* Have a store of the s/w EVP_PKEY_METHOD for software fallback purposes. */ @@ -806,21 +817,28 @@ int qat_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid) *cipher = NULL; return 0; } +#endif EC_KEY_METHOD *qat_get_EC_methods(void) { if (qat_ec_method != NULL && !qat_reload_algo) return qat_ec_method; +#ifndef QAT_BORINGSSL EC_KEY_METHOD *def_ec_meth = (EC_KEY_METHOD *)EC_KEY_get_default_method(); +#endif /* QAT_BORINGSSL */ PFUNC_SIGN sign_pfunc = NULL; +#if !(defined(QAT_BORINGSSL) && defined(ENABLE_QAT_HW_ECDSA)) 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) { @@ -832,7 +850,11 @@ EC_KEY_METHOD *qat_get_EC_methods(void) #ifdef ENABLE_QAT_HW_ECDSA if (qat_hw_offload && (qat_hw_algo_enable_mask & ALGO_ENABLE_MASK_ECDSA)) { EC_KEY_METHOD_set_sign(qat_ec_method, +#ifndef QAT_BORINGSSL qat_ecdsa_sign, +#else + qat_ecdsa_sign_bssl, +#endif /* QAT_BORINGSSL */ NULL, qat_ecdsa_do_sign); EC_KEY_METHOD_set_verify(qat_ec_method, @@ -846,6 +868,7 @@ EC_KEY_METHOD *qat_get_EC_methods(void) } #endif +#ifndef QAT_BORINGSSL #ifdef ENABLE_QAT_SW_ECDSA if (qat_sw_offload && !qat_hw_ecdsa_offload && (qat_sw_algo_enable_mask & ALGO_ENABLE_MASK_ECDSA) && @@ -871,6 +894,7 @@ EC_KEY_METHOD *qat_get_EC_methods(void) DEBUG("QAT SW ECDSA is disabled\n"); } #endif +#endif /* QAT_BORINGSSL */ if ((qat_hw_ecdsa_offload == 0) && (qat_sw_ecdsa_offload == 0)) { EC_KEY_METHOD_get_sign(def_ec_meth, @@ -890,6 +914,7 @@ EC_KEY_METHOD *qat_get_EC_methods(void) 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); @@ -926,6 +951,7 @@ EC_KEY_METHOD *qat_get_EC_methods(void) 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; } @@ -961,6 +987,10 @@ RSA_METHOD *qat_get_RSA_methods(void) #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); +#endif //QAT_BORINGSSL 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); @@ -1033,6 +1063,7 @@ void qat_free_RSA_methods(void) #ifdef QAT_HW # ifndef ENABLE_QAT_HW_SMALL_PKT_OFFLOAD +#ifndef QAT_BORINGSSL /****************************************************************************** * function: * qat_pkt_threshold_table_set_threshold(const char *cn, int threshold) @@ -1090,5 +1121,6 @@ int qat_pkt_threshold_table_get_threshold(int nid) WARN("nid %d not found in threshold table", nid); return 0; } +#endif /* QAT_BORINGSSL */ # endif #endif diff --git a/qat_evp.h b/qat_evp.h index df070243..865689f7 100644 --- a/qat_evp.h +++ b/qat_evp.h @@ -63,6 +63,13 @@ typedef int (*PFUNC_COMP_KEY)(unsigned char **, 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, @@ -71,6 +78,7 @@ typedef int (*PFUNC_SIGN)(int, const BIGNUM *, const BIGNUM *, EC_KEY *); +#endif /* QAT_BORINGSSL */ typedef int (*PFUNC_SIGN_SETUP)(EC_KEY *, BN_CTX *, @@ -94,6 +102,7 @@ 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; @@ -116,6 +125,7 @@ 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); # endif + int qat_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids, int nid); EVP_PKEY_METHOD *qat_prf_pmeth(void); @@ -138,6 +148,7 @@ const EVP_CIPHER *qat_create_gcm_cipher_meth(int nid, int keylen); 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); diff --git a/qat_fork.c b/qat_fork.c index 378b225c..633cf78d 100644 --- a/qat_fork.c +++ b/qat_fork.c @@ -110,6 +110,9 @@ void engine_init_child_at_fork_handler(void) 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; @@ -144,6 +147,7 @@ void engine_finish_before_fork_handler(void) qat_engine_finish_int(e, QAT_RETAIN_GLOBALS); ENGINE_free(e); + ENGINE_QAT_PTR_RESET(); #else QAT_PROV_CTX *ctx; diff --git a/qat_hw_callback.c b/qat_hw_callback.c index 679c9380..28dcf0ae 100644 --- a/qat_hw_callback.c +++ b/qat_hw_callback.c @@ -209,6 +209,12 @@ void qat_crypto_callbackFn(void *callbackTag, CpaStatus status, 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); } } diff --git a/qat_hw_callback.h b/qat_hw_callback.h index a368ba77..e5c50ff3 100644 --- a/qat_hw_callback.h +++ b/qat_hw_callback.h @@ -53,7 +53,7 @@ # include "cpa_types.h" # include "cpa_cy_sym.h" -# if OPENSSL_VERSION_NUMBER >= 0x10100000L +# if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined QAT_BORINGSSL # include # endif diff --git a/qat_hw_ec.c b/qat_hw_ec.c index 10d1c2cf..46676530 100644 --- a/qat_hw_ec.c +++ b/qat_hw_ec.c @@ -53,7 +53,12 @@ #include #include +#ifndef QAT_BORINGSSL #include +#else +#include +#include +#endif /* QAT_BORINGSSL */ #include #include #include @@ -62,6 +67,9 @@ #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" #include "e_qat.h" @@ -81,6 +89,9 @@ 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; @@ -842,6 +853,7 @@ int qat_ecdh_generate_key(EC_KEY *ecdh) #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, @@ -854,6 +866,102 @@ static void qat_ecdsaSignCallbackFn(void *pCallbackTag, CpaStatus status, 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; + + if (!bEcdsaSignStatus) { + WARN("ECDSA sign failed, status %d verifyResult %d\n", status, bEcdsaSignStatus); + goto err; + } + + op_done_t *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; + } + + 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_CHK_QMFREE_FLATBUFF(*pResultR); + OPENSSL_free(pResultR); + } + if (pResultS) { + QAT_CHK_QMFREE_FLATBUFF(*pResultS); + 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) +{ + if (out_buf) { + if (out_buf->pData) { + qaeCryptoMemFreeNonZero(out_buf->pData); + } + OPENSSL_free(out_buf); + } + + if (opData) { + QAT_CHK_QMFREE_FLATBUFF(opData->n); + QAT_CHK_QMFREE_FLATBUFF(opData->m); + QAT_CHK_QMFREE_FLATBUFF(opData->xg); + QAT_CHK_QMFREE_FLATBUFF(opData->yg); + QAT_CHK_QMFREE_FLATBUFF(opData->a); + QAT_CHK_QMFREE_FLATBUFF(opData->b); + QAT_CHK_QMFREE_FLATBUFF(opData->q); + QAT_CHK_CLNSE_QMFREE_NONZERO_FLATBUFF(opData->k); + QAT_CHK_CLNSE_QMFREE_NONZERO_FLATBUFF(opData->d); + OPENSSL_free(opData); + } +} +#endif /* QAT_BORINGSSL */ /* Callback to indicate QAT completion of ECDSA Verify */ static void qat_ecdsaVerifyCallbackFn(void *pCallbackTag, CpaStatus status, @@ -867,6 +975,7 @@ static void qat_ecdsaVerifyCallbackFn(void *pCallbackTag, CpaStatus status, } +#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) @@ -896,6 +1005,7 @@ int qat_ecdsa_sign(int type, const unsigned char *dgst, int dlen, ECDSA_SIG_free(s); return 1; } +#endif /* QAT_BORINGSSL */ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, @@ -916,6 +1026,10 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 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; @@ -1040,7 +1154,11 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 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; @@ -1164,6 +1282,27 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, } } +#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 = qaeCryptoMemAlloc(ECDSA_size(eckey), __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 *))ec_decrypt_op_buf_free); + } +#endif /* QAT_BORINGSSL */ + CRYPTO_QAT_LOG("AU - %s\n", __func__); do { if ((inst_num = get_next_inst_num(INSTANCE_TYPE_CRYPTO_ASYM)) @@ -1176,6 +1315,9 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 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); @@ -1184,12 +1326,29 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, CRYPTO_QAT_LOG("AU - %s\n", __func__); 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 */ if (status == CPA_STATUS_RETRY) { if (op_done.job == NULL) { usleep(ulPollInterval + @@ -1203,11 +1362,13 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, } } } 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 } } } @@ -1226,6 +1387,9 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 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); @@ -1240,11 +1404,25 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, &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, @@ -1268,7 +1446,17 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, 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()) { + icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); + ECDSA_INLINE_POLLING_USLEEP(); + } else { + sched_yield(); + } +#else sched_yield(); +#endif /* QAT_BORINGSSL */ } } while (!op_done.flag || @@ -1306,6 +1494,13 @@ ECDSA_SIG *qat_ecdsa_do_sign(const unsigned char *dgst, int dgst_len, ret = NULL; } +#ifdef QAT_BORINGSSL + if (ret_sig) { + QAT_CHK_QMFREE_FLATBUFF(*ret_sig); + OPENSSL_free(ret_sig); + } +#endif /* QAT_BORINGSSL */ + if (pResultR) { QAT_CHK_QMFREE_FLATBUFF(*pResultR); OPENSSL_free(pResultR); @@ -1513,7 +1708,11 @@ int qat_ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 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; @@ -1739,4 +1938,49 @@ int qat_ecdsa_do_verify(const unsigned char *dgst, int dgst_len, 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 */ diff --git a/qat_hw_ec.h b/qat_hw_ec.h index 7322e7e3..229b4adc 100644 --- a/qat_hw_ec.h +++ b/qat_hw_ec.h @@ -49,9 +49,15 @@ # 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); diff --git a/qat_hw_init.c b/qat_hw_init.c index 107585e6..3b165803 100644 --- a/qat_hw_init.c +++ b/qat_hw_init.c @@ -81,7 +81,7 @@ /* OpenSSL Includes */ #include -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined QAT_BORINGSSL #include #endif #include @@ -140,10 +140,12 @@ int qat_use_signals(void) 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(); } return qat_use_signals_no_engine_start(); @@ -228,6 +230,7 @@ int get_next_inst_num(int inst_type) } ENGINE_free(e); + ENGINE_QAT_PTR_RESET(); } tlv = qat_check_create_local_variables(); @@ -924,7 +927,9 @@ int qat_finish_int(ENGINE *e, int reset_globals) internal_efd = 0; qat_instance_handles = NULL; qat_keep_polling = 1; +#ifndef QAT_BORINGSSL qatPerformOpRetries = 0; +#endif DEBUG("Calling pthread_key_delete()\n"); pthread_key_delete(thread_local_variables); diff --git a/qat_hw_rsa.c b/qat_hw_rsa.c index 50f96456..c8083406 100644 --- a/qat_hw_rsa.c +++ b/qat_hw_rsa.c @@ -52,7 +52,7 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined QAT_BORINGSSL #include #endif #include @@ -130,11 +130,19 @@ static inline int qat_rsa_range_check(int plen) 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 @@ -180,6 +188,9 @@ static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, int job_ret = 0; int sync_mode_ret = 0; thread_local_variables_t *tlv = NULL; +#ifdef QAT_BORINGSSL + op_done_t *op_done_bssl = NULL; +#endif DEBUG("- Started\n"); @@ -222,6 +233,10 @@ static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, QAT_DEC_IN_FLIGHT_REQS(num_requests_in_flight, tlv); return sync_mode_ret; } +#ifdef QAT_BORINGSSL + op_done_bssl = (op_done_t*)op_done.job->copy_op_done(&op_done, + sizeof(op_done), (void (*)(void *, void *))rsa_decrypt_op_buf_free); +#endif /* * cpaCyRsaDecrypt() is the function called for RSA Sign in the API. * For that particular case the dec_op_data [IN] contains both the @@ -240,12 +255,22 @@ static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, } else { QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); } +#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; } DUMP_RSA_DECRYPT(qat_instance_handles[inst_num], &op_done, dec_op_data, output_buf); - sts = cpaCyRsaDecrypt(qat_instance_handles[inst_num], qat_rsaCallbackFn, &op_done, +#ifdef QAT_BORINGSSL + 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); if (sts == CPA_STATUS_RETRY) { if ((qat_wake_job(op_done.job, ASYNC_STATUS_EAGAIN) == 0) || @@ -254,6 +279,7 @@ static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, break; } } +#endif /* QAT_BORINGSSL */ } while (sts == CPA_STATUS_RETRY); @@ -268,8 +294,12 @@ static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, } else { QATerr(QAT_F_QAT_RSA_DECRYPT, ERR_R_INTERNAL_ERROR); } +#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; } @@ -281,11 +311,19 @@ static int qat_rsa_decrypt(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, &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 + op_done.job->free_op_done(op_done_bssl); +#endif return 0; } } } +#ifdef QAT_BORINGSSL + qat_cleanup_op_done(&op_done); + return -1; /* Async mode for BoringSSL */ +#endif /* QAT_BORINGSSL */ + if (qat_get_sw_fallback_enabled()) { CRYPTO_QAT_LOG("Submit success qat inst_num %d device_id %d - %s\n", inst_num, @@ -865,7 +903,7 @@ int qat_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, int rsa_len = 0; CpaCyRsaDecryptOpData *dec_op_data = NULL; CpaFlatBuffer *output_buffer = NULL; - int sts = 1, fallback = 0; + int sts = 1, fallback = 0, dec_ret = 0; #ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION unsigned char *ver_msg = NULL; const BIGNUM *n = NULL; @@ -913,8 +951,20 @@ int qat_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, goto exit; } - if (1 != qat_rsa_decrypt(dec_op_data, rsa_len, output_buffer, &fallback)) { - WARN("Failure in qat_rsa_decrypt fallback = %d\n", fallback); + dec_ret = qat_rsa_decrypt(dec_op_data, rsa_len, output_buffer, &fallback); + 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; @@ -970,6 +1020,7 @@ int qat_rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, exit: /* Free all the memory allocated in this function */ rsa_decrypt_op_buf_free(dec_op_data, output_buffer); + #ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION exit_lenstra: #endif @@ -1010,7 +1061,7 @@ int qat_rsa_priv_dec(int flen, const unsigned char *from, { int rsa_len = 0; int output_len = -1; - int sts = 1, fallback = 0; + int sts = 1, fallback = 0, dec_ret = 0; CpaCyRsaDecryptOpData *dec_op_data = NULL; CpaFlatBuffer *output_buffer = NULL; #ifndef DISABLE_QAT_HW_LENSTRA_PROTECTION @@ -1055,8 +1106,23 @@ int qat_rsa_priv_dec(int flen, const unsigned char *from, goto exit; } - if (1 != qat_rsa_decrypt(dec_op_data, rsa_len, output_buffer, &fallback)) { - WARN("Failure in qat_rsa_decrypt\n"); + dec_ret = qat_rsa_decrypt(dec_op_data, rsa_len, output_buffer, &fallback); + 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); @@ -1395,6 +1461,7 @@ int qat_rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, return 0; } +#ifndef QAT_BORINGSSL /****************************************************************************** * function: * qat_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) @@ -1449,5 +1516,86 @@ 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); + 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); + return 0; + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + 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; +} + +int RSA_private_encrypt_default(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding) +{ + void *temp = (void *)(rsa->meth->sign_raw); + rsa->meth->sign_raw = NULL; + int ret = RSA_private_encrypt(flen, from, to, rsa, padding); + rsa->meth->sign_raw = temp; + return ret; +} + +int RSA_private_decrypt_default(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding) +{ + void *temp = (void *)(rsa->meth->decrypt); + rsa->meth->decrypt = NULL; + int ret = RSA_private_decrypt(flen, from, to, rsa, padding); + rsa->meth->decrypt = temp; + return ret; +} + +#endif /* QAT_BORINGSSL */ #endif /* #ifndef ENABLE_QAT_HW_RSA */ diff --git a/qat_hw_rsa.h b/qat_hw_rsa.h index 7501f432..0463f2ab 100644 --- a/qat_hw_rsa.h +++ b/qat_hw_rsa.h @@ -59,9 +59,21 @@ 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); + +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 */ #endif #endif /* QAT_HW_RSA_H */ diff --git a/qat_hw_rsa_crt.c b/qat_hw_rsa_crt.c index d341d453..21040be7 100644 --- a/qat_hw_rsa_crt.c +++ b/qat_hw_rsa_crt.c @@ -473,6 +473,9 @@ int qat_rsa_decrypt_CRT(CpaCyRsaDecryptOpData * dec_op_data, int rsa_len, do { if(getEnableInlinePolling()) { icp_sal_CyPollInstance(qat_instance_handles[inst_num], 0); +#ifdef QAT_BORINGSSL + RSA_INLINE_POLLING_USLEEP(); +#endif /* QAT_BORINGSSL */ } else sched_yield(); diff --git a/test_bssl/main.c b/test_bssl/main.c new file mode 100644 index 00000000..c96943b2 --- /dev/null +++ b/test_bssl/main.c @@ -0,0 +1,212 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 = (char *)OPENSSL_zalloc(slen + 1))) { + 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 avaliable 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); +} diff --git a/test_bssl/test_bssl_ecdsa.c b/test_bssl/test_bssl_ecdsa.c new file mode 100644 index 00000000..6269bea9 --- /dev/null +++ b/test_bssl/test_bssl_ecdsa.c @@ -0,0 +1,229 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 unsigned int 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, &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, sig_len); + } + + /* Verify */ + signature = ECDSA_SIG_from_bytes(sig_data, 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; +} diff --git a/test_bssl/test_bssl_ecdsa.h b/test_bssl/test_bssl_ecdsa.h new file mode 100644 index 00000000..649aa390 --- /dev/null +++ b/test_bssl/test_bssl_ecdsa.h @@ -0,0 +1,53 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 */ diff --git a/test_bssl/test_bssl_rsa.c b/test_bssl/test_bssl_rsa.c new file mode 100644 index 00000000..cbdf3546 --- /dev/null +++ b/test_bssl/test_bssl_rsa.c @@ -0,0 +1,352 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 */ + } + + /* 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"); + 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"); + return 1; /* fail */ + } else { + T_DEBUG("RSA Decrypt(%s mode): OK\n", async_mode?"Async":"Sync"); + } + + + OPENSSL_free(enc_data); + return 0; +} diff --git a/test_bssl/test_bssl_rsa.h b/test_bssl/test_bssl_rsa.h new file mode 100644 index 00000000..07895cdc --- /dev/null +++ b/test_bssl/test_bssl_rsa.h @@ -0,0 +1,56 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 */ diff --git a/test_bssl/test_bssl_utils.c b/test_bssl/test_bssl_utils.c new file mode 100644 index 00000000..cac838ca --- /dev/null +++ b/test_bssl/test_bssl_utils.c @@ -0,0 +1,109 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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(""); +} diff --git a/test_bssl/test_bssl_utils.h b/test_bssl/test_bssl_utils.h new file mode 100644 index 00000000..b8ba12e1 --- /dev/null +++ b/test_bssl/test_bssl_utils.h @@ -0,0 +1,158 @@ +/* ==================================================================== + * + * + * BSD LICENSE + * + * Copyright(c) 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. + * + * + * ==================================================================== + */ + +/***************************************************************************** + * @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 */