diff --git a/crypto/bn/bn_s390x.c b/crypto/bn/bn_s390x.c index 5449143f4f..0b60f4ec1d 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 2bb82347ff..e8830b7eed 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 7721b5c801..82b2654fb5 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) { /*-