diff options
Diffstat (limited to 'drivers/crypto/nx/nx-sha256.c')
| -rw-r--r-- | drivers/crypto/nx/nx-sha256.c | 70 | 
1 files changed, 40 insertions, 30 deletions
diff --git a/drivers/crypto/nx/nx-sha256.c b/drivers/crypto/nx/nx-sha256.c index 4e91bdb83c59..becb738c897b 100644 --- a/drivers/crypto/nx/nx-sha256.c +++ b/drivers/crypto/nx/nx-sha256.c @@ -29,34 +29,28 @@  #include "nx.h" -static int nx_sha256_init(struct shash_desc *desc) +static int nx_crypto_ctx_sha256_init(struct crypto_tfm *tfm)  { -	struct sha256_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; -	u32 max_sg_len; +	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(tfm); +	int err; -	nx_ctx_init(nx_ctx, HCOP_FC_SHA); +	err = nx_crypto_ctx_sha_init(tfm); +	if (err) +		return err; -	memset(sctx, 0, sizeof *sctx); +	nx_ctx_init(nx_ctx, HCOP_FC_SHA);  	nx_ctx->ap = &nx_ctx->props[NX_PROPS_SHA256];  	NX_CPB_SET_DIGEST_SIZE(nx_ctx->csbcpb, NX_DS_SHA256); -	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); +	return 0; +} -	len = SHA256_DIGEST_SIZE; -	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); +static int nx_sha256_init(struct shash_desc *desc) { +	struct sha256_state *sctx = shash_desc_ctx(desc); -	if (len != SHA256_DIGEST_SIZE) -		return -EINVAL; +	memset(sctx, 0, sizeof *sctx);  	sctx->state[0] = __cpu_to_be32(SHA256_H0);  	sctx->state[1] = __cpu_to_be32(SHA256_H1); @@ -77,7 +71,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data,  	struct sha256_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; +	struct nx_sg *out_sg;  	u64 to_process = 0, leftover, total;  	unsigned long irq_flags;  	int rc = 0; @@ -102,24 +96,28 @@ static int nx_sha256_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); +	data_len = SHA256_DIGEST_SIZE; +	out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *)sctx->state, +				  &data_len, max_sg_len); +	nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg); + +	if (data_len != SHA256_DIGEST_SIZE) { +		rc = -EINVAL; +		goto out; +	} +  	do { -		/* -		 * to_process: the SHA256_BLOCK_SIZE data chunk to process in -		 * this update. This value is also restricted by the sg list -		 * limits. -		 */ -		to_process = total - to_process; -		to_process = to_process & ~(SHA256_BLOCK_SIZE - 1); +		int used_sgs = 0; +		struct nx_sg *in_sg = nx_ctx->in_sg;  		if (buf_len) {  			data_len = buf_len; -			in_sg = nx_build_sg_list(nx_ctx->in_sg, +			in_sg = nx_build_sg_list(in_sg,  						 (u8 *) sctx->buf,  						 &data_len,  						 max_sg_len); @@ -128,15 +126,27 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data,  				rc = -EINVAL;  				goto out;  			} +			used_sgs = in_sg - nx_ctx->in_sg;  		} +		/* to_process: SHA256_BLOCK_SIZE aligned chunk to be +		 * processed in this iteration. This value is restricted +		 * by sg list limits and number of sgs we already used +		 * for leftover data. (see above) +		 * In ideal case, we could allow NX_PAGE_SIZE * max_sg_len, +		 * but because data may not be aligned, we need to account +		 * for that too. */ +		to_process = min_t(u64, total, +			(max_sg_len - 1 - used_sgs) * NX_PAGE_SIZE); +		to_process = to_process & ~(SHA256_BLOCK_SIZE - 1); +  		data_len = to_process - buf_len;  		in_sg = nx_build_sg_list(in_sg, (u8 *) data,  					 &data_len, max_sg_len);  		nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg); -		to_process = (data_len + buf_len); +		to_process = data_len + buf_len;  		leftover = total - to_process;  		/* @@ -282,7 +292,7 @@ struct shash_alg nx_shash_sha256_alg = {  		.cra_blocksize   = SHA256_BLOCK_SIZE,  		.cra_module      = THIS_MODULE,  		.cra_ctxsize     = sizeof(struct nx_crypto_ctx), -		.cra_init        = nx_crypto_ctx_sha_init, +		.cra_init        = nx_crypto_ctx_sha256_init,  		.cra_exit        = nx_crypto_ctx_exit,  	}  };  |