[openwrt/openwrt] openssl: bump to 3.0.8
LEDE Commits
lede-commits at lists.infradead.org
Mon Feb 20 08:03:47 PST 2023
ansuel pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/7e7e76afca7877b97bc049d8f5a83a840a20a2af
commit 7e7e76afca7877b97bc049d8f5a83a840a20a2af
Author: Eneas U de Queiroz <cotequeiroz at gmail.com>
AuthorDate: Tue Feb 7 18:14:27 2023 -0300
openssl: bump to 3.0.8
This is a major update to the current LTS version, supported until
2026-09-07.
Changelog:
https://github.com/openssl/openssl/blob/openssl-3.0.8/CHANGES.md
Signed-off-by: Eneas U de Queiroz <cotequeiroz at gmail.com>
---
include/openssl-engine.mk | 4 +-
package/libs/openssl/Config.in | 40 +-
package/libs/openssl/Makefile | 20 +-
...erlasm-ppc-xlate.pl-add-linux64v2-flavour.patch | 55 -
.../patches/100-Configure-afalg-support.patch | 2 +-
.../patches/120-strip-cflags-from-binary.patch | 8 +-
.../openssl/patches/130-dont-build-fuzz-docs.patch | 20 +
.../patches/130-dont-build-tests-fuzz.patch | 29 -
.../patches/140-allow-prefer-chacha20.patch | 60 +-
.../patches/150-openssl.cnf-add-engines-conf.patch | 4 +-
...crypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch | 58 -
...0-eng_devcrypto-add-configuration-options.patch | 566 ----
...devcrypto-add-command-to-dump-driver-info.patch | 273 --
...crypto-make-the-dev-crypto-engine-dynamic.patch | 2718 --------------------
...ypto-default-to-not-use-digests-in-engine.patch | 41 -
...vcrypto-ignore-error-when-closing-session.patch | 24 -
16 files changed, 87 insertions(+), 3835 deletions(-)
diff --git a/include/openssl-engine.mk b/include/openssl-engine.mk
index d8baba482e..891d284f12 100644
--- a/include/openssl-engine.mk
+++ b/include/openssl-engine.mk
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
#
-# Copyright (C) 2022 Enéas Ulir de Queiroz
+# Copyright (C) 2022-2023 Enéas Ulir de Queiroz
-ENGINES_DIR=engines-1.1
+ENGINES_DIR=engines-3
define Package/openssl/engine/Default
SECTION:=libs
diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in
index bc2f0584b6..6a668fe4cd 100644
--- a/package/libs/openssl/Config.in
+++ b/package/libs/openssl/Config.in
@@ -8,11 +8,9 @@ config OPENSSL_OPTIMIZE_SPEED
prompt "Enable optimization for speed instead of size"
select OPENSSL_WITH_ASM
help
- Enabling this option increases code size (around 20%) and
- performance. The increase in performance and size depends on the
- target CPU. EC and AES seem to benefit the most, with EC speed
- increased by 20%-50% (mipsel & x86).
- AES-GCM is supposed to be 3x faster on x86. YMMV.
+ Enabling this option increases code size and performance.
+ The increase in performance and size depends on the
+ target CPU. EC and AES seem to benefit the most.
config OPENSSL_WITH_ASM
bool
@@ -22,19 +20,7 @@ config OPENSSL_WITH_ASM
help
Disabling this option will reduce code size and performance.
The increase in performance and size depends on the target
- CPU and on the algorithms being optimized. As of 1.1.0i*:
-
- Platform Pkg Inc. Algorithms where assembly is used - ~% Speed Increase
- aarch64 174K BN, aes, sha1, sha256, sha512, nist256, poly1305
- arm 152K BN, aes, sha1, sha256, sha512, nist256, poly1305
- i386 183K BN+147%, aes+300%, rc4+55%, sha1+160%, sha256+114%, sha512+270%, nist256+282%, poly1305+292%
- mipsel 1.5K BN+97%, aes+4%, sha1+94%, sha256+60%
- mips64 3.7K BN, aes, sha1, sha256, sha512, poly1305
- powerpc 20K BN, aes, sha1, sha256, sha512, poly1305
- x86_64 228K BN+220%, aes+173%, rc4+38%, sha1+40%, sha256+64%, sha512+31%, nist256+354%, poly1305+228%
-
- * Only most common algorithms shown. Your mileage may vary.
- BN (bignum) performance was measured using RSA sign/verify.
+ CPU and on the algorithms being optimized.
config OPENSSL_WITH_SSE2
bool
@@ -42,21 +28,17 @@ config OPENSSL_WITH_SSE2
prompt "Enable use of x86 SSE2 instructions"
depends on OPENSSL_WITH_ASM && i386
help
- Use of SSE2 instructions greatly increase performance (up to
- 3x faster) with a minimum (~0.2%, or 23KB) increase in package
- size, but it will bring no benefit if your hardware does not
- support them, such as Geode GX and LX. In this case you may
- save 23KB by saying yes here. AMD Geode NX, and Intel
- Pentium 4 and above support SSE2.
+ Use of SSE2 instructions greatly increase performance with a
+ minimum increase in package size, but it will bring no benefit
+ if your hardware does not support them, such as Geode GX and LX.
+ AMD Geode NX, and Intel Pentium 4 and above support SSE2.
config OPENSSL_WITH_DEPRECATED
bool
default y
- prompt "Include deprecated APIs (See help for a list of packages that need this)"
+ prompt "Include deprecated APIs"
help
- Since openssl 1.1.x is still new to openwrt, some packages
- requiring this option do not list it as a requirement yet:
- * freeswitch-stable, freeswitch, python, python3, squid.
+ This drops all deprecated API, including engine support.
config OPENSSL_NO_DEPRECATED
bool
@@ -84,7 +66,6 @@ config OPENSSL_WITH_TLS13
protocol;
* to increase performance by reducing the number of round-trips
when performing a full handshake.
- It increases package size by ~4KB.
config OPENSSL_WITH_DTLS
bool
@@ -233,6 +214,7 @@ comment "Engine/Hardware Support"
config OPENSSL_ENGINE
bool "Enable engine support"
+ select OPENSSL_WITH_DEPRECATED
default y
help
This enables alternative cryptography implementations,
diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile
index 4883ef82ea..7dc4df0982 100644
--- a/package/libs/openssl/Makefile
+++ b/package/libs/openssl/Makefile
@@ -8,14 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=openssl
-PKG_BASE:=1.1.1
-PKG_BUGFIX:=t
-PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX)
+PKG_VERSION:=3.0.8
PKG_RELEASE:=1
PKG_USE_MIPS16:=0
PKG_BUILD_PARALLEL:=1
+PKG_BASE:=$(subst $(space),.,$(wordlist 1,2,$(subst .,$(space),$(PKG_VERSION))))
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:= \
http://www.openssl.org/source/ \
@@ -25,9 +24,9 @@ PKG_SOURCE_URL:= \
ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/ \
ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/old/$(PKG_BASE)/
-PKG_HASH:=8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b
+PKG_HASH:=6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e
-PKG_LICENSE:=OpenSSL
+PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Eneas U de Queiroz <cotequeiroz at gmail.com>
PKG_CPE_ID:=cpe:/a:openssl:openssl
@@ -95,9 +94,10 @@ $(call Package/openssl/Default)
DEPENDS:=+OPENSSL_WITH_COMPRESSION:zlib \
+OPENSSL_ENGINE_BUILTIN_AFALG:kmod-crypto-user \
+OPENSSL_ENGINE_BUILTIN_DEVCRYPTO:kmod-cryptodev \
- +OPENSSL_ENGINE_BUILTIN_PADLOCK:kmod-crypto-hw-padlock
+ +OPENSSL_ENGINE_BUILTIN_PADLOCK:kmod-crypto-hw-padlock \
+ +(arm||armeb||mips||mipsel||ppc):libatomic
TITLE+= (libraries)
- ABI_VERSION:=1.1
+ ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION)))
MENU:=1
endef
@@ -186,7 +186,7 @@ and https://openwrt.org/docs/techref/hardware/cryptographic.hardware.accelerator
The engine_id is "padlock"
endef
-OPENSSL_OPTIONS:= shared
+OPENSSL_OPTIONS:= shared no-tests
ifndef CONFIG_OPENSSL_WITH_BLAKE2
OPENSSL_OPTIONS += no-blake2
@@ -272,7 +272,7 @@ ifdef CONFIG_OPENSSL_ENGINE
OPENSSL_OPTIONS += enable-devcryptoeng
endif
ifndef CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK
- OPENSSL_OPTIONS += no-hw-padlock
+ OPENSSL_OPTIONS += no-padlockeng
endif
else
ifdef CONFIG_PACKAGE_libopenssl-devcrypto
@@ -282,7 +282,7 @@ ifdef CONFIG_OPENSSL_ENGINE
OPENSSL_OPTIONS += no-afalgeng
endif
ifndef CONFIG_PACKAGE_libopenssl-padlock
- OPENSSL_OPTIONS += no-hw-padlock
+ OPENSSL_OPTIONS += no-padlockeng
endif
endif
else
diff --git a/package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch b/package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch
deleted file mode 100644
index 3da67e25fc..0000000000
--- a/package/libs/openssl/patches/001-crypto-perlasm-ppc-xlate.pl-add-linux64v2-flavour.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Andy Polyakov <appro at openssl.org>
-Date: Sun, 5 May 2019 18:25:50 +0200
-Subject: crypto/perlasm/ppc-xlate.pl: add linux64v2 flavour
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is a big endian ELFv2 configuration. ELFv2 was already being
-used for little endian, and big endian was traditionally ELFv1
-but there are practical configurations that use ELFv2 with big
-endian nowadays (Adélie Linux, Void Linux, possibly Gentoo, etc.)
-
-Reviewed-by: Paul Dale <paul.dale at oracle.com>
-Reviewed-by: Richard Levitte <levitte at openssl.org>
-(Merged from https://github.com/openssl/openssl/pull/8883)
-
---- a/crypto/perlasm/ppc-xlate.pl
-+++ b/crypto/perlasm/ppc-xlate.pl
-@@ -49,7 +49,7 @@ my $globl = sub {
- /osx/ && do { $name = "_$name";
- last;
- };
-- /linux.*(32|64le)/
-+ /linux.*(32|64(le|v2))/
- && do { $ret .= ".globl $name";
- if (!$$type) {
- $ret .= "\n.type $name,\@function";
-@@ -80,7 +80,7 @@ my $globl = sub {
- };
- my $text = sub {
- my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text";
-- $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/);
-+ $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64(le|v2)/);
- $ret;
- };
- my $machine = sub {
-@@ -186,7 +186,7 @@ my $vmr = sub {
-
- # Some ABIs specify vrsave, special-purpose register #256, as reserved
- # for system use.
--my $no_vrsave = ($flavour =~ /aix|linux64le/);
-+my $no_vrsave = ($flavour =~ /aix|linux64(le|v2)/);
- my $mtspr = sub {
- my ($f,$idx,$ra) = @_;
- if ($idx == 256 && $no_vrsave) {
-@@ -318,7 +318,7 @@ while($line=<>) {
- if ($label) {
- my $xlated = ($GLOBALS{$label} or $label);
- print "$xlated:";
-- if ($flavour =~ /linux.*64le/) {
-+ if ($flavour =~ /linux.*64(le|v2)/) {
- if ($TYPES{$label} =~ /function/) {
- printf "\n.localentry %s,0\n",$xlated;
- }
diff --git a/package/libs/openssl/patches/100-Configure-afalg-support.patch b/package/libs/openssl/patches/100-Configure-afalg-support.patch
index 746c50621f..e9cd7bf9c1 100644
--- a/package/libs/openssl/patches/100-Configure-afalg-support.patch
+++ b/package/libs/openssl/patches/100-Configure-afalg-support.patch
@@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
--- a/Configure
+++ b/Configure
-@@ -1548,7 +1548,9 @@ unless ($disabled{"crypto-mdebug-backtra
+@@ -1677,7 +1677,9 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-
unless ($disabled{afalgeng}) {
$config{afalgeng}="";
diff --git a/package/libs/openssl/patches/120-strip-cflags-from-binary.patch b/package/libs/openssl/patches/120-strip-cflags-from-binary.patch
index 90282706d1..e9f4fc131a 100644
--- a/package/libs/openssl/patches/120-strip-cflags-from-binary.patch
+++ b/package/libs/openssl/patches/120-strip-cflags-from-binary.patch
@@ -10,12 +10,12 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
--- a/crypto/build.info
+++ b/crypto/build.info
-@@ -10,7 +10,7 @@ EXTRA= ../ms/uplink-x86.pl ../ms/uplink
- ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl
+@@ -113,7 +113,7 @@ DEFINE[../libcrypto]=$UPLINKDEF
+ DEPEND[info.o]=buildinf.h
DEPEND[cversion.o]=buildinf.h
-GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)"
+GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(filter-out -I% -iremap% -fmacro-prefix-map% -ffile-prefix-map%,$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q))" "$(PLATFORM)"
- DEPEND[buildinf.h]=../configdata.pm
- GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME)
+ GENERATE[uplink-x86.S]=../ms/uplink-x86.pl
+ GENERATE[uplink-x86_64.s]=../ms/uplink-x86_64.pl
diff --git a/package/libs/openssl/patches/130-dont-build-fuzz-docs.patch b/package/libs/openssl/patches/130-dont-build-fuzz-docs.patch
new file mode 100644
index 0000000000..60c4663923
--- /dev/null
+++ b/package/libs/openssl/patches/130-dont-build-fuzz-docs.patch
@@ -0,0 +1,20 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Eneas U de Queiroz <cote2004-github at yahoo.com>
+Date: Thu, 27 Sep 2018 08:34:38 -0300
+Subject: Do not build tests and fuzz directories
+
+This shortens build time.
+
+Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
+
+--- a/build.info
++++ b/build.info
+@@ -1,7 +1,7 @@
+ # Note that some of these directories are filtered in Configure. Look for
+ # %skipdir there for further explanations.
+
+-SUBDIRS=crypto ssl apps util tools fuzz providers doc
++SUBDIRS=crypto ssl apps util tools providers
+ IF[{- !$disabled{tests} -}]
+ SUBDIRS=test
+ ENDIF
diff --git a/package/libs/openssl/patches/130-dont-build-tests-fuzz.patch b/package/libs/openssl/patches/130-dont-build-tests-fuzz.patch
deleted file mode 100644
index baf8bca9e1..0000000000
--- a/package/libs/openssl/patches/130-dont-build-tests-fuzz.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Thu, 27 Sep 2018 08:34:38 -0300
-Subject: Do not build tests and fuzz directories
-
-This shortens build time.
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
---- a/Configure
-+++ b/Configure
-@@ -318,7 +318,7 @@ my $auto_threads=1; # enable threads
- my $default_ranlib;
-
- # Top level directories to build
--$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
-+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "util", "tools" ];
- # crypto/ subdirectories to build
- $config{sdirs} = [
- "objects",
-@@ -330,7 +330,7 @@ $config{sdirs} = [
- "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store"
- ];
- # test/ subdirectories to build
--$config{tdirs} = [ "ossl_shim" ];
-+$config{tdirs} = [];
-
- # Known TLS and DTLS protocols
- my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
diff --git a/package/libs/openssl/patches/140-allow-prefer-chacha20.patch b/package/libs/openssl/patches/140-allow-prefer-chacha20.patch
index 99afd9acf8..43fd92e388 100644
--- a/package/libs/openssl/patches/140-allow-prefer-chacha20.patch
+++ b/package/libs/openssl/patches/140-allow-prefer-chacha20.patch
@@ -14,30 +14,9 @@ when the client has it on top of its ciphersuite preference.
Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
---- a/include/openssl/ssl.h
-+++ b/include/openssl/ssl.h
-@@ -173,9 +173,15 @@ extern "C" {
- # define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL"
- /* This is the default set of TLSv1.3 ciphersuites */
- # if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
--# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
-- "TLS_CHACHA20_POLY1305_SHA256:" \
-- "TLS_AES_128_GCM_SHA256"
-+# ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
-+# define TLS_DEFAULT_CIPHERSUITES "TLS_CHACHA20_POLY1305_SHA256:" \
-+ "TLS_AES_256_GCM_SHA384:" \
-+ "TLS_AES_128_GCM_SHA256"
-+# else
-+# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
-+ "TLS_CHACHA20_POLY1305_SHA256:" \
-+ "TLS_AES_128_GCM_SHA256"
-+# endif
- # else
- # define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
- "TLS_AES_128_GCM_SHA256"
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
-@@ -1465,11 +1465,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+@@ -1505,11 +1505,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,
&tail);
@@ -67,7 +46,7 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
/*
* ...and generally, our preferred cipher is AES.
-@@ -1525,7 +1543,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+@@ -1564,7 +1582,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
* Within each group, ciphers remain sorted by strength and previous
* preference, i.e.,
* 1) ECDHE > DHE
@@ -76,3 +55,38 @@ Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
* 3) AES > rest
* 4) TLS 1.2 > legacy
*
+@@ -2235,7 +2253,13 @@ const char *OSSL_default_cipher_list(voi
+ */
+ const char *OSSL_default_ciphersuites(void)
+ {
++#ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
++ return "TLS_CHACHA20_POLY1305_SHA256:"
++ "TLS_AES_256_GCM_SHA384:"
++ "TLS_AES_128_GCM_SHA256";
++#else
+ return "TLS_AES_256_GCM_SHA384:"
+ "TLS_CHACHA20_POLY1305_SHA256:"
+ "TLS_AES_128_GCM_SHA256";
++#endif
+ }
+--- a/include/openssl/ssl.h.in
++++ b/include/openssl/ssl.h.in
+@@ -195,9 +195,15 @@ extern "C" {
+ * DEPRECATED IN 3.0.0, in favor of OSSL_default_ciphersuites()
+ * Update both macro and function simultaneously
+ */
+-# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
+- "TLS_CHACHA20_POLY1305_SHA256:" \
+- "TLS_AES_128_GCM_SHA256"
++# ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
++# define TLS_DEFAULT_CIPHERSUITES "TLS_CHACHA20_POLY1305_SHA256:" \
++ "TLS_AES_256_GCM_SHA384:" \
++ "TLS_AES_128_GCM_SHA256"
++# else
++# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \
++ "TLS_CHACHA20_POLY1305_SHA256:" \
++ "TLS_AES_128_GCM_SHA256"
++# endif
+ # endif
+ /*
+ * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
diff --git a/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch b/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch
index fa92fbe2ab..b1ec0cae71 100644
--- a/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch
+++ b/package/libs/openssl/patches/150-openssl.cnf-add-engines-conf.patch
@@ -10,7 +10,7 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz at gmail.com>
--- a/apps/openssl.cnf
+++ b/apps/openssl.cnf
-@@ -22,6 +22,16 @@ oid_section = new_oids
+@@ -30,6 +30,16 @@ oid_section = new_oids
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
@@ -25,5 +25,5 @@ Signed-off-by: Eneas U de Queiroz <cotequeiroz at gmail.com>
+.include /etc/ssl/engines.cnf.d
+
[ new_oids ]
-
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+ # Add a simple OID like this:
diff --git a/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch b/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch
deleted file mode 100644
index ed8204c339..0000000000
--- a/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Mon, 5 Nov 2018 15:54:17 -0200
-Subject: eng_devcrypto: save ioctl if EVP_MD_..FLAG_ONESHOT
-
-Since each ioctl causes a context switch, slowing things down, if
-EVP_MD_CTX_FLAG_ONESHOT is set, then:
- - call the ioctl in digest_update, saving the result; and
- - just copy the result in digest_final, instead of using another ioctl.
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
-Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
-Reviewed-by: Richard Levitte <levitte at openssl.org>
-(Merged from https://github.com/openssl/openssl/pull/7585)
-
---- a/crypto/engine/eng_devcrypto.c
-+++ b/crypto/engine/eng_devcrypto.c
-@@ -461,6 +461,7 @@ struct digest_ctx {
- struct session_op sess;
- /* This signals that the init function was called, not that it succeeded. */
- int init_called;
-+ unsigned char digest_res[HASH_MAX_LEN];
- };
-
- static const struct digest_data_st {
-@@ -564,12 +565,15 @@ static int digest_update(EVP_MD_CTX *ctx
- if (digest_ctx == NULL)
- return 0;
-
-- if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-+ if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
-+ return 1;
-+ } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
-+ return 1;
- }
-
-- return 1;
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
- }
-
- static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
-@@ -579,7 +583,10 @@ static int digest_final(EVP_MD_CTX *ctx,
-
- if (md == NULL || digest_ctx == NULL)
- return 0;
-- if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
-+
-+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-+ memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
-+ } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
- SYSerr(SYS_F_IOCTL, errno);
- return 0;
- }
diff --git a/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch b/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch
deleted file mode 100644
index bad7a37256..0000000000
--- a/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch
+++ /dev/null
@@ -1,566 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Sat, 3 Nov 2018 15:41:10 -0300
-Subject: eng_devcrypto: add configuration options
-
-USE_SOFTDRIVERS: whether to use software (not accelerated) drivers
-CIPHERS: list of ciphers to enable
-DIGESTS: list of digests to enable
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
-Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
-Reviewed-by: Richard Levitte <levitte at openssl.org>
-(Merged from https://github.com/openssl/openssl/pull/7585)
-
---- a/crypto/engine/eng_devcrypto.c
-+++ b/crypto/engine/eng_devcrypto.c
-@@ -16,6 +16,7 @@
- #include <unistd.h>
- #include <assert.h>
-
-+#include <openssl/conf.h>
- #include <openssl/evp.h>
- #include <openssl/err.h>
- #include <openssl/engine.h>
-@@ -36,6 +37,30 @@
- * saner... why re-open /dev/crypto for every session?
- */
- static int cfd;
-+#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
-+#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
-+#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
-+
-+#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE
-+static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
-+
-+/*
-+ * cipher/digest status & acceleration definitions
-+ * Make sure the defaults are set to 0
-+ */
-+struct driver_info_st {
-+ enum devcrypto_status_t {
-+ DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */
-+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
-+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
-+ } status;
-+
-+ enum devcrypto_accelerated_t {
-+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
-+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
-+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
-+ } accelerated;
-+};
-
- static int clean_devcrypto_session(struct session_op *sess) {
- if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
-@@ -119,13 +144,22 @@ static const struct cipher_data_st {
- #endif
- };
-
--static size_t get_cipher_data_index(int nid)
-+static size_t find_cipher_data_index(int nid)
- {
- size_t i;
-
- for (i = 0; i < OSSL_NELEM(cipher_data); i++)
- if (nid == cipher_data[i].nid)
- return i;
-+ return (size_t)-1;
-+}
-+
-+static size_t get_cipher_data_index(int nid)
-+{
-+ size_t i = find_cipher_data_index(nid);
-+
-+ if (i != (size_t)-1)
-+ return i;
-
- /*
- * Code further down must make sure that only NIDs in the table above
-@@ -333,19 +367,40 @@ static int cipher_cleanup(EVP_CIPHER_CTX
- }
-
- /*
-- * Keep a table of known nids and associated methods.
-+ * Keep tables of known nids, associated methods, selected ciphers, and driver
-+ * info.
- * Note that known_cipher_nids[] isn't necessarily indexed the same way as
-- * cipher_data[] above, which known_cipher_methods[] is.
-+ * cipher_data[] above, which the other tables are.
- */
- static int known_cipher_nids[OSSL_NELEM(cipher_data)];
- static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
- static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
-+static int selected_ciphers[OSSL_NELEM(cipher_data)];
-+static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
-+
-+
-+static int devcrypto_test_cipher(size_t cipher_data_index)
-+{
-+ return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
-+ && selected_ciphers[cipher_data_index] == 1
-+ && (cipher_driver_info[cipher_data_index].accelerated
-+ == DEVCRYPTO_ACCELERATED
-+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
-+ || (cipher_driver_info[cipher_data_index].accelerated
-+ != DEVCRYPTO_NOT_ACCELERATED
-+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
-+}
-
- static void prepare_cipher_methods(void)
- {
- size_t i;
- struct session_op sess;
- unsigned long cipher_mode;
-+#ifdef CIOCGSESSINFO
-+ struct session_info_op siop;
-+#endif
-+
-+ memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
-
- memset(&sess, 0, sizeof(sess));
- sess.key = (void *)"01234567890123456789012345678901234567890123456789";
-@@ -353,15 +408,16 @@ static void prepare_cipher_methods(void)
- for (i = 0, known_cipher_nids_amount = 0;
- i < OSSL_NELEM(cipher_data); i++) {
-
-+ selected_ciphers[i] = 1;
- /*
-- * Check that the algo is really availably by trying to open and close
-- * a session.
-+ * Check that the cipher is usable
- */
- sess.cipher = cipher_data[i].devcryptoid;
- sess.keylen = cipher_data[i].keylen;
-- if (ioctl(cfd, CIOCGSESSION, &sess) < 0
-- || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
-+ if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- continue;
-+ }
-
- cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
-
-@@ -387,15 +443,41 @@ static void prepare_cipher_methods(void)
- cipher_cleanup)
- || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
- sizeof(struct cipher_ctx))) {
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- EVP_CIPHER_meth_free(known_cipher_methods[i]);
- known_cipher_methods[i] = NULL;
- } else {
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
-+#ifdef CIOCGSESSINFO
-+ siop.ses = sess.ses;
-+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-+ else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+ else
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+#endif /* CIOCGSESSINFO */
-+ }
-+ ioctl(cfd, CIOCFSESSION, &sess.ses);
-+ if (devcrypto_test_cipher(i)) {
- known_cipher_nids[known_cipher_nids_amount++] =
- cipher_data[i].nid;
- }
- }
- }
-
-+static void rebuild_known_cipher_nids(ENGINE *e)
-+{
-+ size_t i;
-+
-+ for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
-+ if (devcrypto_test_cipher(i))
-+ known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
-+ }
-+ ENGINE_unregister_ciphers(e);
-+ ENGINE_register_ciphers(e);
-+}
-+
- static const EVP_CIPHER *get_cipher_method(int nid)
- {
- size_t i = get_cipher_data_index(nid);
-@@ -438,6 +520,36 @@ static int devcrypto_ciphers(ENGINE *e,
- return *cipher != NULL;
- }
-
-+static void devcrypto_select_all_ciphers(int *cipher_list)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++)
-+ cipher_list[i] = 1;
-+}
-+
-+static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
-+{
-+ int *cipher_list = (int *)usr;
-+ char *name;
-+ const EVP_CIPHER *EVP;
-+ size_t i;
-+
-+ if (len == 0)
-+ return 1;
-+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
-+ return 0;
-+ EVP = EVP_get_cipherbyname(name);
-+ if (EVP == NULL)
-+ fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
-+ else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
-+ cipher_list[i] = 1;
-+ else
-+ fprintf(stderr, "devcrypto: cipher %s not available\n", name);
-+ OPENSSL_free(name);
-+ return 1;
-+}
-+
- /*
- * We only support digests if the cryptodev implementation supports multiple
- * data updates and session copying. Otherwise, we would be forced to maintain
-@@ -493,13 +605,22 @@ static const struct digest_data_st {
- #endif
- };
-
--static size_t get_digest_data_index(int nid)
-+static size_t find_digest_data_index(int nid)
- {
- size_t i;
-
- for (i = 0; i < OSSL_NELEM(digest_data); i++)
- if (nid == digest_data[i].nid)
- return i;
-+ return (size_t)-1;
-+}
-+
-+static size_t get_digest_data_index(int nid)
-+{
-+ size_t i = find_digest_data_index(nid);
-+
-+ if (i != (size_t)-1)
-+ return i;
-
- /*
- * Code further down must make sure that only NIDs in the table above
-@@ -516,8 +637,8 @@ static const struct digest_data_st *get_
- }
-
- /*
-- * Following are the four necessary functions to map OpenSSL functionality
-- * with cryptodev.
-+ * Following are the five necessary functions to map OpenSSL functionality
-+ * with cryptodev: init, update, final, cleanup, and copy.
- */
-
- static int digest_init(EVP_MD_CTX *ctx)
-@@ -630,52 +751,94 @@ static int digest_cleanup(EVP_MD_CTX *ct
- return clean_devcrypto_session(&digest_ctx->sess);
- }
-
--static int devcrypto_test_digest(size_t digest_data_index)
--{
-- struct session_op sess1, sess2;
-- struct cphash_op cphash;
-- int ret=0;
--
-- memset(&sess1, 0, sizeof(sess1));
-- memset(&sess2, 0, sizeof(sess2));
-- sess1.mac = digest_data[digest_data_index].devcryptoid;
-- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0)
-- return 0;
-- /* Make sure the driver is capable of hash state copy */
-- sess2.mac = sess1.mac;
-- if (ioctl(cfd, CIOCGSESSION, &sess2) >= 0) {
-- cphash.src_ses = sess1.ses;
-- cphash.dst_ses = sess2.ses;
-- if (ioctl(cfd, CIOCCPHASH, &cphash) >= 0)
-- ret = 1;
-- ioctl(cfd, CIOCFSESSION, &sess2.ses);
-- }
-- ioctl(cfd, CIOCFSESSION, &sess1.ses);
-- return ret;
--}
--
- /*
-- * Keep a table of known nids and associated methods.
-+ * Keep tables of known nids, associated methods, selected digests, and
-+ * driver info.
- * Note that known_digest_nids[] isn't necessarily indexed the same way as
-- * digest_data[] above, which known_digest_methods[] is.
-+ * digest_data[] above, which the other tables are.
- */
- static int known_digest_nids[OSSL_NELEM(digest_data)];
- static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
- static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
-+static int selected_digests[OSSL_NELEM(digest_data)];
-+static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
-+
-+static int devcrypto_test_digest(size_t digest_data_index)
-+{
-+ return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
-+ && selected_digests[digest_data_index] == 1
-+ && (digest_driver_info[digest_data_index].accelerated
-+ == DEVCRYPTO_ACCELERATED
-+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
-+ || (digest_driver_info[digest_data_index].accelerated
-+ != DEVCRYPTO_NOT_ACCELERATED
-+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
-+}
-+
-+static void rebuild_known_digest_nids(ENGINE *e)
-+{
-+ size_t i;
-+
-+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
-+ if (devcrypto_test_digest(i))
-+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
-+ }
-+ ENGINE_unregister_digests(e);
-+ ENGINE_register_digests(e);
-+}
-
- static void prepare_digest_methods(void)
- {
- size_t i;
-+ struct session_op sess1, sess2;
-+#ifdef CIOCGSESSINFO
-+ struct session_info_op siop;
-+#endif
-+ struct cphash_op cphash;
-+
-+ memset(&digest_driver_info, 0, sizeof(digest_driver_info));
-+
-+ memset(&sess1, 0, sizeof(sess1));
-+ memset(&sess2, 0, sizeof(sess2));
-
- for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
- i++) {
-
-+ selected_digests[i] = 1;
-+
- /*
-- * Check that the algo is usable
-+ * Check that the digest is usable
- */
-- if (!devcrypto_test_digest(i))
-- continue;
-+ sess1.mac = digest_data[i].devcryptoid;
-+ sess2.ses = 0;
-+ if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ goto finish;
-+ }
-
-+#ifdef CIOCGSESSINFO
-+ /* gather hardware acceleration info from the driver */
-+ siop.ses = sess1.ses;
-+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
-+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-+ else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
-+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+ else
-+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+#endif
-+
-+ /* digest must be capable of hash state copy */
-+ sess2.mac = sess1.mac;
-+ if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ goto finish;
-+ }
-+ cphash.src_ses = sess1.ses;
-+ cphash.dst_ses = sess2.ses;
-+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ goto finish;
-+ }
- if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
- NID_undef)) == NULL
- || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i],
-@@ -689,11 +852,18 @@ static void prepare_digest_methods(void)
- || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
- || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
- sizeof(struct digest_ctx))) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
- EVP_MD_meth_free(known_digest_methods[i]);
- known_digest_methods[i] = NULL;
-- } else {
-- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
-+ goto finish;
- }
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
-+finish:
-+ ioctl(cfd, CIOCFSESSION, &sess1.ses);
-+ if (sess2.ses != 0)
-+ ioctl(cfd, CIOCFSESSION, &sess2.ses);
-+ if (devcrypto_test_digest(i))
-+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
- }
- }
-
-@@ -739,7 +909,153 @@ static int devcrypto_digests(ENGINE *e,
- return *digest != NULL;
- }
-
-+static void devcrypto_select_all_digests(int *digest_list)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++)
-+ digest_list[i] = 1;
-+}
-+
-+static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
-+{
-+ int *digest_list = (int *)usr;
-+ char *name;
-+ const EVP_MD *EVP;
-+ size_t i;
-+
-+ if (len == 0)
-+ return 1;
-+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
-+ return 0;
-+ EVP = EVP_get_digestbyname(name);
-+ if (EVP == NULL)
-+ fprintf(stderr, "devcrypto: unknown digest %s\n", name);
-+ else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
-+ digest_list[i] = 1;
-+ else
-+ fprintf(stderr, "devcrypto: digest %s not available\n", name);
-+ OPENSSL_free(name);
-+ return 1;
-+}
-+
-+#endif
-+
-+/******************************************************************************
-+ *
-+ * CONTROL COMMANDS
-+ *
-+ *****/
-+
-+#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
-+#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
-+#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
-+#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
-+
-+/* Helper macros for CPP string composition */
-+#ifndef OPENSSL_MSTR
-+# define OPENSSL_MSTR_HELPER(x) #x
-+# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x)
-+#endif
-+
-+static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
-+#ifdef CIOCGSESSINFO
-+ {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
-+ "USE_SOFTDRIVERS",
-+ "specifies whether to use software (not accelerated) drivers ("
-+ OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
-+ OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
-+ OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
-+ "=use if acceleration can't be determined) [default="
-+ OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]",
-+ ENGINE_CMD_FLAG_NUMERIC},
-+#endif
-+
-+ {DEVCRYPTO_CMD_CIPHERS,
-+ "CIPHERS",
-+ "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
-+ ENGINE_CMD_FLAG_STRING},
-+
-+#ifdef IMPLEMENT_DIGEST
-+ {DEVCRYPTO_CMD_DIGESTS,
-+ "DIGESTS",
-+ "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
-+ ENGINE_CMD_FLAG_STRING},
-+#endif
-+
-+ {0, NULL, NULL, 0}
-+};
-+
-+static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
-+{
-+ int *new_list;
-+ switch (cmd) {
-+#ifdef CIOCGSESSINFO
-+ case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
-+ switch (i) {
-+ case DEVCRYPTO_REQUIRE_ACCELERATED:
-+ case DEVCRYPTO_USE_SOFTWARE:
-+ case DEVCRYPTO_REJECT_SOFTWARE:
-+ break;
-+ default:
-+ fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
-+ return 0;
-+ }
-+ if (use_softdrivers == i)
-+ return 1;
-+ use_softdrivers = i;
-+#ifdef IMPLEMENT_DIGEST
-+ rebuild_known_digest_nids(e);
- #endif
-+ rebuild_known_cipher_nids(e);
-+ return 1;
-+#endif /* CIOCGSESSINFO */
-+
-+ case DEVCRYPTO_CMD_CIPHERS:
-+ if (p == NULL)
-+ return 1;
-+ if (strcasecmp((const char *)p, "ALL") == 0) {
-+ devcrypto_select_all_ciphers(selected_ciphers);
-+ } else if (strcasecmp((const char*)p, "NONE") == 0) {
-+ memset(selected_ciphers, 0, sizeof(selected_ciphers));
-+ } else {
-+ new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
-+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
-+ OPENSSL_free(new_list);
-+ return 0;
-+ }
-+ memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
-+ OPENSSL_free(new_list);
-+ }
-+ rebuild_known_cipher_nids(e);
-+ return 1;
-+
-+#ifdef IMPLEMENT_DIGEST
-+ case DEVCRYPTO_CMD_DIGESTS:
-+ if (p == NULL)
-+ return 1;
-+ if (strcasecmp((const char *)p, "ALL") == 0) {
-+ devcrypto_select_all_digests(selected_digests);
-+ } else if (strcasecmp((const char*)p, "NONE") == 0) {
-+ memset(selected_digests, 0, sizeof(selected_digests));
-+ } else {
-+ new_list=OPENSSL_zalloc(sizeof(selected_digests));
-+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
-+ OPENSSL_free(new_list);
-+ return 0;
-+ }
-+ memcpy(selected_digests, new_list, sizeof(selected_digests));
-+ OPENSSL_free(new_list);
-+ }
-+ rebuild_known_digest_nids(e);
-+ return 1;
-+#endif /* IMPLEMENT_DIGEST */
-+
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-
- /******************************************************************************
- *
-@@ -806,6 +1122,8 @@ void engine_load_devcrypto_int()
-
- if (!ENGINE_set_id(e, "devcrypto")
- || !ENGINE_set_name(e, "/dev/crypto engine")
-+ || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
-+ || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)
-
- /*
- * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
diff --git a/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch b/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch
deleted file mode 100644
index eee71c6c62..0000000000
--- a/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Tue, 6 Nov 2018 22:54:07 -0200
-Subject: eng_devcrypto: add command to dump driver info
-
-This is useful to determine the kernel driver running each algorithm.
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
-Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
-Reviewed-by: Richard Levitte <levitte at openssl.org>
-(Merged from https://github.com/openssl/openssl/pull/7585)
-
---- a/crypto/engine/eng_devcrypto.c
-+++ b/crypto/engine/eng_devcrypto.c
-@@ -50,16 +50,20 @@ static int use_softdrivers = DEVCRYPTO_D
- */
- struct driver_info_st {
- enum devcrypto_status_t {
-- DEVCRYPTO_STATUS_UNUSABLE = -1, /* session open failed */
-- DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
-- DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
-+ DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
-+ DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
-+ DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
-+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
-+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
- } status;
-
- enum devcrypto_accelerated_t {
-- DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
-- DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
-- DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
-+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
-+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
-+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
- } accelerated;
-+
-+ char *driver_name;
- };
-
- static int clean_devcrypto_session(struct session_op *sess) {
-@@ -415,7 +419,7 @@ static void prepare_cipher_methods(void)
- sess.cipher = cipher_data[i].devcryptoid;
- sess.keylen = cipher_data[i].keylen;
- if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
-- cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
- continue;
- }
-
-@@ -443,19 +447,24 @@ static void prepare_cipher_methods(void)
- cipher_cleanup)
- || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
- sizeof(struct cipher_ctx))) {
-- cipher_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
- EVP_CIPHER_meth_free(known_cipher_methods[i]);
- known_cipher_methods[i] = NULL;
- } else {
- cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
- #ifdef CIOCGSESSINFO
- siop.ses = sess.ses;
-- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
-+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-- else if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
-- cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-- else
-- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+ } else {
-+ cipher_driver_info[i].driver_name =
-+ OPENSSL_strndup(siop.cipher_info.cra_driver_name,
-+ CRYPTODEV_MAX_ALG_NAME);
-+ if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+ else
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+ }
- #endif /* CIOCGSESSINFO */
- }
- ioctl(cfd, CIOCFSESSION, &sess.ses);
-@@ -505,8 +514,11 @@ static void destroy_all_cipher_methods(v
- {
- size_t i;
-
-- for (i = 0; i < OSSL_NELEM(cipher_data); i++)
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
- destroy_cipher_method(cipher_data[i].nid);
-+ OPENSSL_free(cipher_driver_info[i].driver_name);
-+ cipher_driver_info[i].driver_name = NULL;
-+ }
- }
-
- static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-@@ -550,6 +562,40 @@ static int cryptodev_select_cipher_cb(co
- return 1;
- }
-
-+static void dump_cipher_info(void)
-+{
-+ size_t i;
-+ const char *name;
-+
-+ fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
-+ " engine:\n");
-+#ifndef CIOCGSESSINFO
-+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
-+#endif
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
-+ name = OBJ_nid2sn(cipher_data[i].nid);
-+ fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
-+ name ? name : "unknown", cipher_data[i].nid,
-+ cipher_data[i].devcryptoid);
-+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
-+ fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
-+ continue;
-+ }
-+ fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
-+ cipher_driver_info[i].driver_name : "unknown");
-+ if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
-+ fprintf(stderr, "(hw accelerated)");
-+ else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
-+ fprintf(stderr, "(software)");
-+ else
-+ fprintf(stderr, "(acceleration status unknown)");
-+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
-+ fprintf (stderr, ". Cipher setup failed");
-+ fprintf(stderr, "\n");
-+ }
-+ fprintf(stderr, "\n");
-+}
-+
- /*
- * We only support digests if the cryptodev implementation supports multiple
- * data updates and session copying. Otherwise, we would be forced to maintain
-@@ -812,31 +858,36 @@ static void prepare_digest_methods(void)
- sess1.mac = digest_data[i].devcryptoid;
- sess2.ses = 0;
- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
- goto finish;
- }
-
- #ifdef CIOCGSESSINFO
- /* gather hardware acceleration info from the driver */
- siop.ses = sess1.ses;
-- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0)
-+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-- else if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
-- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-- else
-- digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+ } else {
-+ digest_driver_info[i].driver_name =
-+ OPENSSL_strndup(siop.hash_info.cra_driver_name,
-+ CRYPTODEV_MAX_ALG_NAME);
-+ if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
-+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+ else
-+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+ }
- #endif
-
- /* digest must be capable of hash state copy */
- sess2.mac = sess1.mac;
- if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
- goto finish;
- }
- cphash.src_ses = sess1.ses;
- cphash.dst_ses = sess2.ses;
- if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
- goto finish;
- }
- if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
-@@ -852,7 +903,7 @@ static void prepare_digest_methods(void)
- || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
- || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
- sizeof(struct digest_ctx))) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_UNUSABLE;
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
- EVP_MD_meth_free(known_digest_methods[i]);
- known_digest_methods[i] = NULL;
- goto finish;
-@@ -894,8 +945,11 @@ static void destroy_all_digest_methods(v
- {
- size_t i;
-
-- for (i = 0; i < OSSL_NELEM(digest_data); i++)
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++) {
- destroy_digest_method(digest_data[i].nid);
-+ OPENSSL_free(digest_driver_info[i].driver_name);
-+ digest_driver_info[i].driver_name = NULL;
-+ }
- }
-
- static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
-@@ -939,6 +993,43 @@ static int cryptodev_select_digest_cb(co
- return 1;
- }
-
-+static void dump_digest_info(void)
-+{
-+ size_t i;
-+ const char *name;
-+
-+ fprintf (stderr, "Information about digests supported by the /dev/crypto"
-+ " engine:\n");
-+#ifndef CIOCGSESSINFO
-+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
-+#endif
-+
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++) {
-+ name = OBJ_nid2sn(digest_data[i].nid);
-+ fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
-+ name ? name : "unknown", digest_data[i].nid,
-+ digest_data[i].devcryptoid,
-+ digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
-+ if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
-+ fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
-+ continue;
-+ }
-+ if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
-+ fprintf(stderr, " (hw accelerated)");
-+ else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
-+ fprintf(stderr, " (software)");
-+ else
-+ fprintf(stderr, " (acceleration status unknown)");
-+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
-+ fprintf (stderr, ". Cipher setup failed\n");
-+ else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
-+ fprintf(stderr, ", CIOCCPHASH failed\n");
-+ else
-+ fprintf(stderr, ", CIOCCPHASH capable\n");
-+ }
-+ fprintf(stderr, "\n");
-+}
-+
- #endif
-
- /******************************************************************************
-@@ -983,6 +1074,11 @@ static const ENGINE_CMD_DEFN devcrypto_c
- ENGINE_CMD_FLAG_STRING},
- #endif
-
-+ {DEVCRYPTO_CMD_DUMP_INFO,
-+ "DUMP_INFO",
-+ "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
-+ ENGINE_CMD_FLAG_NO_INPUT},
-+
- {0, NULL, NULL, 0}
- };
-
-@@ -1051,6 +1147,13 @@ static int devcrypto_ctrl(ENGINE *e, int
- return 1;
- #endif /* IMPLEMENT_DIGEST */
-
-+ case DEVCRYPTO_CMD_DUMP_INFO:
-+ dump_cipher_info();
-+#ifdef IMPLEMENT_DIGEST
-+ dump_digest_info();
-+#endif
-+ return 1;
-+
- default:
- break;
- }
diff --git a/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch b/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch
deleted file mode 100644
index 00c74972ab..0000000000
--- a/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch
+++ /dev/null
@@ -1,2718 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Tue, 6 Nov 2018 10:57:03 -0200
-Subject: e_devcrypto: make the /dev/crypto engine dynamic
-
-Engine has been moved from crypto/engine/eng_devcrypto.c to
-engines/e_devcrypto.c.
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
---- a/crypto/engine/build.info
-+++ b/crypto/engine/build.info
-@@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\
- tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
- eng_openssl.c eng_cnf.c eng_dyn.c \
- eng_rdrand.c
--IF[{- !$disabled{devcryptoeng} -}]
-- SOURCE[../../libcrypto]=eng_devcrypto.c
--ENDIF
---- a/crypto/init.c
-+++ b/crypto/init.c
-@@ -328,18 +328,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_
- engine_load_openssl_int();
- return 1;
- }
--# ifndef OPENSSL_NO_DEVCRYPTOENG
--static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
--DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
--{
--# ifdef OPENSSL_INIT_DEBUG
-- fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
-- "engine_load_devcrypto_int()\n");
--# endif
-- engine_load_devcrypto_int();
-- return 1;
--}
--# endif
-
- # ifndef OPENSSL_NO_RDRAND
- static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
-@@ -364,6 +352,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_
- return 1;
- }
- # ifndef OPENSSL_NO_STATIC_ENGINE
-+# ifndef OPENSSL_NO_DEVCRYPTOENG
-+static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
-+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
-+{
-+# ifdef OPENSSL_INIT_DEBUG
-+ fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
-+ "engine_load_devcrypto_int()\n");
-+# endif
-+ engine_load_devcrypto_int();
-+ return 1;
-+}
-+# endif
- # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
- static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
- DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
-@@ -704,11 +704,6 @@ int OPENSSL_init_crypto(uint64_t opts, c
- if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
- && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
- return 0;
--# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
-- if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
-- && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
-- return 0;
--# endif
- # ifndef OPENSSL_NO_RDRAND
- if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
- && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
-@@ -718,6 +713,11 @@ int OPENSSL_init_crypto(uint64_t opts, c
- && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
- return 0;
- # ifndef OPENSSL_NO_STATIC_ENGINE
-+# ifndef OPENSSL_NO_DEVCRYPTOENG
-+ if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
-+ && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
-+ return 0;
-+# endif
- # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
- if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
- && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
---- a/engines/build.info
-+++ b/engines/build.info
-@@ -11,6 +11,9 @@ IF[{- !$disabled{"engine"} -}]
- IF[{- !$disabled{afalgeng} -}]
- SOURCE[../libcrypto]=e_afalg.c
- ENDIF
-+ IF[{- !$disabled{"devcryptoeng"} -}]
-+ SOURCE[../libcrypto]=e_devcrypto.c
-+ ENDIF
- ELSE
- IF[{- !$disabled{hw} && !$disabled{'hw-padlock'} -}]
- ENGINES=padlock
-@@ -30,6 +33,12 @@ IF[{- !$disabled{"engine"} -}]
- DEPEND[afalg]=../libcrypto
- INCLUDE[afalg]= ../include
- ENDIF
-+ IF[{- !$disabled{"devcryptoeng"} -}]
-+ ENGINES=devcrypto
-+ SOURCE[devcrypto]=e_devcrypto.c
-+ DEPEND[devcrypto]=../libcrypto
-+ INCLUDE[devcrypto]=../include
-+ ENDIF
-
- ENGINES_NO_INST=ossltest dasync
- SOURCE[dasync]=e_dasync.c
---- a/crypto/engine/eng_devcrypto.c
-+++ /dev/null
-@@ -1,1277 +0,0 @@
--/*
-- * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
-- *
-- * Licensed under the OpenSSL license (the "License"). You may not use
-- * this file except in compliance with the License. You can obtain a copy
-- * in the file LICENSE in the source distribution or at
-- * https://www.openssl.org/source/license.html
-- */
--
--#include "e_os.h"
--#include <string.h>
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <fcntl.h>
--#include <sys/ioctl.h>
--#include <unistd.h>
--#include <assert.h>
--
--#include <openssl/conf.h>
--#include <openssl/evp.h>
--#include <openssl/err.h>
--#include <openssl/engine.h>
--#include <openssl/objects.h>
--#include <crypto/cryptodev.h>
--
--#include "crypto/engine.h"
--
--/* #define ENGINE_DEVCRYPTO_DEBUG */
--
--#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX
--# define CHECK_BSD_STYLE_MACROS
--#endif
--
--/*
-- * ONE global file descriptor for all sessions. This allows operations
-- * such as digest session data copying (see digest_copy()), but is also
-- * saner... why re-open /dev/crypto for every session?
-- */
--static int cfd;
--#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
--#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
--#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
--
--#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE
--static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
--
--/*
-- * cipher/digest status & acceleration definitions
-- * Make sure the defaults are set to 0
-- */
--struct driver_info_st {
-- enum devcrypto_status_t {
-- DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
-- DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
-- DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
-- DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
-- DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
-- } status;
--
-- enum devcrypto_accelerated_t {
-- DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
-- DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
-- DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
-- } accelerated;
--
-- char *driver_name;
--};
--
--static int clean_devcrypto_session(struct session_op *sess) {
-- if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
-- memset(sess, 0, sizeof(struct session_op));
-- return 1;
--}
--
--/******************************************************************************
-- *
-- * Ciphers
-- *
-- * Because they all do the same basic operation, we have only one set of
-- * method functions for them all to share, and a mapping table between
-- * NIDs and cryptodev IDs, with all the necessary size data.
-- *
-- *****/
--
--struct cipher_ctx {
-- struct session_op sess;
-- int op; /* COP_ENCRYPT or COP_DECRYPT */
-- unsigned long mode; /* EVP_CIPH_*_MODE */
--
-- /* to handle ctr mode being a stream cipher */
-- unsigned char partial[EVP_MAX_BLOCK_LENGTH];
-- unsigned int blocksize, num;
--};
--
--static const struct cipher_data_st {
-- int nid;
-- int blocksize;
-- int keylen;
-- int ivlen;
-- int flags;
-- int devcryptoid;
--} cipher_data[] = {
--#ifndef OPENSSL_NO_DES
-- { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
-- { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
--#endif
--#ifndef OPENSSL_NO_BF
-- { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
--#endif
--#ifndef OPENSSL_NO_CAST
-- { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
--#endif
-- { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
-- { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
-- { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
--#ifndef OPENSSL_NO_RC4
-- { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 },
--#endif
--#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
-- { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
-- { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
-- { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
--#endif
--#if 0 /* Not yet supported */
-- { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
-- { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
--#endif
--#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
-- { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
-- { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
-- { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
--#endif
--#if 0 /* Not yet supported */
-- { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
-- { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
-- { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
--#endif
--#ifndef OPENSSL_NO_CAMELLIA
-- { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
-- CRYPTO_CAMELLIA_CBC },
-- { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
-- CRYPTO_CAMELLIA_CBC },
-- { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
-- CRYPTO_CAMELLIA_CBC },
--#endif
--};
--
--static size_t find_cipher_data_index(int nid)
--{
-- size_t i;
--
-- for (i = 0; i < OSSL_NELEM(cipher_data); i++)
-- if (nid == cipher_data[i].nid)
-- return i;
-- return (size_t)-1;
--}
--
--static size_t get_cipher_data_index(int nid)
--{
-- size_t i = find_cipher_data_index(nid);
--
-- if (i != (size_t)-1)
-- return i;
--
-- /*
-- * Code further down must make sure that only NIDs in the table above
-- * are used. If any other NID reaches this function, there's a grave
-- * coding error further down.
-- */
-- assert("Code that never should be reached" == NULL);
-- return -1;
--}
--
--static const struct cipher_data_st *get_cipher_data(int nid)
--{
-- return &cipher_data[get_cipher_data_index(nid)];
--}
--
--/*
-- * Following are the three necessary functions to map OpenSSL functionality
-- * with cryptodev.
-- */
--
--static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-- const unsigned char *iv, int enc)
--{
-- struct cipher_ctx *cipher_ctx =
-- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-- const struct cipher_data_st *cipher_d =
-- get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
--
-- /* cleanup a previous session */
-- if (cipher_ctx->sess.ses != 0 &&
-- clean_devcrypto_session(&cipher_ctx->sess) == 0)
-- return 0;
--
-- cipher_ctx->sess.cipher = cipher_d->devcryptoid;
-- cipher_ctx->sess.keylen = cipher_d->keylen;
-- cipher_ctx->sess.key = (void *)key;
-- cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
-- cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
-- cipher_ctx->blocksize = cipher_d->blocksize;
-- if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
--
-- return 1;
--}
--
--static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-- const unsigned char *in, size_t inl)
--{
-- struct cipher_ctx *cipher_ctx =
-- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-- struct crypt_op cryp;
-- unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
--#if !defined(COP_FLAG_WRITE_IV)
-- unsigned char saved_iv[EVP_MAX_IV_LENGTH];
-- const unsigned char *ivptr;
-- size_t nblocks, ivlen;
--#endif
--
-- memset(&cryp, 0, sizeof(cryp));
-- cryp.ses = cipher_ctx->sess.ses;
-- cryp.len = inl;
-- cryp.src = (void *)in;
-- cryp.dst = (void *)out;
-- cryp.iv = (void *)iv;
-- cryp.op = cipher_ctx->op;
--#if !defined(COP_FLAG_WRITE_IV)
-- cryp.flags = 0;
--
-- ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-- if (ivlen > 0)
-- switch (cipher_ctx->mode) {
-- case EVP_CIPH_CBC_MODE:
-- assert(inl >= ivlen);
-- if (!EVP_CIPHER_CTX_encrypting(ctx)) {
-- ivptr = in + inl - ivlen;
-- memcpy(saved_iv, ivptr, ivlen);
-- }
-- break;
--
-- case EVP_CIPH_CTR_MODE:
-- break;
--
-- default: /* should not happen */
-- return 0;
-- }
--#else
-- cryp.flags = COP_FLAG_WRITE_IV;
--#endif
--
-- if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
--
--#if !defined(COP_FLAG_WRITE_IV)
-- if (ivlen > 0)
-- switch (cipher_ctx->mode) {
-- case EVP_CIPH_CBC_MODE:
-- assert(inl >= ivlen);
-- if (EVP_CIPHER_CTX_encrypting(ctx))
-- ivptr = out + inl - ivlen;
-- else
-- ivptr = saved_iv;
--
-- memcpy(iv, ivptr, ivlen);
-- break;
--
-- case EVP_CIPH_CTR_MODE:
-- nblocks = (inl + cipher_ctx->blocksize - 1)
-- / cipher_ctx->blocksize;
-- do {
-- ivlen--;
-- nblocks += iv[ivlen];
-- iv[ivlen] = (uint8_t) nblocks;
-- nblocks >>= 8;
-- } while (ivlen);
-- break;
--
-- default: /* should not happen */
-- return 0;
-- }
--#endif
--
-- return 1;
--}
--
--static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-- const unsigned char *in, size_t inl)
--{
-- struct cipher_ctx *cipher_ctx =
-- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-- size_t nblocks, len;
--
-- /* initial partial block */
-- while (cipher_ctx->num && inl) {
-- (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num];
-- --inl;
-- cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize;
-- }
--
-- /* full blocks */
-- if (inl > (unsigned int) cipher_ctx->blocksize) {
-- nblocks = inl/cipher_ctx->blocksize;
-- len = nblocks * cipher_ctx->blocksize;
-- if (cipher_do_cipher(ctx, out, in, len) < 1)
-- return 0;
-- inl -= len;
-- out += len;
-- in += len;
-- }
--
-- /* final partial block */
-- if (inl) {
-- memset(cipher_ctx->partial, 0, cipher_ctx->blocksize);
-- if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial,
-- cipher_ctx->blocksize) < 1)
-- return 0;
-- while (inl--) {
-- out[cipher_ctx->num] = in[cipher_ctx->num]
-- ^ cipher_ctx->partial[cipher_ctx->num];
-- cipher_ctx->num++;
-- }
-- }
--
-- return 1;
--}
--
--static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
--{
-- struct cipher_ctx *cipher_ctx =
-- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-- EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
-- struct cipher_ctx *to_cipher_ctx;
--
-- switch (type) {
-- case EVP_CTRL_COPY:
-- if (cipher_ctx == NULL)
-- return 1;
-- /* when copying the context, a new session needs to be initialized */
-- to_cipher_ctx =
-- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx);
-- memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess));
-- return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
-- (cipher_ctx->op == COP_ENCRYPT));
--
-- case EVP_CTRL_INIT:
-- memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
-- return 1;
--
-- default:
-- break;
-- }
--
-- return -1;
--}
--
--static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
--{
-- struct cipher_ctx *cipher_ctx =
-- (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
--
-- return clean_devcrypto_session(&cipher_ctx->sess);
--}
--
--/*
-- * Keep tables of known nids, associated methods, selected ciphers, and driver
-- * info.
-- * Note that known_cipher_nids[] isn't necessarily indexed the same way as
-- * cipher_data[] above, which the other tables are.
-- */
--static int known_cipher_nids[OSSL_NELEM(cipher_data)];
--static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
--static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
--static int selected_ciphers[OSSL_NELEM(cipher_data)];
--static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
--
--
--static int devcrypto_test_cipher(size_t cipher_data_index)
--{
-- return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
-- && selected_ciphers[cipher_data_index] == 1
-- && (cipher_driver_info[cipher_data_index].accelerated
-- == DEVCRYPTO_ACCELERATED
-- || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
-- || (cipher_driver_info[cipher_data_index].accelerated
-- != DEVCRYPTO_NOT_ACCELERATED
-- && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
--}
--
--static void prepare_cipher_methods(void)
--{
-- size_t i;
-- struct session_op sess;
-- unsigned long cipher_mode;
--#ifdef CIOCGSESSINFO
-- struct session_info_op siop;
--#endif
--
-- memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
--
-- memset(&sess, 0, sizeof(sess));
-- sess.key = (void *)"01234567890123456789012345678901234567890123456789";
--
-- for (i = 0, known_cipher_nids_amount = 0;
-- i < OSSL_NELEM(cipher_data); i++) {
--
-- selected_ciphers[i] = 1;
-- /*
-- * Check that the cipher is usable
-- */
-- sess.cipher = cipher_data[i].devcryptoid;
-- sess.keylen = cipher_data[i].keylen;
-- if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
-- cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
-- continue;
-- }
--
-- cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
--
-- if ((known_cipher_methods[i] =
-- EVP_CIPHER_meth_new(cipher_data[i].nid,
-- cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
-- cipher_data[i].blocksize,
-- cipher_data[i].keylen)) == NULL
-- || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
-- cipher_data[i].ivlen)
-- || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
-- cipher_data[i].flags
-- | EVP_CIPH_CUSTOM_COPY
-- | EVP_CIPH_CTRL_INIT
-- | EVP_CIPH_FLAG_DEFAULT_ASN1)
-- || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
-- || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
-- cipher_mode == EVP_CIPH_CTR_MODE ?
-- ctr_do_cipher :
-- cipher_do_cipher)
-- || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
-- || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
-- cipher_cleanup)
-- || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
-- sizeof(struct cipher_ctx))) {
-- cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
-- EVP_CIPHER_meth_free(known_cipher_methods[i]);
-- known_cipher_methods[i] = NULL;
-- } else {
-- cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
--#ifdef CIOCGSESSINFO
-- siop.ses = sess.ses;
-- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
-- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-- } else {
-- cipher_driver_info[i].driver_name =
-- OPENSSL_strndup(siop.cipher_info.cra_driver_name,
-- CRYPTODEV_MAX_ALG_NAME);
-- if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
-- cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-- else
-- cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-- }
--#endif /* CIOCGSESSINFO */
-- }
-- ioctl(cfd, CIOCFSESSION, &sess.ses);
-- if (devcrypto_test_cipher(i)) {
-- known_cipher_nids[known_cipher_nids_amount++] =
-- cipher_data[i].nid;
-- }
-- }
--}
--
--static void rebuild_known_cipher_nids(ENGINE *e)
--{
-- size_t i;
--
-- for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
-- if (devcrypto_test_cipher(i))
-- known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
-- }
-- ENGINE_unregister_ciphers(e);
-- ENGINE_register_ciphers(e);
--}
--
--static const EVP_CIPHER *get_cipher_method(int nid)
--{
-- size_t i = get_cipher_data_index(nid);
--
-- if (i == (size_t)-1)
-- return NULL;
-- return known_cipher_methods[i];
--}
--
--static int get_cipher_nids(const int **nids)
--{
-- *nids = known_cipher_nids;
-- return known_cipher_nids_amount;
--}
--
--static void destroy_cipher_method(int nid)
--{
-- size_t i = get_cipher_data_index(nid);
--
-- EVP_CIPHER_meth_free(known_cipher_methods[i]);
-- known_cipher_methods[i] = NULL;
--}
--
--static void destroy_all_cipher_methods(void)
--{
-- size_t i;
--
-- for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
-- destroy_cipher_method(cipher_data[i].nid);
-- OPENSSL_free(cipher_driver_info[i].driver_name);
-- cipher_driver_info[i].driver_name = NULL;
-- }
--}
--
--static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-- const int **nids, int nid)
--{
-- if (cipher == NULL)
-- return get_cipher_nids(nids);
--
-- *cipher = get_cipher_method(nid);
--
-- return *cipher != NULL;
--}
--
--static void devcrypto_select_all_ciphers(int *cipher_list)
--{
-- size_t i;
--
-- for (i = 0; i < OSSL_NELEM(cipher_data); i++)
-- cipher_list[i] = 1;
--}
--
--static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
--{
-- int *cipher_list = (int *)usr;
-- char *name;
-- const EVP_CIPHER *EVP;
-- size_t i;
--
-- if (len == 0)
-- return 1;
-- if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
-- return 0;
-- EVP = EVP_get_cipherbyname(name);
-- if (EVP == NULL)
-- fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
-- else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
-- cipher_list[i] = 1;
-- else
-- fprintf(stderr, "devcrypto: cipher %s not available\n", name);
-- OPENSSL_free(name);
-- return 1;
--}
--
--static void dump_cipher_info(void)
--{
-- size_t i;
-- const char *name;
--
-- fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
-- " engine:\n");
--#ifndef CIOCGSESSINFO
-- fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
--#endif
-- for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
-- name = OBJ_nid2sn(cipher_data[i].nid);
-- fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
-- name ? name : "unknown", cipher_data[i].nid,
-- cipher_data[i].devcryptoid);
-- if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
-- fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
-- continue;
-- }
-- fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
-- cipher_driver_info[i].driver_name : "unknown");
-- if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
-- fprintf(stderr, "(hw accelerated)");
-- else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
-- fprintf(stderr, "(software)");
-- else
-- fprintf(stderr, "(acceleration status unknown)");
-- if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
-- fprintf (stderr, ". Cipher setup failed");
-- fprintf(stderr, "\n");
-- }
-- fprintf(stderr, "\n");
--}
--
--/*
-- * We only support digests if the cryptodev implementation supports multiple
-- * data updates and session copying. Otherwise, we would be forced to maintain
-- * a cache, which is perilous if there's a lot of data coming in (if someone
-- * wants to checksum an OpenSSL tarball, for example).
-- */
--#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
--#define IMPLEMENT_DIGEST
--
--/******************************************************************************
-- *
-- * Digests
-- *
-- * Because they all do the same basic operation, we have only one set of
-- * method functions for them all to share, and a mapping table between
-- * NIDs and cryptodev IDs, with all the necessary size data.
-- *
-- *****/
--
--struct digest_ctx {
-- struct session_op sess;
-- /* This signals that the init function was called, not that it succeeded. */
-- int init_called;
-- unsigned char digest_res[HASH_MAX_LEN];
--};
--
--static const struct digest_data_st {
-- int nid;
-- int blocksize;
-- int digestlen;
-- int devcryptoid;
--} digest_data[] = {
--#ifndef OPENSSL_NO_MD5
-- { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 },
--#endif
-- { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 },
--#ifndef OPENSSL_NO_RMD160
--# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160)
-- { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 },
--# endif
--#endif
--#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224)
-- { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 },
--#endif
--#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256)
-- { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 },
--#endif
--#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384)
-- { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 },
--#endif
--#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512)
-- { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 },
--#endif
--};
--
--static size_t find_digest_data_index(int nid)
--{
-- size_t i;
--
-- for (i = 0; i < OSSL_NELEM(digest_data); i++)
-- if (nid == digest_data[i].nid)
-- return i;
-- return (size_t)-1;
--}
--
--static size_t get_digest_data_index(int nid)
--{
-- size_t i = find_digest_data_index(nid);
--
-- if (i != (size_t)-1)
-- return i;
--
-- /*
-- * Code further down must make sure that only NIDs in the table above
-- * are used. If any other NID reaches this function, there's a grave
-- * coding error further down.
-- */
-- assert("Code that never should be reached" == NULL);
-- return -1;
--}
--
--static const struct digest_data_st *get_digest_data(int nid)
--{
-- return &digest_data[get_digest_data_index(nid)];
--}
--
--/*
-- * Following are the five necessary functions to map OpenSSL functionality
-- * with cryptodev: init, update, final, cleanup, and copy.
-- */
--
--static int digest_init(EVP_MD_CTX *ctx)
--{
-- struct digest_ctx *digest_ctx =
-- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
-- const struct digest_data_st *digest_d =
-- get_digest_data(EVP_MD_CTX_type(ctx));
--
-- digest_ctx->init_called = 1;
--
-- memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
-- digest_ctx->sess.mac = digest_d->devcryptoid;
-- if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
--
-- return 1;
--}
--
--static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen,
-- void *res, unsigned int flags)
--{
-- struct crypt_op cryp;
--
-- memset(&cryp, 0, sizeof(cryp));
-- cryp.ses = ctx->sess.ses;
-- cryp.len = srclen;
-- cryp.src = (void *)src;
-- cryp.dst = NULL;
-- cryp.mac = res;
-- cryp.flags = flags;
-- return ioctl(cfd, CIOCCRYPT, &cryp);
--}
--
--static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
--{
-- struct digest_ctx *digest_ctx =
-- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
--
-- if (count == 0)
-- return 1;
--
-- if (digest_ctx == NULL)
-- return 0;
--
-- if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-- if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
-- return 1;
-- } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
-- return 1;
-- }
--
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
--}
--
--static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
--{
-- struct digest_ctx *digest_ctx =
-- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
--
-- if (md == NULL || digest_ctx == NULL)
-- return 0;
--
-- if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-- memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
-- } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
--
-- return 1;
--}
--
--static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
--{
-- struct digest_ctx *digest_from =
-- (struct digest_ctx *)EVP_MD_CTX_md_data(from);
-- struct digest_ctx *digest_to =
-- (struct digest_ctx *)EVP_MD_CTX_md_data(to);
-- struct cphash_op cphash;
--
-- if (digest_from == NULL || digest_from->init_called != 1)
-- return 1;
--
-- if (!digest_init(to)) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
--
-- cphash.src_ses = digest_from->sess.ses;
-- cphash.dst_ses = digest_to->sess.ses;
-- if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
-- SYSerr(SYS_F_IOCTL, errno);
-- return 0;
-- }
-- return 1;
--}
--
--static int digest_cleanup(EVP_MD_CTX *ctx)
--{
-- struct digest_ctx *digest_ctx =
-- (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
--
-- if (digest_ctx == NULL)
-- return 1;
--
-- return clean_devcrypto_session(&digest_ctx->sess);
--}
--
--/*
-- * Keep tables of known nids, associated methods, selected digests, and
-- * driver info.
-- * Note that known_digest_nids[] isn't necessarily indexed the same way as
-- * digest_data[] above, which the other tables are.
-- */
--static int known_digest_nids[OSSL_NELEM(digest_data)];
--static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
--static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
--static int selected_digests[OSSL_NELEM(digest_data)];
--static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
--
--static int devcrypto_test_digest(size_t digest_data_index)
--{
-- return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
-- && selected_digests[digest_data_index] == 1
-- && (digest_driver_info[digest_data_index].accelerated
-- == DEVCRYPTO_ACCELERATED
-- || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
-- || (digest_driver_info[digest_data_index].accelerated
-- != DEVCRYPTO_NOT_ACCELERATED
-- && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
--}
--
--static void rebuild_known_digest_nids(ENGINE *e)
--{
-- size_t i;
--
-- for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
-- if (devcrypto_test_digest(i))
-- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
-- }
-- ENGINE_unregister_digests(e);
-- ENGINE_register_digests(e);
--}
--
--static void prepare_digest_methods(void)
--{
-- size_t i;
-- struct session_op sess1, sess2;
--#ifdef CIOCGSESSINFO
-- struct session_info_op siop;
--#endif
-- struct cphash_op cphash;
--
-- memset(&digest_driver_info, 0, sizeof(digest_driver_info));
--
-- memset(&sess1, 0, sizeof(sess1));
-- memset(&sess2, 0, sizeof(sess2));
--
-- for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
-- i++) {
--
-- selected_digests[i] = 1;
--
-- /*
-- * Check that the digest is usable
-- */
-- sess1.mac = digest_data[i].devcryptoid;
-- sess2.ses = 0;
-- if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
-- goto finish;
-- }
--
--#ifdef CIOCGSESSINFO
-- /* gather hardware acceleration info from the driver */
-- siop.ses = sess1.ses;
-- if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
-- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-- } else {
-- digest_driver_info[i].driver_name =
-- OPENSSL_strndup(siop.hash_info.cra_driver_name,
-- CRYPTODEV_MAX_ALG_NAME);
-- if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
-- digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-- else
-- digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-- }
--#endif
--
-- /* digest must be capable of hash state copy */
-- sess2.mac = sess1.mac;
-- if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
-- goto finish;
-- }
-- cphash.src_ses = sess1.ses;
-- cphash.dst_ses = sess2.ses;
-- if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
-- goto finish;
-- }
-- if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
-- NID_undef)) == NULL
-- || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i],
-- digest_data[i].blocksize)
-- || !EVP_MD_meth_set_result_size(known_digest_methods[i],
-- digest_data[i].digestlen)
-- || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init)
-- || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update)
-- || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final)
-- || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy)
-- || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
-- || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
-- sizeof(struct digest_ctx))) {
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
-- EVP_MD_meth_free(known_digest_methods[i]);
-- known_digest_methods[i] = NULL;
-- goto finish;
-- }
-- digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
--finish:
-- ioctl(cfd, CIOCFSESSION, &sess1.ses);
-- if (sess2.ses != 0)
-- ioctl(cfd, CIOCFSESSION, &sess2.ses);
-- if (devcrypto_test_digest(i))
-- known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
-- }
--}
--
--static const EVP_MD *get_digest_method(int nid)
--{
-- size_t i = get_digest_data_index(nid);
--
-- if (i == (size_t)-1)
-- return NULL;
-- return known_digest_methods[i];
--}
--
--static int get_digest_nids(const int **nids)
--{
-- *nids = known_digest_nids;
-- return known_digest_nids_amount;
--}
--
--static void destroy_digest_method(int nid)
--{
-- size_t i = get_digest_data_index(nid);
--
-- EVP_MD_meth_free(known_digest_methods[i]);
-- known_digest_methods[i] = NULL;
--}
--
--static void destroy_all_digest_methods(void)
--{
-- size_t i;
--
-- for (i = 0; i < OSSL_NELEM(digest_data); i++) {
-- destroy_digest_method(digest_data[i].nid);
-- OPENSSL_free(digest_driver_info[i].driver_name);
-- digest_driver_info[i].driver_name = NULL;
-- }
--}
--
--static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
-- const int **nids, int nid)
--{
-- if (digest == NULL)
-- return get_digest_nids(nids);
--
-- *digest = get_digest_method(nid);
--
-- return *digest != NULL;
--}
--
--static void devcrypto_select_all_digests(int *digest_list)
--{
-- size_t i;
--
-- for (i = 0; i < OSSL_NELEM(digest_data); i++)
-- digest_list[i] = 1;
--}
--
--static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
--{
-- int *digest_list = (int *)usr;
-- char *name;
-- const EVP_MD *EVP;
-- size_t i;
--
-- if (len == 0)
-- return 1;
-- if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
-- return 0;
-- EVP = EVP_get_digestbyname(name);
-- if (EVP == NULL)
-- fprintf(stderr, "devcrypto: unknown digest %s\n", name);
-- else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
-- digest_list[i] = 1;
-- else
-- fprintf(stderr, "devcrypto: digest %s not available\n", name);
-- OPENSSL_free(name);
-- return 1;
--}
--
--static void dump_digest_info(void)
--{
-- size_t i;
-- const char *name;
--
-- fprintf (stderr, "Information about digests supported by the /dev/crypto"
-- " engine:\n");
--#ifndef CIOCGSESSINFO
-- fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
--#endif
--
-- for (i = 0; i < OSSL_NELEM(digest_data); i++) {
-- name = OBJ_nid2sn(digest_data[i].nid);
-- fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
-- name ? name : "unknown", digest_data[i].nid,
-- digest_data[i].devcryptoid,
-- digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
-- if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
-- fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
-- continue;
-- }
-- if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
-- fprintf(stderr, " (hw accelerated)");
-- else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
-- fprintf(stderr, " (software)");
-- else
-- fprintf(stderr, " (acceleration status unknown)");
-- if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
-- fprintf (stderr, ". Cipher setup failed\n");
-- else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
-- fprintf(stderr, ", CIOCCPHASH failed\n");
-- else
-- fprintf(stderr, ", CIOCCPHASH capable\n");
-- }
-- fprintf(stderr, "\n");
--}
--
--#endif
--
--/******************************************************************************
-- *
-- * CONTROL COMMANDS
-- *
-- *****/
--
--#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
--#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
--#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
--#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
--
--/* Helper macros for CPP string composition */
--#ifndef OPENSSL_MSTR
--# define OPENSSL_MSTR_HELPER(x) #x
--# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x)
--#endif
--
--static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
--#ifdef CIOCGSESSINFO
-- {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
-- "USE_SOFTDRIVERS",
-- "specifies whether to use software (not accelerated) drivers ("
-- OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
-- OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
-- OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
-- "=use if acceleration can't be determined) [default="
-- OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]",
-- ENGINE_CMD_FLAG_NUMERIC},
--#endif
--
-- {DEVCRYPTO_CMD_CIPHERS,
-- "CIPHERS",
-- "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
-- ENGINE_CMD_FLAG_STRING},
--
--#ifdef IMPLEMENT_DIGEST
-- {DEVCRYPTO_CMD_DIGESTS,
-- "DIGESTS",
-- "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
-- ENGINE_CMD_FLAG_STRING},
--#endif
--
-- {DEVCRYPTO_CMD_DUMP_INFO,
-- "DUMP_INFO",
-- "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
-- ENGINE_CMD_FLAG_NO_INPUT},
--
-- {0, NULL, NULL, 0}
--};
--
--static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
--{
-- int *new_list;
-- switch (cmd) {
--#ifdef CIOCGSESSINFO
-- case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
-- switch (i) {
-- case DEVCRYPTO_REQUIRE_ACCELERATED:
-- case DEVCRYPTO_USE_SOFTWARE:
-- case DEVCRYPTO_REJECT_SOFTWARE:
-- break;
-- default:
-- fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
-- return 0;
-- }
-- if (use_softdrivers == i)
-- return 1;
-- use_softdrivers = i;
--#ifdef IMPLEMENT_DIGEST
-- rebuild_known_digest_nids(e);
--#endif
-- rebuild_known_cipher_nids(e);
-- return 1;
--#endif /* CIOCGSESSINFO */
--
-- case DEVCRYPTO_CMD_CIPHERS:
-- if (p == NULL)
-- return 1;
-- if (strcasecmp((const char *)p, "ALL") == 0) {
-- devcrypto_select_all_ciphers(selected_ciphers);
-- } else if (strcasecmp((const char*)p, "NONE") == 0) {
-- memset(selected_ciphers, 0, sizeof(selected_ciphers));
-- } else {
-- new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
-- if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
-- OPENSSL_free(new_list);
-- return 0;
-- }
-- memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
-- OPENSSL_free(new_list);
-- }
-- rebuild_known_cipher_nids(e);
-- return 1;
--
--#ifdef IMPLEMENT_DIGEST
-- case DEVCRYPTO_CMD_DIGESTS:
-- if (p == NULL)
-- return 1;
-- if (strcasecmp((const char *)p, "ALL") == 0) {
-- devcrypto_select_all_digests(selected_digests);
-- } else if (strcasecmp((const char*)p, "NONE") == 0) {
-- memset(selected_digests, 0, sizeof(selected_digests));
-- } else {
-- new_list=OPENSSL_zalloc(sizeof(selected_digests));
-- if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
-- OPENSSL_free(new_list);
-- return 0;
-- }
-- memcpy(selected_digests, new_list, sizeof(selected_digests));
-- OPENSSL_free(new_list);
-- }
-- rebuild_known_digest_nids(e);
-- return 1;
--#endif /* IMPLEMENT_DIGEST */
--
-- case DEVCRYPTO_CMD_DUMP_INFO:
-- dump_cipher_info();
--#ifdef IMPLEMENT_DIGEST
-- dump_digest_info();
--#endif
-- return 1;
--
-- default:
-- break;
-- }
-- return 0;
--}
--
--/******************************************************************************
-- *
-- * LOAD / UNLOAD
-- *
-- *****/
--
--static int devcrypto_unload(ENGINE *e)
--{
-- destroy_all_cipher_methods();
--#ifdef IMPLEMENT_DIGEST
-- destroy_all_digest_methods();
--#endif
--
-- close(cfd);
--
-- return 1;
--}
--/*
-- * This engine is always built into libcrypto, so it doesn't offer any
-- * ability to be dynamically loadable.
-- */
--void engine_load_devcrypto_int()
--{
-- ENGINE *e = NULL;
-- int fd;
--
-- if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
--#ifndef ENGINE_DEVCRYPTO_DEBUG
-- if (errno != ENOENT)
--#endif
-- fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno));
-- return;
-- }
--
--#ifdef CRIOGET
-- if (ioctl(fd, CRIOGET, &cfd) < 0) {
-- fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno));
-- close(fd);
-- cfd = -1;
-- return;
-- }
-- close(fd);
--#else
-- cfd = fd;
--#endif
--
-- if ((e = ENGINE_new()) == NULL
-- || !ENGINE_set_destroy_function(e, devcrypto_unload)) {
-- ENGINE_free(e);
-- /*
-- * We know that devcrypto_unload() won't be called when one of the
-- * above two calls have failed, so we close cfd explicitly here to
-- * avoid leaking resources.
-- */
-- close(cfd);
-- return;
-- }
--
-- prepare_cipher_methods();
--#ifdef IMPLEMENT_DIGEST
-- prepare_digest_methods();
--#endif
--
-- if (!ENGINE_set_id(e, "devcrypto")
-- || !ENGINE_set_name(e, "/dev/crypto engine")
-- || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
-- || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)
--
--/*
-- * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
-- * implementations, it seems to only exist in FreeBSD, and regarding the
-- * parameters in its crypt_kop, the manual crypto(4) has this to say:
-- *
-- * The semantics of these arguments are currently undocumented.
-- *
-- * Reading through the FreeBSD source code doesn't give much more than
-- * their CRK_MOD_EXP implementation for ubsec.
-- *
-- * It doesn't look much better with cryptodev-linux. They have the crypt_kop
-- * structure as well as the command (CRK_*) in cryptodev.h, but no support
-- * seems to be implemented at all for the moment.
-- *
-- * At the time of writing, it seems impossible to write proper support for
-- * FreeBSD's asym features without some very deep knowledge and access to
-- * specific kernel modules.
-- *
-- * /Richard Levitte, 2017-05-11
-- */
--#if 0
--# ifndef OPENSSL_NO_RSA
-- || !ENGINE_set_RSA(e, devcrypto_rsa)
--# endif
--# ifndef OPENSSL_NO_DSA
-- || !ENGINE_set_DSA(e, devcrypto_dsa)
--# endif
--# ifndef OPENSSL_NO_DH
-- || !ENGINE_set_DH(e, devcrypto_dh)
--# endif
--# ifndef OPENSSL_NO_EC
-- || !ENGINE_set_EC(e, devcrypto_ec)
--# endif
--#endif
-- || !ENGINE_set_ciphers(e, devcrypto_ciphers)
--#ifdef IMPLEMENT_DIGEST
-- || !ENGINE_set_digests(e, devcrypto_digests)
--#endif
-- ) {
-- ENGINE_free(e);
-- return;
-- }
--
-- ENGINE_add(e);
-- ENGINE_free(e); /* Loose our local reference */
-- ERR_clear_error();
--}
---- /dev/null
-+++ b/engines/e_devcrypto.c
-@@ -0,0 +1,1327 @@
-+/*
-+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
-+ *
-+ * Licensed under the OpenSSL license (the "License"). You may not use
-+ * this file except in compliance with the License. You can obtain a copy
-+ * in the file LICENSE in the source distribution or at
-+ * https://www.openssl.org/source/license.html
-+ */
-+
-+#include "../e_os.h"
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <sys/ioctl.h>
-+#include <unistd.h>
-+#include <assert.h>
-+
-+#include <openssl/conf.h>
-+#include <openssl/evp.h>
-+#include <openssl/err.h>
-+#include <openssl/engine.h>
-+#include <openssl/objects.h>
-+#include <crypto/cryptodev.h>
-+
-+#include "crypto/engine.h"
-+
-+/* #define ENGINE_DEVCRYPTO_DEBUG */
-+
-+#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX
-+# define CHECK_BSD_STYLE_MACROS
-+#endif
-+
-+#define engine_devcrypto_id "devcrypto"
-+
-+/*
-+ * ONE global file descriptor for all sessions. This allows operations
-+ * such as digest session data copying (see digest_copy()), but is also
-+ * saner... why re-open /dev/crypto for every session?
-+ */
-+static int cfd = -1;
-+#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
-+#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
-+#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
-+
-+#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE
-+static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS;
-+
-+/*
-+ * cipher/digest status & acceleration definitions
-+ * Make sure the defaults are set to 0
-+ */
-+struct driver_info_st {
-+ enum devcrypto_status_t {
-+ DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
-+ DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
-+ DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
-+ DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
-+ DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
-+ } status;
-+
-+ enum devcrypto_accelerated_t {
-+ DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
-+ DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
-+ DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
-+ } accelerated;
-+
-+ char *driver_name;
-+};
-+
-+static int clean_devcrypto_session(struct session_op *sess) {
-+ if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+ memset(sess, 0, sizeof(struct session_op));
-+ return 1;
-+}
-+
-+/******************************************************************************
-+ *
-+ * Ciphers
-+ *
-+ * Because they all do the same basic operation, we have only one set of
-+ * method functions for them all to share, and a mapping table between
-+ * NIDs and cryptodev IDs, with all the necessary size data.
-+ *
-+ *****/
-+
-+struct cipher_ctx {
-+ struct session_op sess;
-+ int op; /* COP_ENCRYPT or COP_DECRYPT */
-+ unsigned long mode; /* EVP_CIPH_*_MODE */
-+
-+ /* to handle ctr mode being a stream cipher */
-+ unsigned char partial[EVP_MAX_BLOCK_LENGTH];
-+ unsigned int blocksize, num;
-+};
-+
-+static const struct cipher_data_st {
-+ int nid;
-+ int blocksize;
-+ int keylen;
-+ int ivlen;
-+ int flags;
-+ int devcryptoid;
-+} cipher_data[] = {
-+#ifndef OPENSSL_NO_DES
-+ { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
-+ { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
-+#endif
-+#ifndef OPENSSL_NO_BF
-+ { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
-+#endif
-+#ifndef OPENSSL_NO_CAST
-+ { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
-+#endif
-+ { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
-+ { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
-+ { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
-+#ifndef OPENSSL_NO_RC4
-+ { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 },
-+#endif
-+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
-+ { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
-+ { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
-+ { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
-+#endif
-+#if 0 /* Not yet supported */
-+ { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
-+ { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
-+#endif
-+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
-+ { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
-+ { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
-+ { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
-+#endif
-+#if 0 /* Not yet supported */
-+ { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
-+ { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
-+ { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
-+#endif
-+#ifndef OPENSSL_NO_CAMELLIA
-+ { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
-+ CRYPTO_CAMELLIA_CBC },
-+ { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
-+ CRYPTO_CAMELLIA_CBC },
-+ { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
-+ CRYPTO_CAMELLIA_CBC },
-+#endif
-+};
-+
-+static size_t find_cipher_data_index(int nid)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++)
-+ if (nid == cipher_data[i].nid)
-+ return i;
-+ return (size_t)-1;
-+}
-+
-+static size_t get_cipher_data_index(int nid)
-+{
-+ size_t i = find_cipher_data_index(nid);
-+
-+ if (i != (size_t)-1)
-+ return i;
-+
-+ /*
-+ * Code further down must make sure that only NIDs in the table above
-+ * are used. If any other NID reaches this function, there's a grave
-+ * coding error further down.
-+ */
-+ assert("Code that never should be reached" == NULL);
-+ return -1;
-+}
-+
-+static const struct cipher_data_st *get_cipher_data(int nid)
-+{
-+ return &cipher_data[get_cipher_data_index(nid)];
-+}
-+
-+/*
-+ * Following are the three necessary functions to map OpenSSL functionality
-+ * with cryptodev.
-+ */
-+
-+static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+ const unsigned char *iv, int enc)
-+{
-+ struct cipher_ctx *cipher_ctx =
-+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-+ const struct cipher_data_st *cipher_d =
-+ get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
-+
-+ /* cleanup a previous session */
-+ if (cipher_ctx->sess.ses != 0 &&
-+ clean_devcrypto_session(&cipher_ctx->sess) == 0)
-+ return 0;
-+
-+ cipher_ctx->sess.cipher = cipher_d->devcryptoid;
-+ cipher_ctx->sess.keylen = cipher_d->keylen;
-+ cipher_ctx->sess.key = (void *)key;
-+ cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
-+ cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
-+ cipher_ctx->blocksize = cipher_d->blocksize;
-+ if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+ const unsigned char *in, size_t inl)
-+{
-+ struct cipher_ctx *cipher_ctx =
-+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-+ struct crypt_op cryp;
-+ unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
-+#if !defined(COP_FLAG_WRITE_IV)
-+ unsigned char saved_iv[EVP_MAX_IV_LENGTH];
-+ const unsigned char *ivptr;
-+ size_t nblocks, ivlen;
-+#endif
-+
-+ memset(&cryp, 0, sizeof(cryp));
-+ cryp.ses = cipher_ctx->sess.ses;
-+ cryp.len = inl;
-+ cryp.src = (void *)in;
-+ cryp.dst = (void *)out;
-+ cryp.iv = (void *)iv;
-+ cryp.op = cipher_ctx->op;
-+#if !defined(COP_FLAG_WRITE_IV)
-+ cryp.flags = 0;
-+
-+ ivlen = EVP_CIPHER_CTX_iv_length(ctx);
-+ if (ivlen > 0)
-+ switch (cipher_ctx->mode) {
-+ case EVP_CIPH_CBC_MODE:
-+ assert(inl >= ivlen);
-+ if (!EVP_CIPHER_CTX_encrypting(ctx)) {
-+ ivptr = in + inl - ivlen;
-+ memcpy(saved_iv, ivptr, ivlen);
-+ }
-+ break;
-+
-+ case EVP_CIPH_CTR_MODE:
-+ break;
-+
-+ default: /* should not happen */
-+ return 0;
-+ }
-+#else
-+ cryp.flags = COP_FLAG_WRITE_IV;
-+#endif
-+
-+ if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+
-+#if !defined(COP_FLAG_WRITE_IV)
-+ if (ivlen > 0)
-+ switch (cipher_ctx->mode) {
-+ case EVP_CIPH_CBC_MODE:
-+ assert(inl >= ivlen);
-+ if (EVP_CIPHER_CTX_encrypting(ctx))
-+ ivptr = out + inl - ivlen;
-+ else
-+ ivptr = saved_iv;
-+
-+ memcpy(iv, ivptr, ivlen);
-+ break;
-+
-+ case EVP_CIPH_CTR_MODE:
-+ nblocks = (inl + cipher_ctx->blocksize - 1)
-+ / cipher_ctx->blocksize;
-+ do {
-+ ivlen--;
-+ nblocks += iv[ivlen];
-+ iv[ivlen] = (uint8_t) nblocks;
-+ nblocks >>= 8;
-+ } while (ivlen);
-+ break;
-+
-+ default: /* should not happen */
-+ return 0;
-+ }
-+#endif
-+
-+ return 1;
-+}
-+
-+static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+ const unsigned char *in, size_t inl)
-+{
-+ struct cipher_ctx *cipher_ctx =
-+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-+ size_t nblocks, len;
-+
-+ /* initial partial block */
-+ while (cipher_ctx->num && inl) {
-+ (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num];
-+ --inl;
-+ cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize;
-+ }
-+
-+ /* full blocks */
-+ if (inl > (unsigned int) cipher_ctx->blocksize) {
-+ nblocks = inl/cipher_ctx->blocksize;
-+ len = nblocks * cipher_ctx->blocksize;
-+ if (cipher_do_cipher(ctx, out, in, len) < 1)
-+ return 0;
-+ inl -= len;
-+ out += len;
-+ in += len;
-+ }
-+
-+ /* final partial block */
-+ if (inl) {
-+ memset(cipher_ctx->partial, 0, cipher_ctx->blocksize);
-+ if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial,
-+ cipher_ctx->blocksize) < 1)
-+ return 0;
-+ while (inl--) {
-+ out[cipher_ctx->num] = in[cipher_ctx->num]
-+ ^ cipher_ctx->partial[cipher_ctx->num];
-+ cipher_ctx->num++;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
-+{
-+ struct cipher_ctx *cipher_ctx =
-+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-+ EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
-+ struct cipher_ctx *to_cipher_ctx;
-+
-+ switch (type) {
-+ case EVP_CTRL_COPY:
-+ if (cipher_ctx == NULL)
-+ return 1;
-+ /* when copying the context, a new session needs to be initialized */
-+ to_cipher_ctx =
-+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx);
-+ memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess));
-+ return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
-+ (cipher_ctx->op == COP_ENCRYPT));
-+
-+ case EVP_CTRL_INIT:
-+ memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
-+ return 1;
-+
-+ default:
-+ break;
-+ }
-+
-+ return -1;
-+}
-+
-+static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
-+{
-+ struct cipher_ctx *cipher_ctx =
-+ (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
-+
-+ return clean_devcrypto_session(&cipher_ctx->sess);
-+}
-+
-+/*
-+ * Keep tables of known nids, associated methods, selected ciphers, and driver
-+ * info.
-+ * Note that known_cipher_nids[] isn't necessarily indexed the same way as
-+ * cipher_data[] above, which the other tables are.
-+ */
-+static int known_cipher_nids[OSSL_NELEM(cipher_data)];
-+static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
-+static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
-+static int selected_ciphers[OSSL_NELEM(cipher_data)];
-+static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
-+
-+
-+static int devcrypto_test_cipher(size_t cipher_data_index)
-+{
-+ return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
-+ && selected_ciphers[cipher_data_index] == 1
-+ && (cipher_driver_info[cipher_data_index].accelerated
-+ == DEVCRYPTO_ACCELERATED
-+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
-+ || (cipher_driver_info[cipher_data_index].accelerated
-+ != DEVCRYPTO_NOT_ACCELERATED
-+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
-+}
-+
-+static void prepare_cipher_methods(void)
-+{
-+ size_t i;
-+ struct session_op sess;
-+ unsigned long cipher_mode;
-+#ifdef CIOCGSESSINFO
-+ struct session_info_op siop;
-+#endif
-+
-+ memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
-+
-+ memset(&sess, 0, sizeof(sess));
-+ sess.key = (void *)"01234567890123456789012345678901234567890123456789";
-+
-+ for (i = 0, known_cipher_nids_amount = 0;
-+ i < OSSL_NELEM(cipher_data); i++) {
-+
-+ selected_ciphers[i] = 1;
-+ /*
-+ * Check that the cipher is usable
-+ */
-+ sess.cipher = cipher_data[i].devcryptoid;
-+ sess.keylen = cipher_data[i].keylen;
-+ if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
-+ continue;
-+ }
-+
-+ cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
-+
-+ if ((known_cipher_methods[i] =
-+ EVP_CIPHER_meth_new(cipher_data[i].nid,
-+ cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
-+ cipher_data[i].blocksize,
-+ cipher_data[i].keylen)) == NULL
-+ || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
-+ cipher_data[i].ivlen)
-+ || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
-+ cipher_data[i].flags
-+ | EVP_CIPH_CUSTOM_COPY
-+ | EVP_CIPH_CTRL_INIT
-+ | EVP_CIPH_FLAG_DEFAULT_ASN1)
-+ || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
-+ || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
-+ cipher_mode == EVP_CIPH_CTR_MODE ?
-+ ctr_do_cipher :
-+ cipher_do_cipher)
-+ || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
-+ || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
-+ cipher_cleanup)
-+ || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
-+ sizeof(struct cipher_ctx))) {
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
-+ EVP_CIPHER_meth_free(known_cipher_methods[i]);
-+ known_cipher_methods[i] = NULL;
-+ } else {
-+ cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
-+#ifdef CIOCGSESSINFO
-+ siop.ses = sess.ses;
-+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-+ } else {
-+ cipher_driver_info[i].driver_name =
-+ OPENSSL_strndup(siop.cipher_info.cra_driver_name,
-+ CRYPTODEV_MAX_ALG_NAME);
-+ if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+ else
-+ cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+ }
-+#endif /* CIOCGSESSINFO */
-+ }
-+ ioctl(cfd, CIOCFSESSION, &sess.ses);
-+ if (devcrypto_test_cipher(i)) {
-+ known_cipher_nids[known_cipher_nids_amount++] =
-+ cipher_data[i].nid;
-+ }
-+ }
-+}
-+
-+static void rebuild_known_cipher_nids(ENGINE *e)
-+{
-+ size_t i;
-+
-+ for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
-+ if (devcrypto_test_cipher(i))
-+ known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
-+ }
-+ ENGINE_unregister_ciphers(e);
-+ ENGINE_register_ciphers(e);
-+}
-+
-+static const EVP_CIPHER *get_cipher_method(int nid)
-+{
-+ size_t i = get_cipher_data_index(nid);
-+
-+ if (i == (size_t)-1)
-+ return NULL;
-+ return known_cipher_methods[i];
-+}
-+
-+static int get_cipher_nids(const int **nids)
-+{
-+ *nids = known_cipher_nids;
-+ return known_cipher_nids_amount;
-+}
-+
-+static void destroy_cipher_method(int nid)
-+{
-+ size_t i = get_cipher_data_index(nid);
-+
-+ EVP_CIPHER_meth_free(known_cipher_methods[i]);
-+ known_cipher_methods[i] = NULL;
-+}
-+
-+static void destroy_all_cipher_methods(void)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
-+ destroy_cipher_method(cipher_data[i].nid);
-+ OPENSSL_free(cipher_driver_info[i].driver_name);
-+ cipher_driver_info[i].driver_name = NULL;
-+ }
-+}
-+
-+static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-+ const int **nids, int nid)
-+{
-+ if (cipher == NULL)
-+ return get_cipher_nids(nids);
-+
-+ *cipher = get_cipher_method(nid);
-+
-+ return *cipher != NULL;
-+}
-+
-+static void devcrypto_select_all_ciphers(int *cipher_list)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++)
-+ cipher_list[i] = 1;
-+}
-+
-+static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
-+{
-+ int *cipher_list = (int *)usr;
-+ char *name;
-+ const EVP_CIPHER *EVP;
-+ size_t i;
-+
-+ if (len == 0)
-+ return 1;
-+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
-+ return 0;
-+ EVP = EVP_get_cipherbyname(name);
-+ if (EVP == NULL)
-+ fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
-+ else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
-+ cipher_list[i] = 1;
-+ else
-+ fprintf(stderr, "devcrypto: cipher %s not available\n", name);
-+ OPENSSL_free(name);
-+ return 1;
-+}
-+
-+static void dump_cipher_info(void)
-+{
-+ size_t i;
-+ const char *name;
-+
-+ fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
-+ " engine:\n");
-+#ifndef CIOCGSESSINFO
-+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
-+#endif
-+ for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
-+ name = OBJ_nid2sn(cipher_data[i].nid);
-+ fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
-+ name ? name : "unknown", cipher_data[i].nid,
-+ cipher_data[i].devcryptoid);
-+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
-+ fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
-+ continue;
-+ }
-+ fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
-+ cipher_driver_info[i].driver_name : "unknown");
-+ if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
-+ fprintf(stderr, "(hw accelerated)");
-+ else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
-+ fprintf(stderr, "(software)");
-+ else
-+ fprintf(stderr, "(acceleration status unknown)");
-+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
-+ fprintf (stderr, ". Cipher setup failed");
-+ fprintf(stderr, "\n");
-+ }
-+ fprintf(stderr, "\n");
-+}
-+
-+/*
-+ * We only support digests if the cryptodev implementation supports multiple
-+ * data updates and session copying. Otherwise, we would be forced to maintain
-+ * a cache, which is perilous if there's a lot of data coming in (if someone
-+ * wants to checksum an OpenSSL tarball, for example).
-+ */
-+#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
-+#define IMPLEMENT_DIGEST
-+
-+/******************************************************************************
-+ *
-+ * Digests
-+ *
-+ * Because they all do the same basic operation, we have only one set of
-+ * method functions for them all to share, and a mapping table between
-+ * NIDs and cryptodev IDs, with all the necessary size data.
-+ *
-+ *****/
-+
-+struct digest_ctx {
-+ struct session_op sess;
-+ /* This signals that the init function was called, not that it succeeded. */
-+ int init_called;
-+ unsigned char digest_res[HASH_MAX_LEN];
-+};
-+
-+static const struct digest_data_st {
-+ int nid;
-+ int blocksize;
-+ int digestlen;
-+ int devcryptoid;
-+} digest_data[] = {
-+#ifndef OPENSSL_NO_MD5
-+ { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 },
-+#endif
-+ { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 },
-+#ifndef OPENSSL_NO_RMD160
-+# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160)
-+ { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 },
-+# endif
-+#endif
-+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224)
-+ { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 },
-+#endif
-+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256)
-+ { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 },
-+#endif
-+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384)
-+ { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 },
-+#endif
-+#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512)
-+ { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 },
-+#endif
-+};
-+
-+static size_t find_digest_data_index(int nid)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++)
-+ if (nid == digest_data[i].nid)
-+ return i;
-+ return (size_t)-1;
-+}
-+
-+static size_t get_digest_data_index(int nid)
-+{
-+ size_t i = find_digest_data_index(nid);
-+
-+ if (i != (size_t)-1)
-+ return i;
-+
-+ /*
-+ * Code further down must make sure that only NIDs in the table above
-+ * are used. If any other NID reaches this function, there's a grave
-+ * coding error further down.
-+ */
-+ assert("Code that never should be reached" == NULL);
-+ return -1;
-+}
-+
-+static const struct digest_data_st *get_digest_data(int nid)
-+{
-+ return &digest_data[get_digest_data_index(nid)];
-+}
-+
-+/*
-+ * Following are the five necessary functions to map OpenSSL functionality
-+ * with cryptodev: init, update, final, cleanup, and copy.
-+ */
-+
-+static int digest_init(EVP_MD_CTX *ctx)
-+{
-+ struct digest_ctx *digest_ctx =
-+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
-+ const struct digest_data_st *digest_d =
-+ get_digest_data(EVP_MD_CTX_type(ctx));
-+
-+ digest_ctx->init_called = 1;
-+
-+ memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
-+ digest_ctx->sess.mac = digest_d->devcryptoid;
-+ if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen,
-+ void *res, unsigned int flags)
-+{
-+ struct crypt_op cryp;
-+
-+ memset(&cryp, 0, sizeof(cryp));
-+ cryp.ses = ctx->sess.ses;
-+ cryp.len = srclen;
-+ cryp.src = (void *)src;
-+ cryp.dst = NULL;
-+ cryp.mac = res;
-+ cryp.flags = flags;
-+ return ioctl(cfd, CIOCCRYPT, &cryp);
-+}
-+
-+static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-+{
-+ struct digest_ctx *digest_ctx =
-+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
-+
-+ if (count == 0)
-+ return 1;
-+
-+ if (digest_ctx == NULL)
-+ return 0;
-+
-+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-+ if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
-+ return 1;
-+ } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
-+ return 1;
-+ }
-+
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+}
-+
-+static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
-+{
-+ struct digest_ctx *digest_ctx =
-+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
-+
-+ if (md == NULL || digest_ctx == NULL)
-+ return 0;
-+
-+ if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
-+ memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
-+ } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
-+{
-+ struct digest_ctx *digest_from =
-+ (struct digest_ctx *)EVP_MD_CTX_md_data(from);
-+ struct digest_ctx *digest_to =
-+ (struct digest_ctx *)EVP_MD_CTX_md_data(to);
-+ struct cphash_op cphash;
-+
-+ if (digest_from == NULL || digest_from->init_called != 1)
-+ return 1;
-+
-+ if (!digest_init(to)) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+
-+ cphash.src_ses = digest_from->sess.ses;
-+ cphash.dst_ses = digest_to->sess.ses;
-+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
-+ SYSerr(SYS_F_IOCTL, errno);
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+static int digest_cleanup(EVP_MD_CTX *ctx)
-+{
-+ struct digest_ctx *digest_ctx =
-+ (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
-+
-+ if (digest_ctx == NULL)
-+ return 1;
-+
-+ return clean_devcrypto_session(&digest_ctx->sess);
-+}
-+
-+/*
-+ * Keep tables of known nids, associated methods, selected digests, and
-+ * driver info.
-+ * Note that known_digest_nids[] isn't necessarily indexed the same way as
-+ * digest_data[] above, which the other tables are.
-+ */
-+static int known_digest_nids[OSSL_NELEM(digest_data)];
-+static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
-+static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
-+static int selected_digests[OSSL_NELEM(digest_data)];
-+static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
-+
-+static int devcrypto_test_digest(size_t digest_data_index)
-+{
-+ return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
-+ && selected_digests[digest_data_index] == 1
-+ && (digest_driver_info[digest_data_index].accelerated
-+ == DEVCRYPTO_ACCELERATED
-+ || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
-+ || (digest_driver_info[digest_data_index].accelerated
-+ != DEVCRYPTO_NOT_ACCELERATED
-+ && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
-+}
-+
-+static void rebuild_known_digest_nids(ENGINE *e)
-+{
-+ size_t i;
-+
-+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
-+ if (devcrypto_test_digest(i))
-+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
-+ }
-+ ENGINE_unregister_digests(e);
-+ ENGINE_register_digests(e);
-+}
-+
-+static void prepare_digest_methods(void)
-+{
-+ size_t i;
-+ struct session_op sess1, sess2;
-+#ifdef CIOCGSESSINFO
-+ struct session_info_op siop;
-+#endif
-+ struct cphash_op cphash;
-+
-+ memset(&digest_driver_info, 0, sizeof(digest_driver_info));
-+
-+ memset(&sess1, 0, sizeof(sess1));
-+ memset(&sess2, 0, sizeof(sess2));
-+
-+ for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
-+ i++) {
-+
-+ selected_digests[i] = 1;
-+
-+ /*
-+ * Check that the digest is usable
-+ */
-+ sess1.mac = digest_data[i].devcryptoid;
-+ sess2.ses = 0;
-+ if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
-+ goto finish;
-+ }
-+
-+#ifdef CIOCGSESSINFO
-+ /* gather hardware acceleration info from the driver */
-+ siop.ses = sess1.ses;
-+ if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
-+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
-+ } else {
-+ digest_driver_info[i].driver_name =
-+ OPENSSL_strndup(siop.hash_info.cra_driver_name,
-+ CRYPTODEV_MAX_ALG_NAME);
-+ if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
-+ digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
-+ else
-+ digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
-+ }
-+#endif
-+
-+ /* digest must be capable of hash state copy */
-+ sess2.mac = sess1.mac;
-+ if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
-+ goto finish;
-+ }
-+ cphash.src_ses = sess1.ses;
-+ cphash.dst_ses = sess2.ses;
-+ if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
-+ goto finish;
-+ }
-+ if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
-+ NID_undef)) == NULL
-+ || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i],
-+ digest_data[i].blocksize)
-+ || !EVP_MD_meth_set_result_size(known_digest_methods[i],
-+ digest_data[i].digestlen)
-+ || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init)
-+ || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update)
-+ || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final)
-+ || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy)
-+ || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
-+ || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
-+ sizeof(struct digest_ctx))) {
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
-+ EVP_MD_meth_free(known_digest_methods[i]);
-+ known_digest_methods[i] = NULL;
-+ goto finish;
-+ }
-+ digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
-+finish:
-+ ioctl(cfd, CIOCFSESSION, &sess1.ses);
-+ if (sess2.ses != 0)
-+ ioctl(cfd, CIOCFSESSION, &sess2.ses);
-+ if (devcrypto_test_digest(i))
-+ known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
-+ }
-+}
-+
-+static const EVP_MD *get_digest_method(int nid)
-+{
-+ size_t i = get_digest_data_index(nid);
-+
-+ if (i == (size_t)-1)
-+ return NULL;
-+ return known_digest_methods[i];
-+}
-+
-+static int get_digest_nids(const int **nids)
-+{
-+ *nids = known_digest_nids;
-+ return known_digest_nids_amount;
-+}
-+
-+static void destroy_digest_method(int nid)
-+{
-+ size_t i = get_digest_data_index(nid);
-+
-+ EVP_MD_meth_free(known_digest_methods[i]);
-+ known_digest_methods[i] = NULL;
-+}
-+
-+static void destroy_all_digest_methods(void)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++) {
-+ destroy_digest_method(digest_data[i].nid);
-+ OPENSSL_free(digest_driver_info[i].driver_name);
-+ digest_driver_info[i].driver_name = NULL;
-+ }
-+}
-+
-+static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
-+ const int **nids, int nid)
-+{
-+ if (digest == NULL)
-+ return get_digest_nids(nids);
-+
-+ *digest = get_digest_method(nid);
-+
-+ return *digest != NULL;
-+}
-+
-+static void devcrypto_select_all_digests(int *digest_list)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++)
-+ digest_list[i] = 1;
-+}
-+
-+static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
-+{
-+ int *digest_list = (int *)usr;
-+ char *name;
-+ const EVP_MD *EVP;
-+ size_t i;
-+
-+ if (len == 0)
-+ return 1;
-+ if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
-+ return 0;
-+ EVP = EVP_get_digestbyname(name);
-+ if (EVP == NULL)
-+ fprintf(stderr, "devcrypto: unknown digest %s\n", name);
-+ else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
-+ digest_list[i] = 1;
-+ else
-+ fprintf(stderr, "devcrypto: digest %s not available\n", name);
-+ OPENSSL_free(name);
-+ return 1;
-+}
-+
-+static void dump_digest_info(void)
-+{
-+ size_t i;
-+ const char *name;
-+
-+ fprintf (stderr, "Information about digests supported by the /dev/crypto"
-+ " engine:\n");
-+#ifndef CIOCGSESSINFO
-+ fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
-+#endif
-+
-+ for (i = 0; i < OSSL_NELEM(digest_data); i++) {
-+ name = OBJ_nid2sn(digest_data[i].nid);
-+ fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
-+ name ? name : "unknown", digest_data[i].nid,
-+ digest_data[i].devcryptoid,
-+ digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
-+ if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
-+ fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
-+ continue;
-+ }
-+ if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
-+ fprintf(stderr, " (hw accelerated)");
-+ else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
-+ fprintf(stderr, " (software)");
-+ else
-+ fprintf(stderr, " (acceleration status unknown)");
-+ if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
-+ fprintf (stderr, ". Cipher setup failed\n");
-+ else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
-+ fprintf(stderr, ", CIOCCPHASH failed\n");
-+ else
-+ fprintf(stderr, ", CIOCCPHASH capable\n");
-+ }
-+ fprintf(stderr, "\n");
-+}
-+
-+#endif
-+
-+/******************************************************************************
-+ *
-+ * CONTROL COMMANDS
-+ *
-+ *****/
-+
-+#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
-+#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
-+#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
-+#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
-+
-+/* Helper macros for CPP string composition */
-+#ifndef OPENSSL_MSTR
-+# define OPENSSL_MSTR_HELPER(x) #x
-+# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x)
-+#endif
-+
-+static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
-+#ifdef CIOCGSESSINFO
-+ {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
-+ "USE_SOFTDRIVERS",
-+ "specifies whether to use software (not accelerated) drivers ("
-+ OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
-+ OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
-+ OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
-+ "=use if acceleration can't be determined) [default="
-+ OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]",
-+ ENGINE_CMD_FLAG_NUMERIC},
-+#endif
-+
-+ {DEVCRYPTO_CMD_CIPHERS,
-+ "CIPHERS",
-+ "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
-+ ENGINE_CMD_FLAG_STRING},
-+
-+#ifdef IMPLEMENT_DIGEST
-+ {DEVCRYPTO_CMD_DIGESTS,
-+ "DIGESTS",
-+ "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
-+ ENGINE_CMD_FLAG_STRING},
-+#endif
-+
-+ {DEVCRYPTO_CMD_DUMP_INFO,
-+ "DUMP_INFO",
-+ "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
-+ ENGINE_CMD_FLAG_NO_INPUT},
-+
-+ {0, NULL, NULL, 0}
-+};
-+
-+static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
-+{
-+ int *new_list;
-+ switch (cmd) {
-+#ifdef CIOCGSESSINFO
-+ case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
-+ switch (i) {
-+ case DEVCRYPTO_REQUIRE_ACCELERATED:
-+ case DEVCRYPTO_USE_SOFTWARE:
-+ case DEVCRYPTO_REJECT_SOFTWARE:
-+ break;
-+ default:
-+ fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
-+ return 0;
-+ }
-+ if (use_softdrivers == i)
-+ return 1;
-+ use_softdrivers = i;
-+#ifdef IMPLEMENT_DIGEST
-+ rebuild_known_digest_nids(e);
-+#endif
-+ rebuild_known_cipher_nids(e);
-+ return 1;
-+#endif /* CIOCGSESSINFO */
-+
-+ case DEVCRYPTO_CMD_CIPHERS:
-+ if (p == NULL)
-+ return 1;
-+ if (strcasecmp((const char *)p, "ALL") == 0) {
-+ devcrypto_select_all_ciphers(selected_ciphers);
-+ } else if (strcasecmp((const char*)p, "NONE") == 0) {
-+ memset(selected_ciphers, 0, sizeof(selected_ciphers));
-+ } else {
-+ new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
-+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
-+ OPENSSL_free(new_list);
-+ return 0;
-+ }
-+ memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
-+ OPENSSL_free(new_list);
-+ }
-+ rebuild_known_cipher_nids(e);
-+ return 1;
-+
-+#ifdef IMPLEMENT_DIGEST
-+ case DEVCRYPTO_CMD_DIGESTS:
-+ if (p == NULL)
-+ return 1;
-+ if (strcasecmp((const char *)p, "ALL") == 0) {
-+ devcrypto_select_all_digests(selected_digests);
-+ } else if (strcasecmp((const char*)p, "NONE") == 0) {
-+ memset(selected_digests, 0, sizeof(selected_digests));
-+ } else {
-+ new_list=OPENSSL_zalloc(sizeof(selected_digests));
-+ if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
-+ OPENSSL_free(new_list);
-+ return 0;
-+ }
-+ memcpy(selected_digests, new_list, sizeof(selected_digests));
-+ OPENSSL_free(new_list);
-+ }
-+ rebuild_known_digest_nids(e);
-+ return 1;
-+#endif /* IMPLEMENT_DIGEST */
-+
-+ case DEVCRYPTO_CMD_DUMP_INFO:
-+ dump_cipher_info();
-+#ifdef IMPLEMENT_DIGEST
-+ dump_digest_info();
-+#endif
-+ return 1;
-+
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/******************************************************************************
-+ *
-+ * LOAD / UNLOAD
-+ *
-+ *****/
-+
-+/*
-+ * Opens /dev/crypto
-+ */
-+static int open_devcrypto(void)
-+{
-+ int fd;
-+
-+ if (cfd >= 0)
-+ return 1;
-+
-+ if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
-+#ifndef ENGINE_DEVCRYPTO_DEBUG
-+ if (errno != ENOENT)
-+#endif
-+ fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno));
-+ return 0;
-+ }
-+
-+#ifdef CRIOGET
-+ if (ioctl(fd, CRIOGET, &cfd) < 0) {
-+ fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno));
-+ close(fd);
-+ cfd = -1;
-+ return 0;
-+ }
-+ close(fd);
-+#else
-+ cfd = fd;
-+#endif
-+
-+ return 1;
-+}
-+
-+static int close_devcrypto(void)
-+{
-+ int ret;
-+
-+ if (cfd < 0)
-+ return 1;
-+ ret = close(cfd);
-+ cfd = -1;
-+ if (ret != 0) {
-+ fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno));
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+static int devcrypto_unload(ENGINE *e)
-+{
-+ destroy_all_cipher_methods();
-+#ifdef IMPLEMENT_DIGEST
-+ destroy_all_digest_methods();
-+#endif
-+
-+ close_devcrypto();
-+
-+ return 1;
-+}
-+
-+static int bind_devcrypto(ENGINE *e) {
-+
-+ if (!ENGINE_set_id(e, engine_devcrypto_id)
-+ || !ENGINE_set_name(e, "/dev/crypto engine")
-+ || !ENGINE_set_destroy_function(e, devcrypto_unload)
-+ || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
-+ || !ENGINE_set_ctrl_function(e, devcrypto_ctrl))
-+ return 0;
-+
-+ prepare_cipher_methods();
-+#ifdef IMPLEMENT_DIGEST
-+ prepare_digest_methods();
-+#endif
-+
-+ return (ENGINE_set_ciphers(e, devcrypto_ciphers)
-+#ifdef IMPLEMENT_DIGEST
-+ && ENGINE_set_digests(e, devcrypto_digests)
-+#endif
-+/*
-+ * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
-+ * implementations, it seems to only exist in FreeBSD, and regarding the
-+ * parameters in its crypt_kop, the manual crypto(4) has this to say:
-+ *
-+ * The semantics of these arguments are currently undocumented.
-+ *
-+ * Reading through the FreeBSD source code doesn't give much more than
-+ * their CRK_MOD_EXP implementation for ubsec.
-+ *
-+ * It doesn't look much better with cryptodev-linux. They have the crypt_kop
-+ * structure as well as the command (CRK_*) in cryptodev.h, but no support
-+ * seems to be implemented at all for the moment.
-+ *
-+ * At the time of writing, it seems impossible to write proper support for
-+ * FreeBSD's asym features without some very deep knowledge and access to
-+ * specific kernel modules.
-+ *
-+ * /Richard Levitte, 2017-05-11
-+ */
-+#if 0
-+# ifndef OPENSSL_NO_RSA
-+ && ENGINE_set_RSA(e, devcrypto_rsa)
-+# endif
-+# ifndef OPENSSL_NO_DSA
-+ && ENGINE_set_DSA(e, devcrypto_dsa)
-+# endif
-+# ifndef OPENSSL_NO_DH
-+ && ENGINE_set_DH(e, devcrypto_dh)
-+# endif
-+# ifndef OPENSSL_NO_EC
-+ && ENGINE_set_EC(e, devcrypto_ec)
-+# endif
-+#endif
-+ );
-+}
-+
-+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
-+/*
-+ * In case this engine is built into libcrypto, then it doesn't offer any
-+ * ability to be dynamically loadable.
-+ */
-+void engine_load_devcrypto_int(void)
-+{
-+ ENGINE *e = NULL;
-+
-+ if (!open_devcrypto())
-+ return;
-+
-+ if ((e = ENGINE_new()) == NULL
-+ || !bind_devcrypto(e)) {
-+ close_devcrypto();
-+ ENGINE_free(e);
-+ return;
-+ }
-+
-+ ENGINE_add(e);
-+ ENGINE_free(e); /* Loose our local reference */
-+ ERR_clear_error();
-+}
-+
-+#else
-+
-+static int bind_helper(ENGINE *e, const char *id)
-+{
-+ if ((id && (strcmp(id, engine_devcrypto_id) != 0))
-+ || !open_devcrypto())
-+ return 0;
-+ if (!bind_devcrypto(e)) {
-+ close_devcrypto();
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+IMPLEMENT_DYNAMIC_CHECK_FN()
-+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
-+
-+#endif
diff --git a/package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch b/package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch
deleted file mode 100644
index df5c16d8d2..0000000000
--- a/package/libs/openssl/patches/500-e_devcrypto-default-to-not-use-digests-in-engine.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Mon, 11 Mar 2019 09:29:13 -0300
-Subject: e_devcrypto: default to not use digests in engine
-
-Digests are almost always slower when using /dev/crypto because of the
-cost of the context switches. Only for large blocks it is worth it.
-
-Also, when forking, the open context structures are duplicated, but the
-internal kernel sessions are still shared between forks, which means an
-update/close operation in one fork affects all processes using that
-session.
-
-This affects digests, especially for HMAC, where the session with the
-key hash is used as a source for subsequent operations. At least one
-popular application does this across a fork. Disabling digests by
-default will mitigate the problem, while still allowing the user to
-turn them on if it is safe and fast enough.
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
---- a/engines/e_devcrypto.c
-+++ b/engines/e_devcrypto.c
-@@ -852,7 +852,7 @@ static void prepare_digest_methods(void)
- for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
- i++) {
-
-- selected_digests[i] = 1;
-+ selected_digests[i] = 0;
-
- /*
- * Check that the digest is usable
-@@ -1072,7 +1072,7 @@ static const ENGINE_CMD_DEFN devcrypto_c
- #ifdef IMPLEMENT_DIGEST
- {DEVCRYPTO_CMD_DIGESTS,
- "DIGESTS",
-- "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
-+ "either ALL, NONE, or a comma-separated list of digests to enable [default=NONE]",
- ENGINE_CMD_FLAG_STRING},
- #endif
-
diff --git a/package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch b/package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch
deleted file mode 100644
index 87792cf9d0..0000000000
--- a/package/libs/openssl/patches/510-e_devcrypto-ignore-error-when-closing-session.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Eneas U de Queiroz <cote2004-github at yahoo.com>
-Date: Mon, 11 Mar 2019 10:15:14 -0300
-Subject: e_devcrypto: ignore error when closing session
-
-In cipher_init, ignore an eventual error when closing the previous
-session. It may have been closed by another process after a fork.
-
-Signed-off-by: Eneas U de Queiroz <cote2004-github at yahoo.com>
-
---- a/engines/e_devcrypto.c
-+++ b/engines/e_devcrypto.c
-@@ -195,9 +195,8 @@ static int cipher_init(EVP_CIPHER_CTX *c
- get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
-
- /* cleanup a previous session */
-- if (cipher_ctx->sess.ses != 0 &&
-- clean_devcrypto_session(&cipher_ctx->sess) == 0)
-- return 0;
-+ if (cipher_ctx->sess.ses != 0)
-+ clean_devcrypto_session(&cipher_ctx->sess);
-
- cipher_ctx->sess.cipher = cipher_d->devcryptoid;
- cipher_ctx->sess.keylen = cipher_d->keylen;
More information about the lede-commits
mailing list