mirror of
https://github.com/openssl/openssl.git
synced 2024-12-15 06:01:37 +08:00
f928304a9d
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: 79040cf29e
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25576)
162 lines
5.1 KiB
C
162 lines
5.1 KiB
C
/*
|
|
* Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include "crypto/bn.h"
|
|
#include "crypto/s390x_arch.h"
|
|
|
|
#ifdef S390X_MOD_EXP
|
|
|
|
# include <sys/types.h>
|
|
# include <sys/stat.h>
|
|
# include <fcntl.h>
|
|
# include <asm/zcrypt.h>
|
|
# include <sys/ioctl.h>
|
|
# include <unistd.h>
|
|
# include <errno.h>
|
|
|
|
static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
|
const BIGNUM *m)
|
|
{
|
|
struct ica_rsa_modexpo me;
|
|
unsigned char *buffer;
|
|
size_t size;
|
|
int res = 0;
|
|
|
|
if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev)
|
|
return 0;
|
|
size = BN_num_bytes(m);
|
|
buffer = OPENSSL_zalloc(4 * size);
|
|
if (buffer == NULL)
|
|
return 0;
|
|
me.inputdata = buffer;
|
|
me.inputdatalength = size;
|
|
me.outputdata = buffer + size;
|
|
me.outputdatalength = size;
|
|
me.b_key = buffer + 2 * size;
|
|
me.n_modulus = buffer + 3 * size;
|
|
if (BN_bn2binpad(a, me.inputdata, size) == -1
|
|
|| BN_bn2binpad(p, me.b_key, size) == -1
|
|
|| BN_bn2binpad(m, me.n_modulus, size) == -1)
|
|
goto dealloc;
|
|
if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) != -1) {
|
|
if (BN_bin2bn(me.outputdata, size, r) != NULL)
|
|
res = 1;
|
|
} 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);
|
|
return res;
|
|
}
|
|
|
|
int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
|
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
|
|
{
|
|
if (s390x_mod_exp_hw(r, a, p, m) == 1)
|
|
return 1;
|
|
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
|
}
|
|
|
|
int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
|
|
const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
|
|
{
|
|
struct ica_rsa_modexpo_crt crt;
|
|
unsigned char *buffer, *part;
|
|
size_t size, plen, qlen;
|
|
int res = 0;
|
|
|
|
if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev)
|
|
return 0;
|
|
/*-
|
|
* Hardware-accelerated CRT can only deal with p>q. Fall back to
|
|
* software in the (hopefully rare) other cases.
|
|
*/
|
|
if (BN_ucmp(p, q) != 1)
|
|
return 0;
|
|
plen = BN_num_bytes(p);
|
|
qlen = BN_num_bytes(q);
|
|
size = (plen > qlen ? plen : qlen);
|
|
buffer = OPENSSL_zalloc(9 * size + 24);
|
|
if (buffer == NULL)
|
|
return 0;
|
|
part = buffer;
|
|
crt.inputdata = part;
|
|
crt.inputdatalength = 2 * size;
|
|
part += 2 * size;
|
|
crt.outputdata = part;
|
|
crt.outputdatalength = 2 * size;
|
|
part += 2 * size;
|
|
crt.bp_key = part;
|
|
part += size + 8;
|
|
crt.bq_key = part;
|
|
part += size;
|
|
crt.np_prime = part;
|
|
part += size + 8;
|
|
crt.nq_prime = part;
|
|
part += size;
|
|
crt.u_mult_inv = part;
|
|
if (BN_bn2binpad(i, crt.inputdata, crt.inputdatalength) == -1
|
|
|| BN_bn2binpad(p, crt.np_prime, size + 8) == -1
|
|
|| BN_bn2binpad(q, crt.nq_prime, size) == -1
|
|
|| BN_bn2binpad(dmp, crt.bp_key, size + 8) == -1
|
|
|| BN_bn2binpad(dmq, crt.bq_key, size) == -1
|
|
|| BN_bn2binpad(iqmp, crt.u_mult_inv, size + 8) == -1)
|
|
goto dealloc;
|
|
if (ioctl(OPENSSL_s390xcex, ICARSACRT, &crt) != -1) {
|
|
if (BN_bin2bn(crt.outputdata, crt.outputdatalength, r) != NULL)
|
|
res = 1;
|
|
} 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);
|
|
return res;
|
|
}
|
|
|
|
#else
|
|
int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
|
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
|
|
{
|
|
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
|
}
|
|
|
|
int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
|
|
const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif
|