diff options
author | Cristian Stoica <cristian.stoica@freescale.com> | 2014-09-23 09:27:57 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:41:00 (GMT) |
commit | 009d79e4e946ab963d70f93b7dfe74e568d3ff8f (patch) | |
tree | 3d934ed41f193780fc56833d817114c9af8208ce | |
parent | 566ac91003c8a14f034b4e5a9bb92f7f8dec84aa (diff) | |
download | linux-fsl-qoriq-009d79e4e946ab963d70f93b7dfe74e568d3ff8f.tar.xz |
crypto: caam: fix array out of bound access
All arrays in question have six elements but the index is seven bits
wide. Make sure the index is bound by ARRAY_SIZE to avoid incorrect
memory accesses
Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
Change-Id: Ic1a65f55e9aa76dc7828021010bac8ebac75b565
Reviewed-on: http://git.am.freescale.net:8181/19802
Reviewed-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com>
Reviewed-by: Mircea Pop <mircea.pop@freescale.com>
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Matthew Weigel <Matthew.Weigel@freescale.com>
-rw-r--r-- | drivers/crypto/caam/caamalg.c | 18 | ||||
-rw-r--r-- | drivers/crypto/caam/caamalg_qi.c | 18 | ||||
-rw-r--r-- | drivers/crypto/caam/caamhash.c | 14 |
3 files changed, 40 insertions, 10 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index c9ca243..0e1ad31 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -3445,6 +3445,7 @@ static int caam_cra_init(struct crypto_tfm *tfm) SHA384_DIGEST_SIZE, SHA512_DIGEST_SIZE }; + u8 op_id; ctx->jrdev = caam_jr_alloc(); if (IS_ERR(ctx->jrdev)) { @@ -3461,11 +3462,20 @@ static int caam_cra_init(struct crypto_tfm *tfm) * Need authsize, in case setauthsize callback not called * by upper layer (e.g. TLS). */ - if (caam_alg->alg_op) - ctx->authsize = digest_size[(ctx->alg_op & - OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT]; - else + if (caam_alg->alg_op) { + op_id = (ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) + >> OP_ALG_ALGSEL_SHIFT; + if (op_id < ARRAY_SIZE(digest_size)) { + ctx->authsize = digest_size[op_id]; + } else { + dev_err(ctx->jrdev, "incorrect op_id %d; must be less than %d\n", + op_id, ARRAY_SIZE(digest_size)); + caam_jr_free(ctx->jrdev); + return -EINVAL; + } + } else { ctx->authsize = 0; + } return 0; } diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index aa0423a..4334f82 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -2109,6 +2109,7 @@ static int caam_cra_init(struct crypto_tfm *tfm) SHA384_DIGEST_SIZE, SHA512_DIGEST_SIZE }; + u8 op_id; /* * distribute tfms across job rings to ensure in-order @@ -2129,11 +2130,20 @@ static int caam_cra_init(struct crypto_tfm *tfm) * Need authsize, in case setauthsize callback not called * by upper layer (e.g. TLS). */ - if (caam_alg->alg_op) - ctx->authsize = digest_size[(ctx->alg_op & - OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT]; - else + if (caam_alg->alg_op) { + op_id = (ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) + >> OP_ALG_ALGSEL_SHIFT; + if (op_id < ARRAY_SIZE(digest_size)) { + ctx->authsize = digest_size[op_id]; + } else { + dev_err(ctx->jrdev, "incorrect op_id %d; must be less than %d\n", + op_id, ARRAY_SIZE(digest_size)); + caam_jr_free(ctx->jrdev); + return -EINVAL; + } + } else { ctx->authsize = 0; + } ctx->qidev = priv->qidev; diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index 2f3ae99..edd2124 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -1765,6 +1765,7 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) HASH_MSG_LEN + 64, HASH_MSG_LEN + SHA512_DIGEST_SIZE }; int ret = 0; + u8 op_id; /* * Get a Job ring from Job Ring driver to ensure in-order @@ -1779,14 +1780,23 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm) ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type; ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_hash->alg_op; - ctx->ctx_len = runninglen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> - OP_ALG_ALGSEL_SHIFT]; + op_id = (ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT; + if (op_id >= ARRAY_SIZE(runninglen)) { + dev_err(ctx->jrdev, "incorrect op_id %d; must be less than %d\n", + op_id, ARRAY_SIZE(runninglen)); + ret = -EINVAL; + goto out_err; + } + ctx->ctx_len = runninglen[op_id]; crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct caam_hash_state)); ret = ahash_set_sh_desc(ahash); + return ret; +out_err: + caam_jr_free(ctx->jrdev); return ret; } |