diff options
Diffstat (limited to 'drivers/crypto/nx/nx-sha512.c')
| -rw-r--r-- | drivers/crypto/nx/nx-sha512.c | 85 | 
1 files changed, 50 insertions, 35 deletions
diff --git a/drivers/crypto/nx/nx-sha512.c b/drivers/crypto/nx/nx-sha512.c index b3adf1022673..e6a58d2ee628 100644 --- a/drivers/crypto/nx/nx-sha512.c +++ b/drivers/crypto/nx/nx-sha512.c @@ -32,8 +32,9 @@ static int nx_sha512_init(struct shash_desc *desc)  {  	struct sha512_state *sctx = shash_desc_ctx(desc);  	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base); +	struct nx_sg *out_sg;  	int len; -	int rc; +	u32 max_sg_len;  	nx_ctx_init(nx_ctx, HCOP_FC_SHA); @@ -43,15 +44,18 @@ static int nx_sha512_init(struct shash_desc *desc)  	NX_CPB_SET_DIGEST_SIZE(nx_ctx->csbcpb, NX_DS_SHA512); +	max_sg_len = min_t(u64, nx_ctx->ap->sglen, +			nx_driver.of.max_sg_len/sizeof(struct nx_sg)); +	max_sg_len = min_t(u64, max_sg_len, +			nx_ctx->ap->databytelen/NX_PAGE_SIZE); +  	len = SHA512_DIGEST_SIZE; -	rc = nx_sha_build_sg_list(nx_ctx, nx_ctx->out_sg, -				  &nx_ctx->op.outlen, -				  &len, -				  (u8 *)sctx->state, -				  NX_DS_SHA512); +	out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *)sctx->state, +				  &len, max_sg_len); +	nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg); -	if (rc || len != SHA512_DIGEST_SIZE) -		goto out; +	if (len != SHA512_DIGEST_SIZE) +		return -EINVAL;  	sctx->state[0] = __cpu_to_be64(SHA512_H0);  	sctx->state[1] = __cpu_to_be64(SHA512_H1); @@ -63,7 +67,6 @@ static int nx_sha512_init(struct shash_desc *desc)  	sctx->state[7] = __cpu_to_be64(SHA512_H7);  	sctx->count[0] = 0; -out:  	return 0;  } @@ -73,10 +76,12 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data,  	struct sha512_state *sctx = shash_desc_ctx(desc);  	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);  	struct nx_csbcpb *csbcpb = (struct nx_csbcpb *)nx_ctx->csbcpb; +	struct nx_sg *in_sg;  	u64 to_process, leftover = 0, total;  	unsigned long irq_flags;  	int rc = 0;  	int data_len; +	u32 max_sg_len;  	u64 buf_len = (sctx->count[0] % SHA512_BLOCK_SIZE);  	spin_lock_irqsave(&nx_ctx->lock, irq_flags); @@ -96,6 +101,12 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data,  	NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;  	NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION; +	in_sg = nx_ctx->in_sg; +	max_sg_len = min_t(u64, nx_ctx->ap->sglen, +			nx_driver.of.max_sg_len/sizeof(struct nx_sg)); +	max_sg_len = min_t(u64, max_sg_len, +			nx_ctx->ap->databytelen/NX_PAGE_SIZE); +  	do {  		/*  		 * to_process: the SHA512_BLOCK_SIZE data chunk to process in @@ -108,25 +119,26 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data,  		if (buf_len) {  			data_len = buf_len; -			rc = nx_sha_build_sg_list(nx_ctx, nx_ctx->in_sg, -						  &nx_ctx->op.inlen, -						  &data_len, -						  (u8 *) sctx->buf, -						  NX_DS_SHA512); +			in_sg = nx_build_sg_list(nx_ctx->in_sg, +						 (u8 *) sctx->buf, +						 &data_len, max_sg_len); -			if (rc || data_len != buf_len) +			if (data_len != buf_len) { +				rc = -EINVAL;  				goto out; +			}  		}  		data_len = to_process - buf_len; -		rc = nx_sha_build_sg_list(nx_ctx, nx_ctx->in_sg, -					  &nx_ctx->op.inlen, -					  &data_len, -					  (u8 *) data, -					  NX_DS_SHA512); +		in_sg = nx_build_sg_list(in_sg, (u8 *) data, +					 &data_len, max_sg_len); -		if (rc || data_len != (to_process - buf_len)) +		nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg); + +		if (data_len != (to_process - buf_len)) { +			rc = -EINVAL;  			goto out; +		}  		to_process = (data_len + buf_len);  		leftover = total - to_process; @@ -172,13 +184,20 @@ static int nx_sha512_final(struct shash_desc *desc, u8 *out)  	struct sha512_state *sctx = shash_desc_ctx(desc);  	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);  	struct nx_csbcpb *csbcpb = (struct nx_csbcpb *)nx_ctx->csbcpb; +	struct nx_sg *in_sg, *out_sg; +	u32 max_sg_len;  	u64 count0;  	unsigned long irq_flags; -	int rc; +	int rc = 0;  	int len;  	spin_lock_irqsave(&nx_ctx->lock, irq_flags); +	max_sg_len = min_t(u64, nx_ctx->ap->sglen, +			nx_driver.of.max_sg_len/sizeof(struct nx_sg)); +	max_sg_len = min_t(u64, max_sg_len, +			nx_ctx->ap->databytelen/NX_PAGE_SIZE); +  	/* final is represented by continuing the operation and indicating that  	 * this is not an intermediate operation */  	if (sctx->count[0] >= SHA512_BLOCK_SIZE) { @@ -200,24 +219,20 @@ static int nx_sha512_final(struct shash_desc *desc, u8 *out)  	csbcpb->cpb.sha512.message_bit_length_lo = count0;  	len = sctx->count[0] & (SHA512_BLOCK_SIZE - 1); -	rc = nx_sha_build_sg_list(nx_ctx, nx_ctx->in_sg, -				  &nx_ctx->op.inlen, -				  &len, -				  (u8 *)sctx->buf, -				  NX_DS_SHA512); +	in_sg = nx_build_sg_list(nx_ctx->in_sg, sctx->buf, &len, +				 max_sg_len); -	if (rc || len != (sctx->count[0] & (SHA512_BLOCK_SIZE - 1))) +	if (len != (sctx->count[0] & (SHA512_BLOCK_SIZE - 1))) { +		rc = -EINVAL;  		goto out; +	}  	len = SHA512_DIGEST_SIZE; -	rc = nx_sha_build_sg_list(nx_ctx, nx_ctx->out_sg, -				  &nx_ctx->op.outlen, -				  &len, -				  out, -				  NX_DS_SHA512); +	out_sg = nx_build_sg_list(nx_ctx->out_sg, out, &len, +				 max_sg_len); -	if (rc) -		goto out; +	nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg); +	nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);  	if (!nx_ctx->op.outlen) {  		rc = -EINVAL;  |