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

Commit 809778e0 authored by Antoine Tenart's avatar Antoine Tenart Committed by Herbert Xu
Browse files

crypto: inside-secure - fix hash when length is a multiple of a block



This patch fixes the hash support in the SafeXcel driver when the update
size is a multiple of a block size, and when a final call is made just
after with a size of 0. In such cases the driver should cache the last
block from the update to avoid handling 0 length data on the final call
(that's a hardware limitation).

Cc: stable@vger.kernel.org
Fixes: 1b44c5a6 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
Signed-off-by: default avatarAntoine Tenart <antoine.tenart@free-electrons.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c957f8b3
Loading
Loading
Loading
Loading
+24 −10
Original line number Original line Diff line number Diff line
@@ -189,17 +189,31 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
	else
	else
		cache_len = queued - areq->nbytes;
		cache_len = queued - areq->nbytes;


	/*
	if (!req->last_req) {
	 * If this is not the last request and the queued data does not fit
		/* If this is not the last request and the queued data does not
	 * into full blocks, cache it for the next send() call.
		 * fit into full blocks, cache it for the next send() call.
		 */
		 */
		extra = queued & (crypto_ahash_blocksize(ahash) - 1);
		extra = queued & (crypto_ahash_blocksize(ahash) - 1);
	if (!req->last_req && extra) {
		if (!extra)
			/* If this is not the last request and the queued data
			 * is a multiple of a block, cache the last one for now.
			 */
			extra = queued - crypto_ahash_blocksize(ahash);

		if (extra) {
			sg_pcopy_to_buffer(areq->src, sg_nents(areq->src),
			sg_pcopy_to_buffer(areq->src, sg_nents(areq->src),
				   req->cache_next, extra, areq->nbytes - extra);
					   req->cache_next, extra,
					   areq->nbytes - extra);


			queued -= extra;
			queued -= extra;
			len -= extra;
			len -= extra;

			if (!queued) {
				*commands = 0;
				*results = 0;
				return 0;
			}
		}
	}
	}


	spin_lock_bh(&priv->ring[ring].egress_lock);
	spin_lock_bh(&priv->ring[ring].egress_lock);