Initial commit

This commit is contained in:
domenico
2025-06-24 16:03:39 +02:00
commit f3256cdaf2
6949 changed files with 1441681 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
From 559fbff13af9ce2fbc0b9bc5727a7323e1db6217 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
Date: Thu, 27 Sep 2018 08:29:21 -0300
Subject: Do not use host kernel version to disable AFALG
This patch prevents the Configure script from using the host kernel
version to disable building the AFALG engine on openwrt targets.
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
diff --git a/Configure b/Configure
index 5a699836f3..74d057c219 100755
--- a/Configure
+++ b/Configure
@@ -1545,7 +1545,9 @@ unless ($disabled{"crypto-mdebug-backtrace"})
unless ($disabled{afalgeng}) {
$config{afalgeng}="";
- if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
+ if ($target =~ m/openwrt$/) {
+ push @{$config{engdirs}}, "afalg";
+ } elsif (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
my $minver = 4*10000 + 1*100 + 0;
if ($config{CROSS_COMPILE} eq "") {
my $verstr = `uname -r`;

View File

@@ -0,0 +1,63 @@
From 3d43acc6068f00dbfc0c9a06355e2c8f7d302d0f Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
Date: Thu, 27 Sep 2018 08:30:24 -0300
Subject: Add openwrt targets
Targets are named: linux-$(CONFIG_ARCH)-openwrt
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
diff --git a/Configurations/25-openwrt.conf b/Configurations/25-openwrt.conf
new file mode 100644
index 0000000000..86a86d31e4
--- /dev/null
+++ b/Configurations/25-openwrt.conf
@@ -0,0 +1,48 @@
+## Openwrt "CONFIG_ARCH" matching targets.
+
+# The targets need to end in '-openwrt' for the AFALG patch to work
+
+my %targets = (
+ "openwrt" => {
+ template => 1,
+ CFLAGS => add("\$(OPENWRT_OPTIMIZATION_FLAGS)"),
+ },
+ "linux-aarch64-openwrt" => {
+ inherit_from => [ "linux-aarch64", "openwrt" ],
+ },
+ "linux-arc-openwrt" => {
+ inherit_from => [ "linux-generic32", "openwrt" ],
+ },
+ "linux-arm-openwrt" => {
+ inherit_from => [ "linux-armv4", "openwrt" ],
+ },
+ "linux-armeb-openwrt" => {
+ inherit_from => [ "linux-armv4", "openwrt" ],
+ },
+ "linux-i386-openwrt" => {
+ inherit_from => [ "linux-x86", "openwrt" ],
+ },
+ "linux-mips-openwrt" => {
+ inherit_from => [ "linux-mips32", "openwrt" ],
+ },
+ "linux-mips64-openwrt" => {
+ inherit_from => [ "linux64-mips64", "openwrt" ],
+ },
+ "linux-mips64el-openwrt" => {
+ inherit_from => [ "linux64-mips64", "openwrt" ],
+ },
+ "linux-mipsel-openwrt" => {
+ inherit_from => [ "linux-mips32", "openwrt" ],
+ },
+ "linux-powerpc-openwrt" => {
+ inherit_from => [ "linux-ppc", "openwrt" ],
+ },
+ "linux-x86_64-openwrt" => {
+ inherit_from => [ "linux-x86_64", "openwrt" ],
+ },
+
+### Basic default option
+ "linux-generic32-openwrt" => {
+ inherit_from => [ "linux-generic32", "openwrt" ],
+ },
+);

View File

@@ -0,0 +1,23 @@
From 4ad8f2fe6bf3b91df7904fcbe960e5fdfca36336 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
Date: Thu, 27 Sep 2018 08:31:38 -0300
Subject: Avoid exposing build directories
The CFLAGS contain the build directories, and are shown by calling
OpenSSL_version(OPENSSL_CFLAGS), or running openssl version -a
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
diff --git a/crypto/build.info b/crypto/build.info
index 2c619c62e8..893128345a 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -10,7 +10,7 @@ EXTRA= ../ms/uplink-x86.pl ../ms/uplink.c ../ms/applink.c \
ppccpuid.pl pariscid.pl alphacpuid.pl arm64cpuid.pl armv4cpuid.pl
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%,$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q))" "$(PLATFORM)"
DEPEND[buildinf.h]=../configdata.pm
GENERATE[uplink-x86.s]=../ms/uplink-x86.pl $(PERLASM_SCHEME)

View File

@@ -0,0 +1,31 @@
From ba2fe646f2d9104a18b066e43582154049e9ffcb Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@yahoo.com>
diff --git a/Configure b/Configure
index 74d057c219..5813e9f8fe 100755
--- a/Configure
+++ b/Configure
@@ -318,7 +318,7 @@ my $auto_threads=1; # enable threads automatically? true by default
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);

