On Mon, Feb 25, 2019 at 10:01 AM Eneas U de Queiroz via openwrt-devel <openwrt-devel@lists.openwrt.org> wrote: > > The sender domain has a DMARC Reject/Quarantine policy which disallows > sending mailing list messages using the original "From" header. > > To mitigate this problem, the original message has been wrapped > automatically by the mailing list software. > > > ---------- Forwarded message ---------- > From: Eneas U de Queiroz <cote2004-git...@yahoo.com> > To: openwrt-devel@lists.openwrt.org > Cc: Eneas U de Queiroz <cote2004-git...@yahoo.com> > Bcc: > Date: Mon, 25 Feb 2019 15:00:58 -0300 > Subject: [PATCH v3] openssl: backport devcrypto changes from master > The patches to the /dev/crypto engine were commited to openssl master, > and will be in the next major version (3.0). This version does not apply to master. > > Changes: > - Optimization in computing a digest in one operation, saving an ioctl > - Runtime configuration options for the choice of algorithms to use > - Command to dump useful information about the algorithms supported by > the engine and the system. > - Build the devcrypto engine as a dynamic module, like other engines. > > The devcrypto engine is built as a separate package by default, but > options were added to allow building the engines into the main library. > > Signed-off-by: Eneas U de Queiroz <cote2004-git...@yahoo.com> > --- > This should only be merged after > openssl: fix devcrypto engine md blocksize > > I forgot to mention it before, but this was run-tested on Linksys > WRT3200ACM, WRT610N (software-only), & ASUS RT-N56U (software-only), > running nginx, bind, unbound, and now openssh. > > Changes: > v3: remove PKG_BUILD_DEPENDS:=cryptodev-linux, as it has been properly > added to DEPENDS now. > > v2: accommodate changes from openssl: fix devcrypto engine md blocksize > increased PKG_RELEASE > > diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in > index 3ad8a66b9e..235f38e787 100644 > --- a/package/libs/openssl/Config.in > +++ b/package/libs/openssl/Config.in > @@ -253,18 +253,41 @@ config OPENSSL_ENGINE > Note that you need to enable KERNEL_AIO to be able to build > the > afalg engine package. > > -config OPENSSL_ENGINE_CRYPTO > +config OPENSSL_ENGINE_BUILTIN > + bool "Build chosen engines into libcrypto" > + depends on OPENSSL_ENGINE > + help > + This builds all chosen engines into libcrypto.so, instead of > building > + them as dynamic engines in separate packages. > + The benefit of building the engines into libcrypto is that > they won't > + require any configuration to be used by default. > + > +config OPENSSL_ENGINE_BUILTIN_AFALG > bool > - select OPENSSL_ENGINE > - select PACKAGE_kmod-cryptodev > + prompt "Acceleration support through AF_ALG sockets engine" > + depends on OPENSSL_ENGINE_BUILTIN && KERNEL_AIO && !LINUX_3_18 > select PACKAGE_libopenssl-conf > + help > + This enables use of hardware acceleration through the > + AF_ALG kenrel interface. > + > +config OPENSSL_ENGINE_BUILTIN_DEVCRYPTO > + bool > prompt "Acceleration support through /dev/crypto" > + depends on OPENSSL_ENGINE_BUILTIN > + select PACKAGE_libopenssl-conf > help > This enables use of hardware acceleration through OpenBSD > Cryptodev API (/dev/crypto) interface. > - You must install kmod-cryptodev (under Kernel modules, > Cryptographic > - API modules) for /dev/crypto to show up and use hardware > - acceleration; otherwise it falls back to software. > + > +config OPENSSL_ENGINE_BUILTIN_PADLOCK > + bool > + prompt "VIA Padlock Acceleration support engine" > + depends on OPENSSL_ENGINE_BUILTIN && TARGET_x86 > + select PACKAGE_libopenssl-conf > + help > + This enables use of hardware acceleration through the > + VIA Padlock module. > > config OPENSSL_WITH_ASYNC > bool > diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile > index ab32668cb9..a7dbbae2b1 100644 > --- a/package/libs/openssl/Makefile > +++ b/package/libs/openssl/Makefile > @@ -11,12 +11,11 @@ PKG_NAME:=openssl > PKG_BASE:=1.1.1 > PKG_BUGFIX:=a > PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX) > -PKG_RELEASE:=3 > +PKG_RELEASE:=4 > PKG_USE_MIPS16:=0 > ENGINES_DIR=engines-1.1 > > PKG_BUILD_PARALLEL:=0 > -PKG_BUILD_DEPENDS:=cryptodev-linux > > PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz > PKG_SOURCE_URL:= \ > @@ -32,7 +31,10 @@ PKG_LICENSE_FILES:=LICENSE > PKG_CPE_ID:=cpe:/a:openssl:openssl > PKG_CONFIG_DEPENDS:= \ > CONFIG_OPENSSL_ENGINE \ > - CONFIG_OPENSSL_ENGINE_CRYPTO \ > + CONFIG_OPENSSL_ENGINE_BUILTIN \ > + CONFIG_OPENSSL_ENGINE_BUILTIN_AFALG \ > + CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO \ > + CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK \ > CONFIG_OPENSSL_NO_DEPRECATED \ > CONFIG_OPENSSL_OPTIMIZE_SPEED \ > CONFIG_OPENSSL_PREFER_CHACHA_OVER_GCM \ > @@ -89,7 +91,10 @@ endef > define Package/libopenssl > $(call Package/openssl/Default) > SUBMENU:=SSL > - DEPENDS:=+OPENSSL_WITH_COMPRESSION:zlib > + 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 > TITLE+= (libraries) > ABI_VERSION:=1.1 > MENU:=1 > @@ -134,7 +139,7 @@ define Package/libopenssl-afalg > SUBMENU:=SSL > TITLE:=AFALG hardware acceleration engine > DEPENDS:=libopenssl @OPENSSL_ENGINE @KERNEL_AIO @!LINUX_3_18 > +kmod-crypto-user \ > - +libopenssl-conf > + +libopenssl-conf @!OPENSSL_ENGINE_BUILTIN > endef > > define Package/libopenssl-afalg/description > @@ -145,12 +150,28 @@ See > https://www.openssl.org/docs/man1.1.1/man5/config.html#Engine-Configuration- > The engine_id is "afalg" > endef > > +define Package/libopenssl-devcrypto > + $(call Package/openssl/Default) > + SUBMENU:=SSL > + TITLE:=/dev/crypto hardware acceleration engine > + DEPENDS:=libopenssl @OPENSSL_ENGINE +kmod-cryptodev +libopenssl-conf \ > + @!OPENSSL_ENGINE_BUILTIN > +endef > + > +define Package/libopenssl-devcrypto/description > +This package adds an engine that enables hardware acceleration > +through the /dev/crypto kernel interface. > +To use it, you need to configure the engine in /etc/ssl/openssl.cnf > +See > https://www.openssl.org/docs/man1.1.1/man5/config.html#Engine-Configuration-Module > +The engine_id is "devcrypto" > +endef > + > define Package/libopenssl-padlock > $(call Package/openssl/Default) > SUBMENU:=SSL > TITLE:=VIA Padlock hardware acceleration engine > DEPENDS:=libopenssl @OPENSSL_ENGINE @TARGET_x86 +kmod-crypto-hw-padlock \ > - +libopenssl-conf > + +libopenssl-conf @!OPENSSL_ENGINE_BUILTIN > endef > > define Package/libopenssl-padlock/description > @@ -241,14 +262,27 @@ else > endif > > ifdef CONFIG_OPENSSL_ENGINE > - ifdef CONFIG_OPENSSL_ENGINE_CRYPTO > - OPENSSL_OPTIONS += enable-devcryptoeng > - endif > - ifndef CONFIG_PACKAGE_libopenssl-afalg > - OPENSSL_OPTIONS += no-afalgeng > - endif > - ifndef CONFIG_PACKAGE_libopenssl-padlock > - OPENSSL_OPTIONS += no-hw-padlock > + ifdef CONFIG_OPENSSL_ENGINE_BUILTIN > + OPENSSL_OPTIONS += disable-dynamic-engine > + ifndef CONFIG_OPENSSL_ENGINE_BUILTIN_AFALG > + OPENSSL_OPTIONS += no-afalgeng > + endif > + ifdef CONFIG_OPENSSL_ENGINE_BUILTIN_DEVCRYPTO > + OPENSSL_OPTIONS += enable-devcryptoeng > + endif > + ifndef CONFIG_OPENSSL_ENGINE_BUILTIN_PADLOCK > + OPENSSL_OPTIONS += no-hw-padlock > + endif > + else > + ifdef CONFIG_PACKAGE_libopenssl-devcrypto > + OPENSSL_OPTIONS += enable-devcryptoeng > + endif > + ifndef CONFIG_PACKAGE_libopenssl-afalg > + OPENSSL_OPTIONS += no-afalgeng > + endif > + ifndef CONFIG_PACKAGE_libopenssl-padlock > + OPENSSL_OPTIONS += no-hw-padlock > + endif > endif > else > OPENSSL_OPTIONS += no-engine > @@ -364,6 +398,11 @@ define Package/libopenssl-afalg/install > $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/$(ENGINES_DIR)/afalg.so > $(1)/usr/lib/$(ENGINES_DIR) > endef > > +define Package/libopenssl-devcrypto/install > + $(INSTALL_DIR) $(1)/usr/lib/$(ENGINES_DIR) > + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/$(ENGINES_DIR)/devcrypto.so > $(1)/usr/lib/$(ENGINES_DIR) > +endef > + > define Package/libopenssl-padlock/install > $(INSTALL_DIR) $(1)/usr/lib/$(ENGINES_DIR) > $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/$(ENGINES_DIR)/*padlock.so > $(1)/usr/lib/$(ENGINES_DIR) > @@ -372,5 +411,6 @@ endef > $(eval $(call BuildPackage,libopenssl)) > $(eval $(call BuildPackage,libopenssl-conf)) > $(eval $(call BuildPackage,libopenssl-afalg)) > +$(eval $(call BuildPackage,libopenssl-devcrypto)) > $(eval $(call BuildPackage,libopenssl-padlock)) > $(eval $(call BuildPackage,openssl-util)) > 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 > new file mode 100644 > index 0000000000..9ea3aef6ec > --- /dev/null > +++ > b/package/libs/openssl/patches/400-eng_devcrypto-save-ioctl-if-EVP_MD_.FLAG_ONESHOT.patch > @@ -0,0 +1,60 @@ > +From c50879688edc862213b19ae9993a4ac037af4781 Mon Sep 17 00:00:00 2001 > +From: Eneas U de Queiroz <cote2004-git...@yahoo.com> > +Date: Mon, 5 Nov 2018 15:54:17 -0200 > +Subject: [PATCH 1/4] 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-git...@yahoo.com> > + > +Reviewed-by: Matthias St. Pierre <matthias.st.pie...@ncp-e.com> > +Reviewed-by: Richard Levitte <levi...@openssl.org> > +(Merged from https://github.com/openssl/openssl/pull/7585) > + > +diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c > +index 11ec4393e7..f96cba70d7 100644 > +--- a/crypto/engine/eng_devcrypto.c > ++++ b/crypto/engine/eng_devcrypto.c > +@@ -460,6 +460,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 { > +@@ -562,12 +563,15 @@ static int digest_update(EVP_MD_CTX *ctx, const void > *data, size_t count) > + 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) > +@@ -577,7 +581,10 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char > *md) > + > + 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 > new file mode 100644 > index 0000000000..bc716a92e2 > --- /dev/null > +++ > b/package/libs/openssl/patches/410-eng_devcrypto-add-configuration-options.patch > @@ -0,0 +1,569 @@ > +From f9e4bf71b6ecff66a19a3594c870cd2f58e23af6 Mon Sep 17 00:00:00 2001 > +From: Eneas U de Queiroz <cote2004-git...@yahoo.com> > +Date: Sat, 3 Nov 2018 15:41:10 -0300 > +Subject: [PATCH 2/4] 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-git...@yahoo.com> > + > +Reviewed-by: Matthias St. Pierre <matthias.st.pie...@ncp-e.com> > +Reviewed-by: Richard Levitte <levi...@openssl.org> > +(Merged from https://github.com/openssl/openssl/pull/7585) > + > +diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c > +index f96cba70d7..0f0aee6b57 100644 > +--- 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> > +@@ -34,6 +35,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) { > +@@ -117,13 +142,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 > +@@ -332,19 +366,40 @@ static int cipher_cleanup(EVP_CIPHER_CTX *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"; > +@@ -352,15 +407,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; > + > +@@ -386,15 +442,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); > +@@ -437,6 +519,36 @@ static int devcrypto_ciphers(ENGINE *e, const > EVP_CIPHER **cipher, > + 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 > +@@ -492,13 +604,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 > +@@ -515,8 +636,8 @@ static const struct digest_data_st *get_digest_data(int > nid) > + } > + > + /* > +- * 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) > +@@ -628,52 +749,94 @@ static int digest_cleanup(EVP_MD_CTX *ctx) > + 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], > +@@ -687,11 +850,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; > + } > + } > + > +@@ -737,8 +907,154 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD > **digest, > + 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; > ++} > ++ > + > /****************************************************************************** > + * > + * LOAD / UNLOAD > +@@ -788,6 +1104,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 > new file mode 100644 > index 0000000000..4e3b8597bb > --- /dev/null > +++ > b/package/libs/openssl/patches/420-eng_devcrypto-add-command-to-dump-driver-info.patch > @@ -0,0 +1,275 @@ > +From 8cc22636b95de928f5abaebd0d19e2f040870953 Mon Sep 17 00:00:00 2001 > +From: Eneas U de Queiroz <cote2004-git...@yahoo.com> > +Date: Tue, 6 Nov 2018 22:54:07 -0200 > +Subject: [PATCH 3/4] 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-git...@yahoo.com> > + > +Reviewed-by: Matthias St. Pierre <matthias.st.pie...@ncp-e.com> > +Reviewed-by: Richard Levitte <levi...@openssl.org> > +(Merged from https://github.com/openssl/openssl/pull/7585) > + > +diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c > +index 0f0aee6b57..44e60cbc7b 100644 > +--- a/crypto/engine/eng_devcrypto.c > ++++ b/crypto/engine/eng_devcrypto.c > +@@ -48,16 +48,20 @@ static int use_softdrivers = > DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS; > + */ > + 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) { > +@@ -414,7 +418,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; > + } > + > +@@ -442,19 +446,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); > +@@ -504,8 +513,11 @@ static void destroy_all_cipher_methods(void) > + { > + 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, > +@@ -549,6 +561,40 @@ static int cryptodev_select_cipher_cb(const char *str, > int len, void *usr) > + 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 > +@@ -810,31 +856,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, > +@@ -850,7 +901,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; > +@@ -892,8 +943,11 @@ static void destroy_all_digest_methods(void) > + { > + 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, > +@@ -937,6 +991,43 @@ static int cryptodev_select_digest_cb(const char *str, > int len, void *usr) > + 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 > + > + > /****************************************************************************** > +@@ -981,6 +1072,11 @@ static const ENGINE_CMD_DEFN devcrypto_cmds[] = { > + 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} > + }; > + > +@@ -1049,6 +1145,13 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, > void *p, void (*f) (void)) > + 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 > new file mode 100644 > index 0000000000..fa5e48f36a > --- /dev/null > +++ > b/package/libs/openssl/patches/430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch > @@ -0,0 +1,336 @@ > +From 9e0ca5fff3fa439fc36fa5374671b91dc5657b6a Mon Sep 17 00:00:00 2001 > +From: Eneas U de Queiroz <cote2004-git...@yahoo.com> > +Date: Tue, 6 Nov 2018 10:57:03 -0200 > +Subject: [PATCH 4/4] 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-git...@yahoo.com> > + > +diff --git a/crypto/engine/build.info b/crypto/engine/build.info > +index e00802a3fd..47fe948966 100644 > +--- 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 > +diff --git a/crypto/init.c b/crypto/init.c > +index 209d1a483d..02c609535f 100644 > +--- a/crypto/init.c > ++++ b/crypto/init.c > +@@ -290,18 +290,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) > + 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; > +@@ -326,6 +314,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) > + 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) > +@@ -645,11 +645,6 @@ int OPENSSL_init_crypto(uint64_t opts, const > OPENSSL_INIT_SETTINGS *settings) > + 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)) > +@@ -659,6 +654,11 @@ int OPENSSL_init_crypto(uint64_t opts, const > OPENSSL_INIT_SETTINGS *settings) > + && !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)) > +diff --git a/engines/build.info b/engines/build.info > +index df173ea69d..dc0cbeb0a3 100644 > +--- a/engines/build.info > ++++ b/engines/build.info > +@@ -10,6 +10,9 @@ IF[{- !$disabled{"engine"} -}] > + IF[{- !$disabled{afalgeng} -}] > + SOURCE[../libcrypto]=e_afalg.c > + ENDIF > ++ IF[{- !$disabled{"devcryptoeng"} -}] > ++ SOURCE[../libcrypto]=e_devcrypto.c > ++ ENDIF > + ELSE > + ENGINES=padlock > + SOURCE[padlock]=e_padlock.c {- $target{padlock_asm_src} -} > +@@ -27,6 +30,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 > +diff --git a/crypto/engine/eng_devcrypto.c b/engines/e_devcrypto.c > +similarity index 95% > +rename from crypto/engine/eng_devcrypto.c > +rename to engines/e_devcrypto.c > +index 44e60cbc7b..9af2ce174a 100644 > +--- a/crypto/engine/eng_devcrypto.c > ++++ b/engines/e_devcrypto.c > +@@ -7,7 +7,7 @@ > + * https://www.openssl.org/source/license.html > + */ > + > +-#include "e_os.h" > ++#include "../e_os.h" > + #include <string.h> > + #include <sys/types.h> > + #include <sys/stat.h> > +@@ -23,24 +23,24 @@ > + #include <openssl/objects.h> > + #include <crypto/cryptodev.h> > + > +-#include "internal/engine.h" > +- > + #ifdef CRYPTO_ALGORITHM_MIN > + # 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; > ++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_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE > +-static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS; > ++#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE > ++static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS; > + > + /* > + * cipher/digest status & acceleration definitions > +@@ -73,6 +73,10 @@ static int clean_devcrypto_session(struct session_op > *sess) { > + return 1; > + } > + > ++#ifdef OPENSSL_NO_DYNAMIC_ENGINE > ++void engine_load_devcrypto_int(void); > ++#endif > ++ > + > /****************************************************************************** > + * > + * Ciphers > +@@ -1164,6 +1168,37 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, > void *p, void (*f) (void)) > + * > + *****/ > + > ++/* > ++ * Opens /dev/crypto > ++ */ > ++static int open_devcrypto(void) > ++{ > ++ if (cfd >= 0) > ++ return 1; > ++ > ++ if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { > ++ fprintf(stderr, "Could not open /dev/crypto: %s\n", > strerror(errno)); > ++ return 0; > ++ } > ++ > ++ 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(); > +@@ -1171,45 +1206,29 @@ static int devcrypto_unload(ENGINE *e) > + destroy_all_digest_methods(); > + #endif > + > +- close(cfd); > ++ close_devcrypto(); > + > + 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; > + > +- if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) { > +- fprintf(stderr, "Could not open /dev/crypto: %s\n", > strerror(errno)); > +- return; > +- } > ++static int bind_devcrypto(ENGINE *e) { > + > +- 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; > +- } > ++ 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 > + > +- 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) > +- > ++ 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 > +@@ -1232,23 +1251,36 @@ void engine_load_devcrypto_int() > + */ > + #if 0 > + # ifndef OPENSSL_NO_RSA > +- || !ENGINE_set_RSA(e, devcrypto_rsa) > ++ && ENGINE_set_RSA(e, devcrypto_rsa) > + # endif > + # ifndef OPENSSL_NO_DSA > +- || !ENGINE_set_DSA(e, devcrypto_dsa) > ++ && ENGINE_set_DSA(e, devcrypto_dsa) > + # endif > + # ifndef OPENSSL_NO_DH > +- || !ENGINE_set_DH(e, devcrypto_dh) > ++ && ENGINE_set_DH(e, devcrypto_dh) > + # endif > + # ifndef OPENSSL_NO_EC > +- || !ENGINE_set_EC(e, devcrypto_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 > +- ) { > ++ ); > ++} > ++ > ++#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; > + } > +@@ -1257,3 +1289,22 @@ void engine_load_devcrypto_int() > + 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 > > _______________________________________________ > openwrt-devel mailing list > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel