Commit bcc981e9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto fixes from Herbert Xu:
 "This fixes a couple of regressions in the talitos driver that were
  introduced back in 4.3.

  The first bug causes a crash when the driver's AEAD functionality is
  used while the second bug prevents its AEAD feature from working once
  you get past the first bug"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: talitos - fix AEAD tcrypt tests
  crypto: talitos - fix crash in talitos_cra_init()
parents 02da2d72 340ff60a
...@@ -63,6 +63,14 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr, ...@@ -63,6 +63,14 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
ptr->eptr = upper_32_bits(dma_addr); ptr->eptr = upper_32_bits(dma_addr);
} }
static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
struct talitos_ptr *src_ptr, bool is_sec1)
{
dst_ptr->ptr = src_ptr->ptr;
if (!is_sec1)
dst_ptr->eptr = src_ptr->eptr;
}
static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len, static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
bool is_sec1) bool is_sec1)
{ {
...@@ -1083,21 +1091,20 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ...@@ -1083,21 +1091,20 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1, sg_count = dma_map_sg(dev, areq->src, edesc->src_nents ?: 1,
(areq->src == areq->dst) ? DMA_BIDIRECTIONAL (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
: DMA_TO_DEVICE); : DMA_TO_DEVICE);
/* hmac data */ /* hmac data */
desc->ptr[1].len = cpu_to_be16(areq->assoclen); desc->ptr[1].len = cpu_to_be16(areq->assoclen);
if (sg_count > 1 && if (sg_count > 1 &&
(ret = sg_to_link_tbl_offset(areq->src, sg_count, 0, (ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
areq->assoclen, areq->assoclen,
&edesc->link_tbl[tbl_off])) > 1) { &edesc->link_tbl[tbl_off])) > 1) {
tbl_off += ret;
to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off * to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off *
sizeof(struct talitos_ptr), 0); sizeof(struct talitos_ptr), 0);
desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP; desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
dma_sync_single_for_device(dev, edesc->dma_link_tbl, dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL); edesc->dma_len, DMA_BIDIRECTIONAL);
tbl_off += ret;
} else { } else {
to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0); to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0);
desc->ptr[1].j_extent = 0; desc->ptr[1].j_extent = 0;
...@@ -1126,11 +1133,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ...@@ -1126,11 +1133,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV) if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
sg_link_tbl_len += authsize; sg_link_tbl_len += authsize;
if (sg_count > 1 && if (sg_count == 1) {
(ret = sg_to_link_tbl_offset(areq->src, sg_count, areq->assoclen, to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src) +
sg_link_tbl_len, areq->assoclen, 0);
&edesc->link_tbl[tbl_off])) > 1) { } else if ((ret = sg_to_link_tbl_offset(areq->src, sg_count,
tbl_off += ret; areq->assoclen, sg_link_tbl_len,
&edesc->link_tbl[tbl_off])) >
1) {
desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl + to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl +
tbl_off * tbl_off *
...@@ -1138,8 +1147,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ...@@ -1138,8 +1147,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
dma_sync_single_for_device(dev, edesc->dma_link_tbl, dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, edesc->dma_len,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
} else tbl_off += ret;
to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src), 0); } else {
copy_talitos_ptr(&desc->ptr[4], &edesc->link_tbl[tbl_off], 0);
}
/* cipher out */ /* cipher out */
desc->ptr[5].len = cpu_to_be16(cryptlen); desc->ptr[5].len = cpu_to_be16(cryptlen);
...@@ -1151,11 +1162,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ...@@ -1151,11 +1162,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
edesc->icv_ool = false; edesc->icv_ool = false;
if (sg_count > 1 && if (sg_count == 1) {
(sg_count = sg_to_link_tbl_offset(areq->dst, sg_count, to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst) +
areq->assoclen, 0);
} else if ((sg_count =
sg_to_link_tbl_offset(areq->dst, sg_count,
areq->assoclen, cryptlen, areq->assoclen, cryptlen,
&edesc->link_tbl[tbl_off])) > &edesc->link_tbl[tbl_off])) > 1) {
1) {
struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off]; struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];
to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl + to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
...@@ -1178,8 +1191,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq, ...@@ -1178,8 +1191,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
edesc->dma_len, DMA_BIDIRECTIONAL); edesc->dma_len, DMA_BIDIRECTIONAL);
edesc->icv_ool = true; edesc->icv_ool = true;
} else } else {
to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst), 0); copy_talitos_ptr(&desc->ptr[5], &edesc->link_tbl[tbl_off], 0);
}
/* iv out */ /* iv out */
map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
...@@ -2629,21 +2643,11 @@ struct talitos_crypto_alg { ...@@ -2629,21 +2643,11 @@ struct talitos_crypto_alg {
struct talitos_alg_template algt; struct talitos_alg_template algt;
}; };
static int talitos_cra_init(struct crypto_tfm *tfm) static int talitos_init_common(struct talitos_ctx *ctx,
struct talitos_crypto_alg *talitos_alg)
{ {
struct crypto_alg *alg = tfm->__crt_alg;
struct talitos_crypto_alg *talitos_alg;
struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
struct talitos_private *priv; struct talitos_private *priv;
if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
talitos_alg = container_of(__crypto_ahash_alg(alg),
struct talitos_crypto_alg,
algt.alg.hash);
else
talitos_alg = container_of(alg, struct talitos_crypto_alg,
algt.alg.crypto);
/* update context with ptr to dev */ /* update context with ptr to dev */
ctx->dev = talitos_alg->dev; ctx->dev = talitos_alg->dev;
...@@ -2661,10 +2665,33 @@ static int talitos_cra_init(struct crypto_tfm *tfm) ...@@ -2661,10 +2665,33 @@ static int talitos_cra_init(struct crypto_tfm *tfm)
return 0; return 0;
} }
static int talitos_cra_init(struct crypto_tfm *tfm)
{
struct crypto_alg *alg = tfm->__crt_alg;
struct talitos_crypto_alg *talitos_alg;
struct talitos_ctx *ctx = crypto_tfm_ctx(tfm);
if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH)
talitos_alg = container_of(__crypto_ahash_alg(alg),
struct talitos_crypto_alg,
algt.alg.hash);
else
talitos_alg = container_of(alg, struct talitos_crypto_alg,
algt.alg.crypto);
return talitos_init_common(ctx, talitos_alg);
}
static int talitos_cra_init_aead(struct crypto_aead *tfm) static int talitos_cra_init_aead(struct crypto_aead *tfm)
{ {
talitos_cra_init(crypto_aead_tfm(tfm)); struct aead_alg *alg = crypto_aead_alg(tfm);
return 0; struct talitos_crypto_alg *talitos_alg;
struct talitos_ctx *ctx = crypto_aead_ctx(tfm);
talitos_alg = container_of(alg, struct talitos_crypto_alg,
algt.alg.aead);
return talitos_init_common(ctx, talitos_alg);
} }
static int talitos_cra_init_ahash(struct crypto_tfm *tfm) static int talitos_cra_init_ahash(struct crypto_tfm *tfm)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment