Add upfront RSA modulus length validation and reject zero-length or unsupported modulus sizes. Validate CRT key component pointers and lengths, validate private exponent length, and derive the actual CRT key size from component lengths instead of relying solely on modulus size.
Also round up the half-modulus bound used for CRT parameters so odd-length moduli do not incorrectly reject valid factors. These checks ensure RSA key material fits within CNXK hardware limits, prevent invalid parameter acceptance, and avoid potential NULL pointer dereferences. Signed-off-by: Sucharitha Sarananaga <[email protected]> --- drivers/crypto/cnxk/cnxk_ae.h | 59 ++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h index f2aa5d5a2e..b94f5de769 100644 --- a/drivers/crypto/cnxk/cnxk_ae.h +++ b/drivers/crypto/cnxk/cnxk_ae.h @@ -19,6 +19,17 @@ #define CNXK_AE_EDDSA_MAX_PARAM_LEN 1024 +/* + * Maximum RSA modulus length (in bytes) supported by CNXK hardware. Must + * match CNXK_CPT_MAX_ASYM_OP_MOD_LEN in cnxk_cryptodev_ops.c and the + * modlen.max capability advertised in cnxk_cryptodev_capabilities.c. The + * per-op scratch buffer (CNXK_CPT_MAX_ASYM_OP_NUM_PARAMS * + * CNXK_CPT_MAX_ASYM_OP_MOD_LEN) that cnxk_ae_rsa_crt_prep()/ + * cnxk_ae_rsa_exp_prep() write into is sized against this limit, so RSA + * key material must be rejected up front if it exceeds it. + */ +#define CNXK_AE_RSA_MAX_MODLEN 1024 + struct cnxk_ae_sess { uint8_t rte_sess[ASYM_SESS_SIZE]; enum rte_crypto_asym_xform_type xfrm_type; @@ -135,23 +146,55 @@ cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess, size_t mod_len = xfrm_rsa->n.length; size_t exp_len = xfrm_rsa->e.length; uint64_t total_size; + size_t max_len; size_t len = 0; + /* Bound n/e against CNXK's RSA capability and require valid data, + * since they're used unconditionally below. + */ + if (mod_len > CNXK_AE_RSA_MAX_MODLEN || exp_len == 0 || exp_len > CNXK_AE_RSA_MAX_MODLEN || + xfrm_rsa->n.data == NULL || xfrm_rsa->e.data == NULL) + return -EINVAL; + /* Set private key type */ rsa->key_type = xfrm_rsa->key_type; if (rsa->key_type == RTE_RSA_KEY_TYPE_QT) { - if (qt.p.length != 0 && qt.p.data == NULL) + /* Round up so an odd-length modulus doesn't reject a legitimately + * sized factor (mod_len/2 alone truncates down). + */ + max_len = (mod_len + 1) / 2; + + /* + * Each quintuple component (q, dQ, p, dP, qInv) is independently + * caller-controlled and copied with its own length, so every one of + * them must be bounds-checked individually against mod_len/2 - + * relying on qt.p.length alone is not sufficient. + */ + if (qt.p.length == 0 || qt.p.length > max_len || qt.p.data == NULL || + qt.q.length == 0 || qt.q.length > max_len || qt.q.data == NULL || + qt.dP.length == 0 || qt.dP.length > max_len || qt.dP.data == NULL || + qt.dQ.length == 0 || qt.dQ.length > max_len || qt.dQ.data == NULL || + qt.qInv.length == 0 || qt.qInv.length > max_len || qt.qInv.data == NULL) return -EINVAL; - /* Make sure key length used is not more than mod_len/2 */ - if (qt.p.data != NULL) - len = (((mod_len / 2) < qt.p.length) ? 0 : qt.p.length * 5); + /* Total size is the actual sum of the quintuple component lengths */ + len = qt.q.length + qt.dQ.length + qt.p.length + qt.dP.length + qt.qInv.length; } else if (rsa->key_type == RTE_RSA_KEY_TYPE_EXP) { - if (d.length != 0 && d.data == NULL) + /* + * d is optional here: RTE_RSA_KEY_TYPE_EXP also covers + * public-only (encrypt/verify) transforms that supply just + * n/e, which cnxk_ae_rsa_prep() uses without ever reading d. + * When a private exponent is supplied, bound it and require + * its data. + */ + if (d.length > mod_len || (d.length != 0 && d.data == NULL)) return -EINVAL; len = d.length; + } else { + /* Reject unknown key_type instead of silently treating it as EXP. */ + return -EINVAL; } /* Total size required for RSA key params(n,e,(q,dQ,p,dP,qInv)) */ @@ -174,8 +217,7 @@ cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess, rsa->qt.dQ.data = rsa->qt.q.data + qt.q.length; memcpy(rsa->qt.dQ.data, qt.dQ.data, qt.dQ.length); rsa->qt.p.data = rsa->qt.dQ.data + qt.dQ.length; - if (qt.p.data != NULL) - memcpy(rsa->qt.p.data, qt.p.data, qt.p.length); + memcpy(rsa->qt.p.data, qt.p.data, qt.p.length); rsa->qt.dP.data = rsa->qt.p.data + qt.p.length; memcpy(rsa->qt.dP.data, qt.dP.data, qt.dP.length); rsa->qt.qInv.data = rsa->qt.dP.data + qt.dP.length; @@ -189,7 +231,8 @@ cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess, } else if (rsa->key_type == RTE_RSA_KEY_TYPE_EXP) { /* Private key in exponent format */ rsa->d.data = rsa->e.data + exp_len; - memcpy(rsa->d.data, d.data, d.length); + if (d.data != NULL) + memcpy(rsa->d.data, d.data, d.length); rsa->d.length = d.length; } rsa->n.length = mod_len; -- 2.54.0