View File

@@ -0,0 +1,82 @@
From 4f7ab2040bb71f03a8f8388911144559aa2a5b60 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@yahoo.com>
Date: Thu, 27 Sep 2018 08:44:39 -0300
Subject: Add OPENSSL_PREFER_CHACHA_OVER_GCM option
This enables a compile-time option to prefer ChaCha20-Poly1305 over
AES-GCM in the openssl default ciphersuite, which is useful in systems
without AES specific CPU instructions.
OPENSSL_PREFER_CHACHA_OVER_GCM must be defined to enable it.
Note that this does not have the same effect as the
SL_OP_PRIORITIZE_CHACHA option, which prioritizes ChaCha20-Poly1305 only
when the client has it on top of its ciphersuite preference.
Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 6724ccf2d2..96d959427e 100644
--- 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"
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 27a1b2ec68..7039811323 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1467,11 +1467,29 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,
&tail);
+ /*
+ * If OPENSSL_PREFER_CHACHA_OVER_GCM is defined, ChaCha20_Poly1305
+ * will be placed before AES-256. Otherwise, the default behavior of
+ * preferring GCM over CHACHA is used.
+ * This is useful for systems that do not have AES-specific CPU
+ * instructions, where ChaCha20-Poly1305 is 3 times faster than AES.
+ * Note that this does not have the same effect as the SSL_OP_PRIORITIZE_CHACHA
+ * option, which prioritizes ChaCha20-Poly1305 only when the client has it on top
+ * of its ciphersuite preference.
+ */
+
+#ifdef OPENSSL_PREFER_CHACHA_OVER_GCM
+ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
+ &head, &tail);
+#else
/* Within each strength group, we prefer GCM over CHACHA... */
ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
&head, &tail);
ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
&head, &tail);
+#endif
/*
* ...and generally, our preferred cipher is AES.
@@ -1527,7 +1545,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
* Within each group, ciphers remain sorted by strength and previous
* preference, i.e.,
* 1) ECDHE > DHE
- * 2) GCM > CHACHA
+ * 2) GCM > CHACHA, reversed if OPENSSL_PREFER_CHACHA_OVER_GCM is defined
* 3) AES > rest
* 4) TLS 1.2 > legacy
*

View File

@@ -0,0 +1,85 @@
--- a/apps/openssl.cnf
+++ b/apps/openssl.cnf
@@ -22,6 +22,82 @@ oid_section = new_oids
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
+openssl_conf=openssl_conf
+
+[openssl_conf]
+engines=engines
+
+[engines]
+# To enable an engine, install the package, and uncomment it here:
+#devcrypto=devcrypto
+#afalg=afalg
+#padlock=padlock
+
+[afalg]
+# Leave this alone and configure algorithms with CIPERS/DIGESTS below
+default_algorithms = ALL
+
+# The following commands are only available if using the alternative
+# (sync) AFALG engine
+# Configuration commands:
+# Run 'openssl engine -t -c -vv -pre DUMP_INFO devcrypto' to see a
+# list of supported algorithms, along with their driver, whether they
+# are hw accelerated or not, and the engine's configuration commands.
+
+# USE_SOFTDRIVERS: specifies whether to use software (not accelerated)
+# drivers (0=use only accelerated drivers, 1=allow all drivers, 2=use
+# if acceleration can't be determined) [default=2]
+#USE_SOFTDRIVERS = 2
+
+# CIPHERS: either ALL, NONE, NO_ECB (all except ECB-mode) or a
+# comma-separated list of ciphers to enable [default=NO_ECB]
+# Starting in 1.2.0, if you use a cipher list, each cipher may be
+# followed by a colon (:) and the minimum request length to use
+# AF_ALG drivers for that cipher; smaller requests are processed by
+# softare; a negative value will use the default for that cipher
+#CIPHERS=AES-128-CBC:1024, AES-256-CBC:768, DES-EDE3-CBC:0
+
+# DIGESTS: either ALL, NONE, or a comma-separated list of digests to
+# enable [default=NONE]
+# It is strongly recommended not to enable digests; their performance
+# is poor, and there are many cases in which they will not work,
+# especially when calling fork with open crypto contexts. Openssh,
+# for example, does this, and you may not be able to login.
+#DIGESTS = NONE
+
+[devcrypto]
+# Leave this alone and configure algorithms with CIPERS/DIGESTS below
+default_algorithms = ALL
+
+# Configuration commands:
+# Run 'openssl engine -t -c -vv -pre DUMP_INFO devcrypto' to see a
+# list of supported algorithms, along with their driver, whether they
+# are hw accelerated or not, and the engine's configuration commands.
+
+# USE_SOFTDRIVERS: specifies whether to use software (not accelerated)
+# drivers (0=use only accelerated drivers, 1=allow all drivers, 2=use
+# if acceleration can't be determined) [default=2]
+#USE_SOFTDRIVERS = 2
+
+# CIPHERS: either ALL, NONE, or a comma-separated list of ciphers to
+# enable [default=ALL]
+# It is recommended to disable the ECB ciphers; in most cases, it will
+# only be used for PRNG, in small blocks, where performance is poor,
+# and there may be problems with apps forking with open crypto
+# contexts, leading to failures. The CBC ciphers work well:
+#CIPHERS=DES-CBC, DES-EDE3-CBC, AES-128-CBC, AES-192-CBC, AES-256-CBC
+
+# DIGESTS: either ALL, NONE, or a comma-separated list of digests to
+# enable [default=NONE]
+# It is strongly recommended not to enable digests; their performance
+# is poor, and there are many cases in which they will not work,
+# especially when calling fork with open crypto contexts. Openssh,
+# for example, does this, and you may not be able to login.
+#DIGESTS = NONE
+
+[padlock]
+default_algorithms = ALL
+
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.

View File

@@ -0,0 +1,60 @@
From f14345422747a495a52f9237a43b8be189f21912 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@yahoo.com>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Richard Levitte <levitte@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 a727c6f646..a2c9a966f7 100644
--- 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, 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)
@@ -579,7 +583,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;
}

View File

@@ -0,0 +1,569 @@
From 1c2fabcdb34e436286b4a8760cfbfbff11ea551a Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@yahoo.com>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Richard Levitte <levitte@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 a2c9a966f7..5ec38ca8f3 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>
@@ -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 *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, 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
@@ -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_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)
@@ -630,52 +751,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],
@@ -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,8 +909,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
@@ -793,6 +1109,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

View File

@@ -0,0 +1,275 @@
From 78e7b1cc7119622645bc5a8542c55b6c95dc7868 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@yahoo.com>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Richard Levitte <levitte@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 5ec38ca8f3..64dc6b891d 100644
--- a/crypto/engine/eng_devcrypto.c
+++ b/crypto/engine/eng_devcrypto.c
@@ -50,16 +50,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) {
@@ -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(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,
@@ -550,6 +562,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
@@ -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(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,
@@ -939,6 +993,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
/******************************************************************************
@@ -983,6 +1074,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}
};
@@ -1051,6 +1147,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;
}

View File

@@ -0,0 +1,348 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@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 1b0d523bea..ee3e2eb075 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -329,18 +329,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;
@@ -365,6 +353,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)
@@ -713,11 +713,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))
@@ -727,6 +722,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 1db771971c..33a25d7004 100644
--- 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
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 2c1b52d572..eff1ed3a7d 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>
@@ -31,18 +31,20 @@
# 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
@@ -1058,7 +1060,7 @@ static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
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) "]",
+ OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]",
ENGINE_CMD_FLAG_NUMERIC},
#endif
@@ -1166,32 +1168,22 @@ static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
*
*****/
-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.
+ * Opens /dev/crypto
*/
-void engine_load_devcrypto_int()
+static int open_devcrypto(void)
{
- ENGINE *e = NULL;
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;
+ return 0;
}
#ifdef CRIOGET
@@ -1199,35 +1191,61 @@ void engine_load_devcrypto_int()
fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno));
close(fd);
cfd = -1;
- return;
+ return 0;
}
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;
+ 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;
+}
- prepare_cipher_methods();
+static int devcrypto_unload(ENGINE *e)
+{
+ destroy_all_cipher_methods();
#ifdef IMPLEMENT_DIGEST
- prepare_digest_methods();
+ destroy_all_digest_methods();
#endif
- if (!ENGINE_set_id(e, "devcrypto")
+ 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)
+ || !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
@@ -1250,23 +1268,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;
}
@@ -1275,3 +1306,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

View File

@@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@yahoo.com>
diff --git a/engines/e_devcrypto.c b/engines/e_devcrypto.c
index 3fcd81de7a..d25230d366 100644
--- 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_cmds[] = {
#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

View File

@@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eneas U de Queiroz <cote2004-github@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@yahoo.com>
diff --git a/engines/e_devcrypto.c b/engines/e_devcrypto.c
index d25230d366..f4570f1666 100644
--- a/engines/e_devcrypto.c
+++ b/engines/e_devcrypto.c
@@ -195,9 +195,8 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
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;