From: Ingo Franzki Date: Thu, 26 Sep 2024 13:56:47 +0000 (+0200) Subject: s390x: Don't probe crypto cards for ME/CRT offloading during initialization X-Git-Tag: openssl-3.3.3~139 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dd2f524010c1ca595d28e6fb8eb17f21dc9e427;p=thirdparty%2Fopenssl.git s390x: Don't probe crypto cards for ME/CRT offloading during initialization Probing for crypto cards during initialization by issuing an ioctl to the zcrypt device driver can cause a lot of traffic and overhead, because it runs for each and every application that uses OpenSSL, regardless if that application will later perform ME or CRT operations or not. Fix this by performing no probing during initialization, but detect the crypto card availability only at the first ME/CRT operation that is subject to be offloaded. If the ioctl returns ENODEV, then no suitable crypto card is available in the system, and we disable further offloading attempts by setting flag OPENSSL_s390xcex_nodev to 1. Setting the global flag OPENSSL_s390xcex_nodev in case of ENODEV is intentionally not made in a thread save manner, because the only thing that could happen is that another thread, that misses the flag update, also issues an ioctl and gets ENODEV as well. The file descriptor is not closed in such error cases, because this could cause raise conditions where we would close a foreign file if the same file descriptor got reused by another thread. The file descriptor is finally closed during termination by the atexit handler. In case the ioctl returns ENOTTY then this indicates that the file descriptor was closed (e.g. by a sandbox), but in the meantime the same file descriptor has been reused for another file. Do not use the file descriptor anymore, and also do not close it during termination. Fixes: https://github.com/openssl/openssl/commit/79040cf29e011c21789563d74da626b7465a0540 Signed-off-by: Ingo Franzki Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/25576) (cherry picked from commit f928304a9db3772a6047462599384fb57d878ccb) --- diff --git a/crypto/bn/bn_s390x.c b/crypto/bn/bn_s390x.c index 5449143f4f0..0b60f4ec1d9 100644 --- a/crypto/bn/bn_s390x.c +++ b/crypto/bn/bn_s390x.c @@ -28,7 +28,7 @@ static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, size_t size; int res = 0; - if (OPENSSL_s390xcex == -1) + if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev) return 0; size = BN_num_bytes(m); buffer = OPENSSL_zalloc(4 * size); @@ -47,12 +47,21 @@ static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) != -1) { if (BN_bin2bn(me.outputdata, size, r) != NULL) res = 1; - } else if (errno == EBADF) { - /*- + } else if (errno == EBADF || errno == ENOTTY) { + /* * In this cases, someone (e.g. a sandbox) closed the fd. * Make sure to not further use this hardware acceleration. + * In case of ENOTTY the file descriptor was already reused for another + * file. Do not attempt to use or close that file descriptor anymore. */ OPENSSL_s390xcex = -1; + } else if (errno == ENODEV) { + /* + * No crypto card(s) available to handle RSA requests. + * Make sure to not further use this hardware acceleration, + * but do not close the file descriptor. + */ + OPENSSL_s390xcex_nodev = 1; } dealloc: OPENSSL_clear_free(buffer, 4 * size); @@ -75,7 +84,7 @@ int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q, size_t size, plen, qlen; int res = 0; - if (OPENSSL_s390xcex == -1) + if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev) return 0; /*- * Hardware-accelerated CRT can only deal with p>q. Fall back to @@ -115,12 +124,21 @@ int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q, if (ioctl(OPENSSL_s390xcex, ICARSACRT, &crt) != -1) { if (BN_bin2bn(crt.outputdata, crt.outputdatalength, r) != NULL) res = 1; - } else if (errno == EBADF) { - /*- + } else if (errno == EBADF || errno == ENOTTY) { + /* * In this cases, someone (e.g. a sandbox) closed the fd. * Make sure to not further use this hardware acceleration. + * In case of ENOTTY the file descriptor was already reused for another + * file. Do not attempt to use or close that file descriptor anymore. */ OPENSSL_s390xcex = -1; + } else if (errno == ENODEV) { + /* + * No crypto card(s) available to handle RSA requests. + * Make sure to not further use this hardware acceleration, + * but do not close the file descriptor. + */ + OPENSSL_s390xcex_nodev = 1; } dealloc: OPENSSL_clear_free(buffer, 9 * size + 24); diff --git a/crypto/s390x_arch.h b/crypto/s390x_arch.h index fdc682af06b..6ac40b92fbb 100644 --- a/crypto/s390x_arch.h +++ b/crypto/s390x_arch.h @@ -74,17 +74,21 @@ struct OPENSSL_s390xcap_st { unsigned long long kdsa[2]; }; -#if defined(__GNUC__) && defined(__linux) -__attribute__ ((visibility("hidden"))) -#endif +# if defined(__GNUC__) && defined(__linux) +__attribute__((visibility("hidden"))) +# endif extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; -#ifdef S390X_MOD_EXP -# if defined(__GNUC__) && defined(__linux) -__attribute__ ((visibility("hidden"))) -# endif +# ifdef S390X_MOD_EXP +# if defined(__GNUC__) && defined(__linux) +__attribute__((visibility("hidden"))) +# endif extern int OPENSSL_s390xcex; -#endif +# if defined(__GNUC__) && defined(__linux) +__attribute__((visibility("hidden"))) +# endif +extern int OPENSSL_s390xcex_nodev; +# endif /* Max number of 64-bit words currently returned by STFLE */ # define S390X_STFLE_MAX 3 diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index 7721b5c801a..82b2654fb59 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -86,8 +86,8 @@ void OPENSSL_s390x_functions(void); struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; #ifdef S390X_MOD_EXP -static int probe_cex(void); int OPENSSL_s390xcex; +int OPENSSL_s390xcex_nodev; #if defined(__GNUC__) __attribute__ ((visibility("hidden"))) @@ -217,45 +217,12 @@ void OPENSSL_cpuid_setup(void) OPENSSL_s390xcex = -1; } else { OPENSSL_s390xcex = open("/dev/z90crypt", O_RDWR | O_CLOEXEC); - if (probe_cex() == 1) - OPENSSL_atexit(OPENSSL_s390x_cleanup); + OPENSSL_atexit(OPENSSL_s390x_cleanup); } + OPENSSL_s390xcex_nodev = 0; #endif } -#ifdef S390X_MOD_EXP -static int probe_cex(void) -{ - struct ica_rsa_modexpo me; - const unsigned char inval[16] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,2 - }; - const unsigned char modulus[16] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,3 - }; - unsigned char res[16]; - int olderrno; - int rc = 1; - - me.inputdata = (unsigned char *)inval; - me.inputdatalength = sizeof(inval); - me.outputdata = (unsigned char *)res; - me.outputdatalength = sizeof(res); - me.b_key = (unsigned char *)inval; - me.n_modulus = (unsigned char *)modulus; - olderrno = errno; - if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) == -1) { - (void)close(OPENSSL_s390xcex); - OPENSSL_s390xcex = -1; - rc = 0; - } - errno = olderrno; - return rc; -} -#endif - static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex) { /*-