Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcc981e9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+57 −30
Original line number Diff line number Diff line
@@ -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)
{
@@ -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;
@@ -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)
		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 *
@@ -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,
					   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);
@@ -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 +
@@ -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,
@@ -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;

@@ -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)