Commit 278d737c authored by Herbert Xu's avatar Herbert Xu
Browse files

crypto: aspeed/hash - Move final padding into dma_prepare



Rather than processing a final as two separate updates, combine
them into one for the linear dma_prepare case.

This means that the total hash size is slightly reduced, but that
will be fixed up later by repeating the hash if necessary.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 879203de
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -114,27 +114,32 @@ static int aspeed_ahash_dma_prepare(struct aspeed_hace_dev *hace_dev)
	struct aspeed_engine_hash *hash_engine = &hace_dev->hash_engine;
	struct ahash_request *req = hash_engine->req;
	struct aspeed_sham_reqctx *rctx = ahash_request_ctx(req);
	int length, remain;
	bool final = rctx->flags & SHA_FLAGS_FINUP;
	unsigned int length, remain;

	length = rctx->total + rctx->bufcnt;
	remain = length % rctx->block_size;
	remain = final ? 0 : length % rctx->block_size;

	AHASH_DBG(hace_dev, "length:0x%x, remain:0x%x\n", length, remain);

	if (rctx->bufcnt)
		memcpy(hash_engine->ahash_src_addr, rctx->buffer, rctx->bufcnt);

	if (rctx->total + rctx->bufcnt < ASPEED_CRYPTO_SRC_DMA_BUF_LEN) {
	if ((final ? round_up(length, rctx->block_size) + rctx->block_size :
		     length) > ASPEED_CRYPTO_SRC_DMA_BUF_LEN) {
		dev_warn(hace_dev->dev, "Hash data length is too large\n");
		return -EINVAL;
	}

	scatterwalk_map_and_copy(hash_engine->ahash_src_addr +
				 rctx->bufcnt, rctx->src_sg,
				 rctx->offset, rctx->total - remain, 0);
	rctx->offset += rctx->total - remain;

	} else {
		dev_warn(hace_dev->dev, "Hash data length is too large\n");
		return -EINVAL;
	}

	if (final)
		length += aspeed_ahash_fill_padding(
			hace_dev, rctx, hash_engine->ahash_src_addr + length);
	else
		scatterwalk_map_and_copy(rctx->buffer, rctx->src_sg,
					 rctx->offset, remain, 0);

@@ -423,7 +428,7 @@ static int aspeed_ahash_update_resume(struct aspeed_hace_dev *hace_dev)
			 SHA512_DIGEST_SIZE, DMA_BIDIRECTIONAL);

	if (rctx->flags & SHA_FLAGS_FINUP)
		return aspeed_ahash_req_final(hace_dev);
		memcpy(req->result, rctx->digest, rctx->digsize);

	return aspeed_ahash_complete(hace_dev);
}