Skip to content

Commit

Permalink
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/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()
  • Loading branch information
Linus Torvalds committed Apr 25, 2016
2 parents 02da2d7 + 340ff60 commit bcc981e
Showing 1 changed file with 57 additions and 30 deletions.
87 changes: 57 additions & 30 deletions drivers/crypto/talitos.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

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,
bool is_sec1)
{
Expand Down Expand Up @@ -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,
(areq->src == areq->dst) ? DMA_BIDIRECTIONAL
: DMA_TO_DEVICE);

/* hmac data */
desc->ptr[1].len = cpu_to_be16(areq->assoclen);
if (sg_count > 1 &&
(ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
areq->assoclen,
&edesc->link_tbl[tbl_off])) > 1) {
tbl_off += ret;

to_talitos_ptr(&desc->ptr[1], edesc->dma_link_tbl + tbl_off *
sizeof(struct talitos_ptr), 0);
desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;

dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len, DMA_BIDIRECTIONAL);

tbl_off += ret;
} else {
to_talitos_ptr(&desc->ptr[1], sg_dma_address(areq->src), 0);
desc->ptr[1].j_extent = 0;
Expand Down Expand Up @@ -1126,20 +1133,24 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
sg_link_tbl_len += authsize;

if (sg_count > 1 &&
(ret = sg_to_link_tbl_offset(areq->src, sg_count, areq->assoclen,
sg_link_tbl_len,
&edesc->link_tbl[tbl_off])) > 1) {
tbl_off += ret;
if (sg_count == 1) {
to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src) +
areq->assoclen, 0);
} else if ((ret = sg_to_link_tbl_offset(areq->src, sg_count,
areq->assoclen, sg_link_tbl_len,
&edesc->link_tbl[tbl_off])) >
1) {
desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl +
tbl_off *
sizeof(struct talitos_ptr), 0);
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
edesc->dma_len,
DMA_BIDIRECTIONAL);
} else
to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src), 0);
tbl_off += ret;
} else {
copy_talitos_ptr(&desc->ptr[4], &edesc->link_tbl[tbl_off], 0);
}

/* cipher out */
desc->ptr[5].len = cpu_to_be16(cryptlen);
Expand All @@ -1151,11 +1162,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,

edesc->icv_ool = false;

if (sg_count > 1 &&
(sg_count = sg_to_link_tbl_offset(areq->dst, sg_count,
if (sg_count == 1) {
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,
&edesc->link_tbl[tbl_off])) >
1) {
&edesc->link_tbl[tbl_off])) > 1) {
struct talitos_ptr *tbl_ptr = &edesc->link_tbl[tbl_off];

to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
Expand All @@ -1178,8 +1191,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
edesc->dma_len, DMA_BIDIRECTIONAL);

edesc->icv_ool = true;
} else
to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst), 0);
} else {
copy_talitos_ptr(&desc->ptr[5], &edesc->link_tbl[tbl_off], 0);
}

/* iv out */
map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv,
Expand Down Expand Up @@ -2629,21 +2643,11 @@ struct talitos_crypto_alg {
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;

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 */
ctx->dev = talitos_alg->dev;

Expand All @@ -2661,10 +2665,33 @@ static int talitos_cra_init(struct crypto_tfm *tfm)
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)
{
talitos_cra_init(crypto_aead_tfm(tfm));
return 0;
struct aead_alg *alg = crypto_aead_alg(tfm);
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)
Expand Down

0 comments on commit bcc981e

Please sign in to comment.