crypto/chcr: AEAD support and bug fixes
Subsystems (2)
v2 cover crypto/chcr: AEAD support and bug fixes
This patch series includes Bug Fixes, performance improvement and support for following AEAD algos. GCM,CCM,RFC4106,RFC4303,authenc(hmac(shaXXX),cbc(aes))
Jitendra Lulla (4):
chcr:Fix memory corruption done
Added new structure chcr_wr to populate Work Request Header.
Remove malloc/free in hash operation and allocate memory in
chcr_ahash_req_ctx structure.
Harsh Jain (5):
Calculate Reverse round key in setkey callback.
chcr: Adjust Dest. buffer size
chcr: Use SHASH_DESC_ON_STACK
chcr: Move tfm ctx variable to request context Add AEAD algos.
GCM,CCM,RFC4106,RFC4309,authenc(hmac(shaXXX),cbc(aes)).
drivers/crypto/chelsio/Kconfig | 1 + drivers/crypto/chelsio/chcr_algo.c | 2014 +++++++++++++++++++++++++++++----- drivers/crypto/chelsio/chcr_algo.h | 102 +- drivers/crypto/chelsio/chcr_core.c | 8 +- drivers/crypto/chelsio/chcr_core.h | 18 +- drivers/crypto/chelsio/chcr_crypto.h | 115 +- 6 files changed, 1874 insertions(+), 384 deletions(-)
Signature · 1 line
1.8.2.3
PATCH v2 1/9 crypto/chcr:Fix memory corruption done
Fix memory corruption done by *((u32 *)dec_key + k) operation.
--- drivers/crypto/chelsio/chcr_algo.c | 52 ++++++++++++++++++++++++++++++++++ drivers/crypto/chelsio/chcr_algo.h | 58 +------------------------------------- 2 files changed, 53 insertions(+), 57 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +52 -0
@@ -178,6 +178,58 @@ static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)return flits +sgl_len (cnt); } +static void get_aes_decrypt_key (unsigned char *dec_key, +const unsigned char *key, +unsigned int keylength) +{ +u32 temp; +u32 w_ring[MAX_NK ]; +int i, j, k; +u8 nr, nk; + +switch (keylength) { +case AES_KEYLENGTH_128BIT : + nk =KEYLENGTH_4BYTES ; + nr =NUMBER_OF_ROUNDS_10 ; +break ; +case AES_KEYLENGTH_192BIT : + nk =KEYLENGTH_6BYTES ; + nr =NUMBER_OF_ROUNDS_12 ; +break ; +case AES_KEYLENGTH_256BIT : + nk =KEYLENGTH_8BYTES ; + nr =NUMBER_OF_ROUNDS_14 ; +break ; +default : +return ; + } +for (i =0 ; i < nk; i++) + w_ring[i] =be32_to_cpu (*(u32 *)&key[4 * i]); + + i =0 ; + temp = w_ring[nk -1 ]; +while (i + nk < (nr +1 ) *4 ) { +if (!(i % nk)) { +/* RotWord(temp) */ + temp = (temp <<8 ) | (temp >>24 ); + temp =aes_ks_subword (temp); + temp ^= round_constant[i / nk]; + }else if (nk ==8 && (i %4 ==0 )) { + temp =aes_ks_subword (temp); + } + w_ring[i % nk] ^= temp; + temp = w_ring[i % nk]; + i++; + } + i--; +for (k =0 , j = i % nk; k < nk; k++) { + *((u32 *)dec_key + k) =htonl (w_ring[j]); + j--; +if (j <0 ) + j += nk; + } +} +static struct shash_desc *chcr_alloc_shash (unsigned int ds) {struct crypto_shash *base_hash =NULL ;
drivers/crypto/chelsio/chcr_algo.h +1 -57
68 lines not on this page · raw message
Signature · 1 line
1.8.2.3
PATCH v2 2/9 crypto/chcr: Added new structure chcr_wr to populate Work Request Header.
In reply to Harsh Jain--- drivers/crypto/chelsio/chcr_algo.c | 239 +++++++++++++++++------------------ drivers/crypto/chelsio/chcr_algo.h | 28 ++-- drivers/crypto/chelsio/chcr_core.h | 16 +++ drivers/crypto/chelsio/chcr_crypto.h | 6 - 4 files changed, 140 insertions(+), 149 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +113 -126
@@ -414,8 +414,23 @@ static inline int get_cryptoalg_subtype(struct crypto_tfm *tfm)return chcr_crypto_alg->type &CRYPTO_ALG_SUB_TYPE_MASK ; } +static inline void write_buffer_to_skb (struct sk_buff *skb, +unsigned int *frags, +char *bfr, +u8 bfr_len) +{ + skb->len += bfr_len; + skb->data_len += bfr_len; + skb->truesize += bfr_len; +get_page (virt_to_page (bfr)); +skb_fill_page_desc (skb, *frags,virt_to_page (bfr), +offset_in_page (bfr), bfr_len); + (*frags)++; +} + +static inline void -write_sg_data_page_desc (struct sk_buff *skb,unsigned int *frags, +write_sg_to_skb (struct sk_buff *skb,unsigned int *frags,struct scatterlist *sg,unsigned int count) {struct page *spage;
@@ -456,14 +471,12 @@ static int generate_copy_rrkey(struct ablk_ctx *ablkctx, }static inline void create_wreq (struct chcr_context *ctx, -struct fw_crypto_lookaside_wr *wreq, +struct chcr_wr *chcr_req,void *req,struct sk_buff *skb,int kctx_len,int hash_sz,unsigned int phys_dsgl) {struct uld_ctx *u_ctx =ULD_CTX (ctx); -struct ulp_txpkt *ulptx = (struct ulp_txpkt *)(wreq +1 ); -struct ulptx_idata *sc_imm = (struct ulptx_idata *)(ulptx +1 );int iv_loc =IV_DSGL ;int qid = u_ctx->lldi.rxq_ids[ctx->tx_channel_id];unsigned int immdatalen =0 , nr_frags =0 ;
@@ -475,24 +488,27 @@ static inline void create_wreq(struct chcr_context *ctx, nr_frags =skb_shinfo (skb)->nr_frags; } - wreq->op_to_cctx_size =FILL_WR_OP_CCTX_SIZE (immdatalen, - (kctx_len >>4 )); - wreq->pld_size_hash_size = + chcr_req->wreq.op_to_cctx_size =FILL_WR_OP_CCTX_SIZE (immdatalen, + ((sizeof (chcr_req->key_ctx) + kctx_len) >>4 )); + chcr_req->wreq.pld_size_hash_size =htonl (FW_CRYPTO_LOOKASIDE_WR_PLD_SIZE_V (sgl_lengths[nr_frags]) |FW_CRYPTO_LOOKASIDE_WR_HASH_SIZE_V (hash_sz)); - wreq->len16_pkd =htonl (FW_CRYPTO_LOOKASIDE_WR_LEN16_V (DIV_ROUND_UP ( + chcr_req->wreq.len16_pkd = +htonl (FW_CRYPTO_LOOKASIDE_WR_LEN16_V (DIV_ROUND_UP ( (calc_tx_flits_ofld (skb) *8 ),16 ))); - wreq->cookie =cpu_to_be64 ((uintptr_t )req); - wreq->rx_chid_to_rx_q_id = + chcr_req->wreq.cookie =cpu_to_be64 ((uintptr_t )req); + chcr_req->wreq.rx_chid_to_rx_q_id =FILL_WR_RX_Q_ID (ctx->dev->tx_channel_id, qid, (hash_sz) ?IV_NOP : iv_loc); - ulptx->cmd_dest =FILL_ULPTX_CMD_DEST (ctx->dev->tx_channel_id); - ulptx->len =htonl ((DIV_ROUND_UP ((calc_tx_flits_ofld (skb) *8 ), -16 ) - ((sizeof (*wreq)) >>4 ))); + chcr_req->ulptx.cmd_dest =FILL_ULPTX_CMD_DEST (ctx->dev->tx_channel_id); + chcr_req->ulptx.len =htonl ((DIV_ROUND_UP ((calc_tx_flits_ofld (skb) *8 ), +16 ) - ((sizeof (chcr_req->wreq)) >>4 ))); - sc_imm->cmd_more =FILL_CMD_MORE (immdatalen); - sc_imm->len =cpu_to_be32 (sizeof (struct cpl_tx_sec_pdu ) + kctx_len + + chcr_req->sc_imm.cmd_more =FILL_CMD_MORE (immdatalen); + chcr_req->sc_imm.len =cpu_to_be32 (sizeof (struct cpl_tx_sec_pdu ) + +sizeof (chcr_req->key_ctx) + + kctx_len + ((hash_sz) ?DUMMY_BYTES : (sizeof (struct cpl_rx_phys_dsgl ) + phys_dsgl)) + immdatalen);
@@ -506,23 +522,23 @@ static inline void create_wreq(struct chcr_context *ctx,* @op_type: encryption or decryption */ static struct sk_buff -*create_cipher_wr (struct crypto_async_request *req_base, -struct chcr_context *ctx,unsigned short qid, +*create_cipher_wr (struct ablkcipher_request *req, +unsigned short qid,unsigned short op_type) { -struct ablkcipher_request *req = (struct ablkcipher_request *)req_base;struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (req); +struct chcr_context *ctx =crypto_ablkcipher_ctx (tfm);struct uld_ctx *u_ctx =ULD_CTX (ctx);struct ablk_ctx *ablkctx =ABLK_CTX (ctx);struct sk_buff *skb =NULL ; -struct _key_ctx *key_ctx; -struct fw_crypto_lookaside_wr *wreq; -struct cpl_tx_sec_pdu *sec_cpl; +struct chcr_wr *chcr_req;struct cpl_rx_phys_dsgl *phys_cpl;struct chcr_blkcipher_req_ctx *req_ctx =ablkcipher_request_ctx (req);struct phys_sge_parm sg_param;unsigned int frags =0 , transhdr_len, phys_dsgl, dst_bufsize =0 ;unsigned int ivsize =crypto_ablkcipher_ivsize (tfm), kctx_len; +gfp_t flags = req->base.flags &CRYPTO_TFM_REQ_MAY_SLEEP ?GFP_KERNEL : +GFP_ATOMIC ;if (!req->info)return ERR_PTR (-EINVAL );
@@ -530,62 +546,57 @@ static inline void create_wreq(struct chcr_context *ctx, ablkctx->enc = op_type;if ((ablkctx->enckey_len ==0 ) || (ivsize >AES_BLOCK_SIZE ) || - (req->nbytes <=0 ) || (req->nbytes %AES_BLOCK_SIZE )) + (req->nbytes <=0 ) || (req->nbytes %AES_BLOCK_SIZE )) { +pr_err ("AES: Invalid value of Key Len %d nbytes %d IV Len %d\n" , + ablkctx->enckey_len, req->nbytes, ivsize);return ERR_PTR (-EINVAL ); + } phys_dsgl =get_space_for_phys_dsgl (ablkctx->dst_nents); - kctx_len =sizeof (*key_ctx) + - (DIV_ROUND_UP (ablkctx->enckey_len,16 ) *16 ); + kctx_len = (DIV_ROUND_UP (ablkctx->enckey_len,16 ) *16 ); transhdr_len =CIPHER_TRANSHDR_SIZE (kctx_len, phys_dsgl); - skb =alloc_skb ((transhdr_len +sizeof (struct sge_opaque_hdr )), -GFP_ATOMIC ); + skb =alloc_skb ((transhdr_len +sizeof (struct sge_opaque_hdr )), flags);if (!skb)return ERR_PTR (-ENOMEM );skb_reserve (skb,sizeof (struct sge_opaque_hdr )); - wreq = (struct fw_crypto_lookaside_wr *)__skb_put (skb, transhdr_len); - - sec_cpl = (struct cpl_tx_sec_pdu *)((u8 *)wreq +SEC_CPL_OFFSET ); - sec_cpl->op_ivinsrtofst = -FILL_SEC_CPL_OP_IVINSR (ctx->dev->tx_channel_id,2 ,1 ,1 ); - - sec_cpl->pldlen =htonl (ivsize + req->nbytes); - sec_cpl->aadstart_cipherstop_hi =FILL_SEC_CPL_CIPHERSTOP_HI (0 ,0 , - ivsize +1 ,0 ); - - sec_cpl->cipherstop_lo_authinsert =FILL_SEC_CPL_AUTHINSERT (0 ,0 , -0 ,0 ); - sec_cpl->seqno_numivs =FILL_SEC_CPL_SCMD0_SEQNO (op_type,0 , + chcr_req = (struct chcr_wr *)__skb_put (skb, transhdr_len); +memset (chcr_req,0 , transhdr_len); + chcr_req->sec_cpl.op_ivinsrtofst = +FILL_SEC_CPL_OP_IVINSR (ctx->dev->tx_channel_id,2 ,1 ); + + chcr_req->sec_cpl.pldlen =htonl (ivsize + req->nbytes); + chcr_req->sec_cpl.aadstart_cipherstop_hi = +FILL_SEC_CPL_CIPHERSTOP_HI (0 ,0 , ivsize +1 ,0 ); + + chcr_req->sec_cpl.cipherstop_lo_authinsert = +FILL_SEC_CPL_AUTHINSERT (0 ,0 ,0 ,0 ); + chcr_req->sec_cpl.seqno_numivs =FILL_SEC_CPL_SCMD0_SEQNO (op_type,0 , ablkctx->ciph_mode, -0 ,0 , ivsize >>1 ,1 ); - sec_cpl->ivgen_hdrlen =FILL_SEC_CPL_IVGEN_HDRLEN (0 ,0 ,0 , +0 ,0 , ivsize >>1 ); + chcr_req->sec_cpl.ivgen_hdrlen =FILL_SEC_CPL_IVGEN_HDRLEN (0 ,0 ,0 ,0 ,1 , phys_dsgl); - key_ctx = (struct _key_ctx *)((u8 *)sec_cpl +sizeof (*sec_cpl)); - key_ctx->ctx_hdr = ablkctx->key_ctx_hdr; + chcr_req->key_ctx.ctx_hdr = ablkctx->key_ctx_hdr;if (op_type ==CHCR_DECRYPT_OP ) { -if (generate_copy_rrkey (ablkctx, key_ctx)) - goto map_fail1; +generate_copy_rrkey (ablkctx, &chcr_req->key_ctx); }else {if (ablkctx->ciph_mode ==CHCR_SCMD_CIPHER_MODE_AES_CBC ) { -memcpy (key_ctx->key, ablkctx->key, ablkctx->enckey_len); +memcpy (chcr_req->key_ctx.key, ablkctx->key, + ablkctx->enckey_len); }else { -memcpy (key_ctx->key, ablkctx->key + +memcpy (chcr_req->key_ctx.key, ablkctx->key + (ablkctx->enckey_len >>1 ), ablkctx->enckey_len >>1 ); -memcpy (key_ctx->key + +memcpy (chcr_req->key_ctx.key + (ablkctx->enckey_len >>1 ), ablkctx->key, ablkctx->enckey_len >>1 ); } } - phys_cpl = (struct cpl_rx_phys_dsgl *)((u8 *)key_ctx + kctx_len); - -memcpy (ablkctx->iv, req->info, ivsize); -sg_init_table (&ablkctx->iv_sg,1 ); -sg_set_buf (&ablkctx->iv_sg, ablkctx->iv, ivsize); + phys_cpl = (struct cpl_rx_phys_dsgl *)((u8 *)(chcr_req +1 ) + kctx_len); sg_param.nents = ablkctx->dst_nents; - sg_param.obsize = dst_bufsize; + sg_param.obsize = req->nbytes; sg_param.qid = qid; sg_param.align =1 ; if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, req->dst,
@@ -593,9 +604,10 @@ static inline void create_wreq(struct chcr_context *ctx, goto map_fail1;skb_set_transport_header (skb, transhdr_len); -write_sg_data_page_desc (skb, &frags, &ablkctx->iv_sg, ivsize); -write_sg_data_page_desc (skb, &frags, req->src, req->nbytes); -create_wreq (ctx, wreq, req, skb, kctx_len,0 , phys_dsgl); +memcpy (ablkctx->iv, req->info, ivsize); +write_buffer_to_skb (skb, &frags, ablkctx->iv, ivsize); +write_sg_to_skb (skb, &frags, req->src, req->nbytes); +create_wreq (ctx, chcr_req, req, skb, kctx_len,0 , phys_dsgl); req_ctx->skb = skb;skb_get (skb);return skb;
@@ -662,7 +674,6 @@ static int chcr_aes_encrypt(struct ablkcipher_request *req) {struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (req);struct chcr_context *ctx =crypto_ablkcipher_ctx (tfm); -struct crypto_async_request *req_base = &req->base;struct uld_ctx *u_ctx =ULD_CTX (ctx);struct sk_buff *skb;
@@ -672,8 +683,7 @@ static int chcr_aes_encrypt(struct ablkcipher_request *req)return -EBUSY ; } - skb =create_cipher_wr (req_base, ctx, - u_ctx->lldi.rxq_ids[ctx->tx_channel_id], + skb =create_cipher_wr (req, u_ctx->lldi.rxq_ids[ctx->tx_channel_id],CHCR_ENCRYPT_OP );if (IS_ERR (skb)) {pr_err ("chcr : %s : Failed to form WR. No memory\n" , __func__);
@@ -689,7 +699,6 @@ static int chcr_aes_decrypt(struct ablkcipher_request *req) {struct crypto_ablkcipher *tfm =crypto_ablkcipher_reqtfm (req);struct chcr_context *ctx =crypto_ablkcipher_ctx (tfm); -struct crypto_async_request *req_base = &req->base;struct uld_ctx *u_ctx =ULD_CTX (ctx);struct sk_buff *skb;
@@ -699,7 +708,7 @@ static int chcr_aes_decrypt(struct ablkcipher_request *req)return -EBUSY ; } - skb =create_cipher_wr (req_base, ctx, u_ctx->lldi.rxq_ids[0 ], + skb =create_cipher_wr (req, u_ctx->lldi.rxq_ids[0 ],CHCR_DECRYPT_OP );if (IS_ERR (skb)) {pr_err ("chcr : %s : Failed to form WR. No memory\n" , __func__);
@@ -779,33 +788,11 @@ static int get_alg_config(struct algo_param *params,return 0 ; } -static inline int -write_buffer_data_page_desc (struct chcr_ahash_req_ctx *req_ctx, -struct sk_buff *skb,unsigned int *frags,char *bfr, -u8 bfr_len) -{ -void *page_ptr =NULL ; - - skb->len += bfr_len; - skb->data_len += bfr_len; - skb->truesize += bfr_len; - page_ptr =kmalloc (CHCR_HASH_MAX_BLOCK_SIZE_128 ,GFP_ATOMIC |GFP_DMA ); -if (!page_ptr) -return -ENOMEM ; -get_page (virt_to_page (page_ptr)); - req_ctx->dummy_payload_ptr = page_ptr; -memcpy (page_ptr, bfr, bfr_len); -skb_fill_page_desc (skb, *frags,virt_to_page (page_ptr), -offset_in_page (page_ptr), bfr_len); - (*frags)++; -return 0 ; -} -/** -* create_final_hash_wr - Create hash work request +* create_hash_wr - Create hash work request * @req - Cipher req base */ -static struct sk_buff *create_final_hash_wr (struct ahash_request *req, +static struct sk_buff *create_hash_wr (struct ahash_request *req,struct hash_wr_param *param) {struct chcr_ahash_req_ctx *req_ctx =ahash_request_ctx (req);
@@ -813,16 +800,16 @@ static struct sk_buff *create_final_hash_wr(struct ahash_request *req,struct chcr_context *ctx =crypto_tfm_ctx (crypto_ahash_tfm (tfm));struct hmac_ctx *hmacctx =HMAC_CTX (ctx);struct sk_buff *skb =NULL ; -struct _key_ctx *key_ctx; -struct fw_crypto_lookaside_wr *wreq; -struct cpl_tx_sec_pdu *sec_cpl; +struct chcr_wr *chcr_req;unsigned int frags =0 , transhdr_len, iopad_alignment =0 ;unsigned int digestsize =crypto_ahash_digestsize (tfm); -unsigned int kctx_len =sizeof (*key_ctx); +unsigned int kctx_len =0 ;u8 hash_size_in_response =0 ; +gfp_t flags = req->base.flags &CRYPTO_TFM_REQ_MAY_SLEEP ?GFP_KERNEL : +GFP_ATOMIC ; iopad_alignment =KEYCTX_ALIGN_PAD (digestsize); - kctx_len += param->alg_prm.result_size + iopad_alignment; + kctx_len = param->alg_prm.result_size + iopad_alignment;if (param->opad_needed) kctx_len += param->alg_prm.result_size + iopad_alignment;
@@ -831,53 +818,53 @@ static struct sk_buff *create_final_hash_wr(struct ahash_request *req,else hash_size_in_response = param->alg_prm.result_size; transhdr_len =HASH_TRANSHDR_SIZE (kctx_len); - skb =alloc_skb ((transhdr_len +sizeof (struct sge_opaque_hdr )), -GFP_ATOMIC ); + skb =alloc_skb ((transhdr_len +sizeof (struct sge_opaque_hdr )), flags);if (!skb)return skb;skb_reserve (skb,sizeof (struct sge_opaque_hdr )); - wreq = (struct fw_crypto_lookaside_wr *)__skb_put (skb, transhdr_len); -memset (wreq,0 , transhdr_len); + chcr_req = (struct chcr_wr *)__skb_put (skb, transhdr_len); +memset (chcr_req,0 , transhdr_len); - sec_cpl = (struct cpl_tx_sec_pdu *)((u8 *)wreq +SEC_CPL_OFFSET ); - sec_cpl->op_ivinsrtofst = -FILL_SEC_CPL_OP_IVINSR (ctx->dev->tx_channel_id,2 ,0 ,0 ); - sec_cpl->pldlen =htonl (param->bfr_len + param->sg_len); + chcr_req->sec_cpl.op_ivinsrtofst = +FILL_SEC_CPL_OP_IVINSR (ctx->dev->tx_channel_id,2 ,0 ); + chcr_req->sec_cpl.pldlen =htonl (param->bfr_len + param->sg_len); - sec_cpl->aadstart_cipherstop_hi = + chcr_req->sec_cpl.aadstart_cipherstop_hi =FILL_SEC_CPL_CIPHERSTOP_HI (0 ,0 ,0 ,0 ); - sec_cpl->cipherstop_lo_authinsert = + chcr_req->sec_cpl.cipherstop_lo_authinsert =FILL_SEC_CPL_AUTHINSERT (0 ,1 ,0 ,0 ); - sec_cpl->seqno_numivs = + chcr_req->sec_cpl.seqno_numivs =FILL_SEC_CPL_SCMD0_SEQNO (0 ,0 ,0 , param->alg_prm.auth_mode, - param->opad_needed,0 ,0 ); + param->opad_needed,0 ); - sec_cpl->ivgen_hdrlen = + chcr_req->sec_cpl.ivgen_hdrlen =FILL_SEC_CPL_IVGEN_HDRLEN (param->last, param->more,0 ,1 ,0 ,0 ); - key_ctx = (struct _key_ctx *)((u8 *)sec_cpl +sizeof (*sec_cpl)); -memcpy (key_ctx->key, req_ctx->partial_hash, param->alg_prm.result_size); +memcpy (chcr_req->key_ctx.key, req_ctx->partial_hash, + param->alg_prm.result_size);if (param->opad_needed) -memcpy (key_ctx->key + ((param->alg_prm.result_size <=32 ) ?32 : -CHCR_HASH_MAX_DIGEST_SIZE ), +memcpy (chcr_req->key_ctx.key + + ((param->alg_prm.result_size <=32 ) ?32 : +CHCR_HASH_MAX_DIGEST_SIZE ), hmacctx->opad, param->alg_prm.result_size); - key_ctx->ctx_hdr =FILL_KEY_CTX_HDR (CHCR_KEYCTX_NO_KEY , + chcr_req->key_ctx.ctx_hdr =FILL_KEY_CTX_HDR (CHCR_KEYCTX_NO_KEY , param->alg_prm.mk_size,0 , param->opad_needed, - (kctx_len >>4 )); - sec_cpl->scmd1 =cpu_to_be64 ((u64 )param->scmd1); + ((kctx_len + +sizeof (chcr_req->key_ctx)) >>4 )); + chcr_req->sec_cpl.scmd1 =cpu_to_be64 ((u64 )param->scmd1);skb_set_transport_header (skb, transhdr_len);if (param->bfr_len !=0 ) -write_buffer_data_page_desc (req_ctx, skb, &frags, req_ctx->bfr, +write_buffer_to_skb (skb, &frags, req_ctx->bfr, param->bfr_len);if (param->sg_len !=0 ) -write_sg_data_page_desc (skb, &frags, req->src, param->sg_len); +write_sg_to_skb (skb, &frags, req->src, param->sg_len); -create_wreq (ctx, wreq, req, skb, kctx_len, hash_size_in_response, +create_wreq (ctx, chcr_req, req, skb, kctx_len, hash_size_in_response,0 ); req_ctx->skb = skb;skb_get (skb);
@@ -917,15 +904,11 @@ static int chcr_ahash_update(struct ahash_request *req) params.opad_needed =0 ; params.more =1 ; params.last =0 ; - params.sg_len = nbytes - req_ctx->bfr_len; - params.bfr_len = req_ctx->bfr_len; params.scmd1 =0 ;get_alg_config (¶ms.alg_prm,crypto_ahash_digestsize (rtfm)); req_ctx->result =0 ; req_ctx->data_len += params.sg_len + params.bfr_len; - skb =create_final_hash_wr (req, ¶ms); -if (!skb) -return -ENOMEM ; + skb =create_hash_wr (req, ¶ms); req_ctx->bfr_len = remainder;if (remainder)
@@ -981,7 +964,10 @@ static int chcr_ahash_final(struct ahash_request *req) params.last =1 ; params.more =0 ; } - skb =create_final_hash_wr (req, ¶ms); + skb =create_hash_wr (req, ¶ms); +if (IS_ERR (skb)) +return PTR_ERR (skb); + skb->dev = u_ctx->lldi.ports[0 ];set_wr_txq (skb,CPL_PRIORITY_DATA , ctx->tx_channel_id);chcr_send_wr (skb);
@@ -1029,9 +1015,10 @@ static int chcr_ahash_finup(struct ahash_request *req) params.more =0 ; } - skb =create_final_hash_wr (req, ¶ms); -if (!skb) -return -ENOMEM ; + skb =create_hash_wr (req, ¶ms); +if (IS_ERR (skb)) +return PTR_ERR (skb); + skb->dev = u_ctx->lldi.ports[0 ];set_wr_txq (skb,CPL_PRIORITY_DATA , ctx->tx_channel_id);chcr_send_wr (skb);
@@ -1079,9 +1066,9 @@ static int chcr_ahash_digest(struct ahash_request *req) params.bfr_len = bs; } - skb =create_final_hash_wr (req, ¶ms); -if (!skb) -return -ENOMEM ; + skb =create_hash_wr (req, ¶ms); +if (IS_ERR (skb)) +return PTR_ERR (skb); skb->dev = u_ctx->lldi.ports[0 ];set_wr_txq (skb,CPL_PRIORITY_DATA , ctx->tx_channel_id);
drivers/crypto/chelsio/chcr_algo.h +11 -17
@@ -108,30 +108,24 @@#define IPAD_DATA 0x36363636#define OPAD_DATA 0x5c5c5c5c -#define TRANSHDR_SIZE (alignedkctx_len)\ - (sizeof(struct ulptx_idata) +\ - sizeof(struct ulp_txpkt) +\ - sizeof(struct fw_crypto_lookaside_wr) +\ - sizeof(struct cpl_tx_sec_pdu) +\ - (alignedkctx_len)) -#define CIPHER_TRANSHDR_SIZE (alignedkctx_len, sge_pairs) \ - (TRANSHDR_SIZE(alignedkctx_len) + sge_pairs +\ +#define TRANSHDR_SIZE (kctx_len)\ + (sizeof(struct chcr_wr) +\ + kctx_len) +#define CIPHER_TRANSHDR_SIZE (kctx_len, sge_pairs) \ + (TRANSHDR_SIZE((kctx_len)) + (sge_pairs) +\ sizeof(struct cpl_rx_phys_dsgl)) -#define HASH_TRANSHDR_SIZE (alignedkctx_len)\ - (TRANSHDR_SIZE(alignedkctx_len) + DUMMY_BYTES) +#define HASH_TRANSHDR_SIZE (kctx_len)\ + (TRANSHDR_SIZE(kctx_len) + DUMMY_BYTES) -#define SEC_CPL_OFFSET (sizeof(struct fw_crypto_lookaside_wr) + \ - sizeof(struct ulp_txpkt) + \ - sizeof(struct ulptx_idata)) -#define FILL_SEC_CPL_OP_IVINSR (id, len, hldr, ofst) \ +#define FILL_SEC_CPL_OP_IVINSR (id, len, ofst) \ htonl( \ CPL_TX_SEC_PDU_OPCODE_V(CPL_TX_SEC_PDU) | \ CPL_TX_SEC_PDU_RXCHID_V((id)) | \ CPL_TX_SEC_PDU_ACKFOLLOWS_V(0) | \ CPL_TX_SEC_PDU_ULPTXLPBK_V(1) | \ CPL_TX_SEC_PDU_CPLLEN_V((len)) | \ - CPL_TX_SEC_PDU_PLACEHOLDER_V((hldr)) | \ + CPL_TX_SEC_PDU_PLACEHOLDER_V(0) | \ CPL_TX_SEC_PDU_IVINSRTOFST_V((ofst)))#define FILL_SEC_CPL_CIPHERSTOP_HI (a_start, a_stop, c_start, c_stop_hi) \
@@ -148,7 +142,7 @@ CPL_TX_SEC_PDU_AUTHSTOP_V((a_stop)) | \ CPL_TX_SEC_PDU_AUTHINSERT_V((a_inst))) -#define FILL_SEC_CPL_SCMD0_SEQNO (ctrl, seq, cmode, amode, opad, size, nivs) \ +#define FILL_SEC_CPL_SCMD0_SEQNO (ctrl, seq, cmode, amode, opad, size) \ htonl( \ SCMD_SEQ_NO_CTRL_V(0) | \ SCMD_STATUS_PRESENT_V(0) | \
@@ -159,7 +153,7 @@ SCMD_AUTH_MODE_V((amode)) | \ SCMD_HMAC_CTRL_V((opad)) | \ SCMD_IV_SIZE_V((size)) | \ - SCMD_NUM_IVS_V((nivs))) + SCMD_NUM_IVS_V(0))#define FILL_SEC_CPL_IVGEN_HDRLEN (last, more, ctx_in, mac, ivdrop, len) htonl( \ SCMD_ENB_DBGID_V(0) | \
drivers/crypto/chelsio/chcr_core.h +16 -0
@@ -52,9 +52,25 @@#define MAC_ERROR_BIT 0#define CHK_MAC_ERR_BIT (x) (((x) >> MAC_ERROR_BIT) & 1) +#define MAX_SALT 4struct uld_ctx ; +struct _key_ctx { +__be32 ctx_hdr; +u8 salt[MAX_SALT ]; +__be64 reserverd; +unsigned char key[0 ]; +}; + +struct chcr_wr { +struct fw_crypto_lookaside_wr wreq; +struct ulp_txpkt ulptx; +struct ulptx_idata sc_imm; +struct cpl_tx_sec_pdu sec_cpl; +struct _key_ctx key_ctx; +}; +struct chcr_dev {/* Request submited to h/w and waiting for response. */ spinlock_t lock_chcr_dev;
drivers/crypto/chelsio/chcr_crypto.h +0 -6
@@ -118,12 +118,6 @@#define CHCR_HASH_MAX_BLOCK_SIZE_128 128/* Aligned to 128 bit boundary */ -struct _key_ctx { -__be32 ctx_hdr; -u8 salt[MAX_SALT ]; -__be64 reserverd; -unsigned char key[0 ]; -};struct ablk_ctx {u8 enc;
Signature · 1 line
1.8.2.3
PATCH v2 3/9 crypto/chcr: Fixes Unchecked dereference inside function
In reply to Harsh JainFixes 324429d74127, Unchecked dereference inside function.
--- drivers/crypto/chelsio/chcr_algo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/crypto/chelsio/chcr_algo.c +2 -1
@@ -439,8 +439,9 @@ static inline void write_buffer_to_skb(struct sk_buff *skb, skb->len += count; skb->data_len += count; skb->truesize += count; +while (count >0 ) { -if (sg && (!(sg->length))) +if (!sg || (!(sg->length)))break ; spage =sg_page (sg);get_page (spage);
Signature · 1 line
1.8.2.3
PATCH v2 5/9 crypto/chcr: Calculate Reverse round key in setkey callback.
In reply to Harsh JainMove reverse round key calculation logic in setkey operation.
--- drivers/crypto/chelsio/chcr_algo.c | 52 ++++++++++++++++-------------------- drivers/crypto/chelsio/chcr_crypto.h | 2 +- 2 files changed, 24 insertions(+), 30 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +23 -29
@@ -455,16 +455,13 @@ static int generate_copy_rrkey(struct ablk_ctx *ablkctx, struct _key_ctx *key_ctx) {if (ablkctx->ciph_mode ==CHCR_SCMD_CIPHER_MODE_AES_CBC ) { -get_aes_decrypt_key (key_ctx->key, ablkctx->key, - ablkctx->enckey_len <<3 ); -memset (key_ctx->key + ablkctx->enckey_len,0 , -CHCR_AES_MAX_KEY_LEN - ablkctx->enckey_len); +memcpy (key_ctx->key, ablkctx->rrkey, ablkctx->enckey_len); }else {memcpy (key_ctx->key, ablkctx->key + (ablkctx->enckey_len >>1 ), ablkctx->enckey_len >>1 ); -get_aes_decrypt_key (key_ctx->key + (ablkctx->enckey_len >>1 ), - ablkctx->key, ablkctx->enckey_len <<2 ); +memcpy (key_ctx->key + (ablkctx->enckey_len >>1 ), + ablkctx->rrkey, ablkctx->enckey_len >>1 ); }return 0 ; }
@@ -620,15 +617,9 @@ static int chcr_aes_cbc_setkey(struct crypto_ablkcipher *tfm, const u8 *key, {struct chcr_context *ctx =crypto_ablkcipher_ctx (tfm);struct ablk_ctx *ablkctx =ABLK_CTX (ctx); -struct ablkcipher_alg *alg =crypto_ablkcipher_alg (tfm);unsigned int ck_size, context_size;u16 alignment =0 ; -if ((keylen < alg->min_keysize) || (keylen > alg->max_keysize)) - goto badkey_err; - -memcpy (ablkctx->key, key, keylen); - ablkctx->enckey_len = keylen;if (keylen ==AES_KEYSIZE_128 ) { ck_size =CHCR_KEYCTX_CIPHER_KEY_SIZE_128 ; }else if (keylen ==AES_KEYSIZE_192 ) {
@@ -639,7 +630,9 @@ static int chcr_aes_cbc_setkey(struct crypto_ablkcipher *tfm, const u8 *key, }else { goto badkey_err; } - +memcpy (ablkctx->key, key, keylen); + ablkctx->enckey_len = keylen; +get_aes_decrypt_key (ablkctx->rrkey, ablkctx->key, keylen <<3 ); context_size = (KEY_CONTEXT_HDR_SALT_AND_PAD + keylen + alignment) >>4 ;
@@ -1172,28 +1165,29 @@ static int chcr_aes_xts_setkey(struct crypto_ablkcipher *tfm, const u8 *key, {struct chcr_context *ctx =crypto_ablkcipher_ctx (tfm);struct ablk_ctx *ablkctx =ABLK_CTX (ctx); -int status =0 ;unsigned short context_size =0 ; -if ((key_len == (AES_KEYSIZE_128 <<1 )) || - (key_len == (AES_KEYSIZE_256 <<1 ))) { -memcpy (ablkctx->key, key, key_len); - ablkctx->enckey_len = key_len; - context_size = (KEY_CONTEXT_HDR_SALT_AND_PAD + key_len) >>4 ; - ablkctx->key_ctx_hdr = -FILL_KEY_CTX_HDR ((key_len ==AES_KEYSIZE_256 ) ? -CHCR_KEYCTX_CIPHER_KEY_SIZE_128 : -CHCR_KEYCTX_CIPHER_KEY_SIZE_256 , -CHCR_KEYCTX_NO_KEY ,1 , -0 , context_size); - ablkctx->ciph_mode =CHCR_SCMD_CIPHER_MODE_AES_XTS ; - }else { +if ((key_len != (AES_KEYSIZE_128 <<1 )) && + (key_len != (AES_KEYSIZE_256 <<1 ))) {crypto_tfm_set_flags ((struct crypto_tfm *)tfm,CRYPTO_TFM_RES_BAD_KEY_LEN ); ablkctx->enckey_len =0 ; - status = -EINVAL ; +return -EINVAL ; + } -return status; + +memcpy (ablkctx->key, key, key_len); + ablkctx->enckey_len = key_len; +get_aes_decrypt_key (ablkctx->rrkey, ablkctx->key, key_len <<2 ); + context_size = (KEY_CONTEXT_HDR_SALT_AND_PAD + key_len) >>4 ; + ablkctx->key_ctx_hdr = +FILL_KEY_CTX_HDR ((key_len ==AES_KEYSIZE_256 ) ? +CHCR_KEYCTX_CIPHER_KEY_SIZE_128 : +CHCR_KEYCTX_CIPHER_KEY_SIZE_256 , +CHCR_KEYCTX_NO_KEY ,1 , +0 , context_size); + ablkctx->ciph_mode =CHCR_SCMD_CIPHER_MODE_AES_XTS ; +return 0 ; }static int chcr_sha_init (struct ahash_request *areq)
drivers/crypto/chelsio/chcr_crypto.h +1 -1
@@ -125,8 +125,8 @@ struct ablk_ctx {__be32 key_ctx_hdr;unsigned int enckey_len;unsigned int dst_nents; -struct scatterlist iv_sg;u8 key[CHCR_AES_MAX_KEY_LEN ]; +u8 rrkey[AES_MAX_KEY_SIZE ];u8 iv[CHCR_MAX_CRYPTO_IV_LEN ];unsigned char ciph_mode; };
Signature · 1 line
1.8.2.3
PATCH v2 4/9 crypto/chcr: Remove dynamic allocation
In reply to Harsh JainRemove malloc/free in hash operation and allocate
memory in chcr_ahash_req_ctx structure.
--- drivers/crypto/chelsio/chcr_algo.c | 69 +++++++++++++++++++++--------------- drivers/crypto/chelsio/chcr_crypto.h | 8 +++-- 2 files changed, 45 insertions(+), 32 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +40 -29
@@ -150,8 +150,6 @@ int chcr_handle_resp(struct crypto_async_request *req, unsigned char *input,sizeof (struct cpl_fw6_pld ), updated_digestsize); } -kfree (ctx_req.ctx.ahash_ctx->dummy_payload_ptr); - ctx_req.ctx.ahash_ctx->dummy_payload_ptr =NULL ;break ; }return 0 ;
@@ -860,8 +858,8 @@ static struct sk_buff *create_hash_wr(struct ahash_request *req,skb_set_transport_header (skb, transhdr_len);if (param->bfr_len !=0 ) -write_buffer_to_skb (skb, &frags, req_ctx->bfr, - param->bfr_len); +write_buffer_to_skb (skb, &frags, req_ctx->reqbfr, + param->bfr_len);if (param->sg_len !=0 )write_sg_to_skb (skb, &frags, req->src, param->sg_len);
@@ -892,30 +890,41 @@ static int chcr_ahash_update(struct ahash_request *req)return -EBUSY ; } -if (nbytes + req_ctx->bfr_len >= bs) { - remainder = (nbytes + req_ctx->bfr_len) % bs; - nbytes = nbytes + req_ctx->bfr_len - remainder; +if (nbytes + req_ctx->reqlen >= bs) { + remainder = (nbytes + req_ctx->reqlen) % bs; + nbytes = nbytes + req_ctx->reqlen - remainder; }else { -sg_pcopy_to_buffer (req->src,sg_nents (req->src), req_ctx->bfr + - req_ctx->bfr_len, nbytes,0 ); - req_ctx->bfr_len += nbytes; +sg_pcopy_to_buffer (req->src,sg_nents (req->src), req_ctx->reqbfr + + req_ctx->reqlen, nbytes,0 ); + req_ctx->reqlen += nbytes;return 0 ; } params.opad_needed =0 ; params.more =1 ; params.last =0 ; + params.sg_len = nbytes - req_ctx->reqlen; + params.bfr_len = req_ctx->reqlen; params.scmd1 =0 ;get_alg_config (¶ms.alg_prm,crypto_ahash_digestsize (rtfm)); req_ctx->result =0 ; req_ctx->data_len += params.sg_len + params.bfr_len; skb =create_hash_wr (req, ¶ms); - req_ctx->bfr_len = remainder; -if (remainder) +if (IS_ERR (skb)) +return PTR_ERR (skb); + +if (remainder) { +u8 *temp; +/* Swap buffers */ + temp = req_ctx->reqbfr; + req_ctx->reqbfr = req_ctx->skbfr; + req_ctx->skbfr = temp;sg_pcopy_to_buffer (req->src,sg_nents (req->src), - req_ctx->bfr, remainder, req->nbytes - + req_ctx->reqbfr, remainder, req->nbytes - remainder); + } + req_ctx->reqlen = remainder; skb->dev = u_ctx->lldi.ports[0 ];set_wr_txq (skb,CPL_PRIORITY_DATA , ctx->tx_channel_id);chcr_send_wr (skb);
@@ -951,10 +960,10 @@ static int chcr_ahash_final(struct ahash_request *req) params.sg_len =0 ;get_alg_config (¶ms.alg_prm,crypto_ahash_digestsize (rtfm)); req_ctx->result =1 ; - params.bfr_len = req_ctx->bfr_len; + params.bfr_len = req_ctx->reqlen; req_ctx->data_len += params.bfr_len + params.sg_len; -if (req_ctx->bfr && (req_ctx->bfr_len ==0 )) { -create_last_hash_block (req_ctx->bfr, bs, req_ctx->data_len); +if (req_ctx->reqlen ==0 ) { +create_last_hash_block (req_ctx->reqbfr, bs, req_ctx->data_len); params.last =0 ; params.more =1 ; params.scmd1 =0 ;
@@ -1000,12 +1009,12 @@ static int chcr_ahash_finup(struct ahash_request *req) params.opad_needed =0 ; params.sg_len = req->nbytes; - params.bfr_len = req_ctx->bfr_len; + params.bfr_len = req_ctx->reqlen;get_alg_config (¶ms.alg_prm,crypto_ahash_digestsize (rtfm)); req_ctx->data_len += params.bfr_len + params.sg_len; req_ctx->result =1 ; -if (req_ctx->bfr && (req_ctx->bfr_len + req->nbytes) ==0 ) { -create_last_hash_block (req_ctx->bfr, bs, req_ctx->data_len); +if ((req_ctx->reqlen + req->nbytes) ==0 ) { +create_last_hash_block (req_ctx->reqbfr, bs, req_ctx->data_len); params.last =0 ; params.more =1 ; params.scmd1 =0 ;
@@ -1061,8 +1070,8 @@ static int chcr_ahash_digest(struct ahash_request *req) req_ctx->result =1 ; req_ctx->data_len += params.bfr_len + params.sg_len; -if (req_ctx->bfr && req->nbytes ==0 ) { -create_last_hash_block (req_ctx->bfr, bs,0 ); +if (req->nbytes ==0 ) { +create_last_hash_block (req_ctx->reqbfr, bs,0 ); params.more =1 ; params.bfr_len = bs; }
@@ -1082,12 +1091,12 @@ static int chcr_ahash_export(struct ahash_request *areq, void *out)struct chcr_ahash_req_ctx *req_ctx =ahash_request_ctx (areq);struct chcr_ahash_req_ctx *state = out; - state->bfr_len = req_ctx->bfr_len; + state->reqlen = req_ctx->reqlen; state->data_len = req_ctx->data_len; -memcpy (state->bfr, req_ctx->bfr,CHCR_HASH_MAX_BLOCK_SIZE_128 ); +memcpy (state->bfr1, req_ctx->reqbfr, req_ctx->reqlen);memcpy (state->partial_hash, req_ctx->partial_hash,CHCR_HASH_MAX_DIGEST_SIZE ); -return 0 ; +return 0 ; }static int chcr_ahash_import (struct ahash_request *areq,const void *in)
@@ -1095,10 +1104,11 @@ static int chcr_ahash_import(struct ahash_request *areq, const void *in)struct chcr_ahash_req_ctx *req_ctx =ahash_request_ctx (areq);struct chcr_ahash_req_ctx *state = (struct chcr_ahash_req_ctx *)in; - req_ctx->bfr_len = state->bfr_len; + req_ctx->reqlen = state->reqlen; req_ctx->data_len = state->data_len; - req_ctx->dummy_payload_ptr =NULL ; -memcpy (req_ctx->bfr, state->bfr,CHCR_HASH_MAX_BLOCK_SIZE_128 ); + req_ctx->reqbfr = req_ctx->bfr1; + req_ctx->skbfr = req_ctx->bfr2; +memcpy (req_ctx->bfr1, state->bfr1,CHCR_HASH_MAX_BLOCK_SIZE_128 );memcpy (req_ctx->partial_hash, state->partial_hash,CHCR_HASH_MAX_DIGEST_SIZE );return 0 ;
@@ -1193,8 +1203,9 @@ static int chcr_sha_init(struct ahash_request *areq)int digestsize =crypto_ahash_digestsize (tfm); req_ctx->data_len =0 ; - req_ctx->dummy_payload_ptr =NULL ; - req_ctx->bfr_len =0 ; + req_ctx->reqlen =0 ; + req_ctx->reqbfr = req_ctx->bfr1; + req_ctx->skbfr = req_ctx->bfr2; req_ctx->skb =NULL ; req_ctx->result =0 ;copy_hash_init_values (req_ctx->partial_hash, digestsize);
drivers/crypto/chelsio/chcr_crypto.h +5 -3
@@ -150,12 +150,14 @@ struct chcr_context {struct chcr_ahash_req_ctx {u32 result; -char bfr[CHCR_HASH_MAX_BLOCK_SIZE_128 ]; -u8 bfr_len; +u8 bfr1[CHCR_HASH_MAX_BLOCK_SIZE_128 ]; +u8 bfr2[CHCR_HASH_MAX_BLOCK_SIZE_128 ]; +u8 *reqbfr; +u8 *skbfr; +u8 reqlen;/* DMA the partial hash in it */ u8 partial_hash[CHCR_HASH_MAX_DIGEST_SIZE ];u64 data_len;/* Data len till time */ -void *dummy_payload_ptr;/* SKB which is being sent to the hardware for processing */ struct sk_buff *skb; };
Signature · 1 line
1.8.2.3
PATCH v2 6/9 crypto/chcr: Adjust Dest. buffer size
In reply to Harsh JainDestination buffer size passed to hardware should not be greater than crypto operation output.
--- drivers/crypto/chelsio/chcr_algo.c | 50 +++++++++++++++----------------------- 1 file changed, 20 insertions(+), 30 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +20 -30
@@ -335,25 +335,13 @@ static inline int is_hmac(struct crypto_tfm *tfm)return 0 ; } -static inline unsigned int ch_nents (struct scatterlist *sg, -unsigned int *total_size) -{ -unsigned int nents; - -for (nents =0 , *total_size =0 ; sg; sg =sg_next (sg)) { - nents++; - *total_size += sg->length; - } -return nents; -} -static void write_phys_cpl (struct cpl_rx_phys_dsgl *phys_cpl,struct scatterlist *sg,struct phys_sge_parm *sg_param) {struct phys_sge_pairs *to; -unsigned int out_buf_size = sg_param->obsize; -unsigned int nents = sg_param->nents, i, j, tot_len =0 ; +int out_buf_size = sg_param->obsize; +unsigned int nents = sg_param->nents, i, j =0 ; phys_cpl->op_to_tid =htonl (CPL_RX_PHYS_DSGL_OPCODE_V (CPL_RX_PHYS_DSGL ) |CPL_RX_PHYS_DSGL_ISRDMA_V (0 ));
@@ -371,25 +359,24 @@ static void write_phys_cpl(struct cpl_rx_phys_dsgl *phys_cpl, sizeof(struct cpl_rx_phys_dsgl));for (i =0 ; nents; to++) { -for (j = i; (nents && (j < (8 + i))); j++, nents--) { - to->len[j] =htons (sg->length); +for (j =0 ; j <8 && nents; j++, nents--) { + out_buf_size -=sg_dma_len (sg); + to->len[j] =htons (sg_dma_len (sg)); to->addr[j] =cpu_to_be64 (sg_dma_address (sg)); -if (out_buf_size) { -if (tot_len +sg_dma_len (sg) >= out_buf_size) { - to->len[j] =htons (out_buf_size - - tot_len); -return ; - } - tot_len +=sg_dma_len (sg); - } sg =sg_next (sg); } } +if (out_buf_size) { + j--; + to--; + to->len[j] =htons (ntohs (to->len[j]) + (out_buf_size)); + } } -static inline unsigned -int map_writesg_phys_cpl (struct device *dev,struct cpl_rx_phys_dsgl *phys_cpl, -struct scatterlist *sg,struct phys_sge_parm *sg_param) +static inline int map_writesg_phys_cpl (struct device *dev, +struct cpl_rx_phys_dsgl *phys_cpl, +struct scatterlist *sg, +struct phys_sge_parm *sg_param) {if (!sg || !sg_param->nents)return 0 ;
@@ -531,16 +518,19 @@ static inline void create_wreq(struct chcr_context *ctx,struct cpl_rx_phys_dsgl *phys_cpl;struct chcr_blkcipher_req_ctx *req_ctx =ablkcipher_request_ctx (req);struct phys_sge_parm sg_param; -unsigned int frags =0 , transhdr_len, phys_dsgl, dst_bufsize =0 ; +unsigned int frags =0 , transhdr_len, phys_dsgl;unsigned int ivsize =crypto_ablkcipher_ivsize (tfm), kctx_len;gfp_t flags = req->base.flags &CRYPTO_TFM_REQ_MAY_SLEEP ?GFP_KERNEL :GFP_ATOMIC ;if (!req->info)return ERR_PTR (-EINVAL ); - ablkctx->dst_nents =ch_nents (req->dst, &dst_bufsize); + ablkctx->dst_nents =sg_nents_for_len (req->dst, req->nbytes); +if (ablkctx->dst_nents <=0 ) { +pr_err ("AES:Invalid Destination sg lists\n" ); +return ERR_PTR (-EINVAL ); + } ablkctx->enc = op_type; -if ((ablkctx->enckey_len ==0 ) || (ivsize >AES_BLOCK_SIZE ) || (req->nbytes <=0 ) || (req->nbytes %AES_BLOCK_SIZE )) { pr_err("AES: Invalid value of Key Len %d nbytes %d IV Len %d\n",
Signature · 1 line
1.8.2.3
PATCH v2 7/9 crypto/chcr: Use SHASH_DESC_ON_STACK
In reply to Harsh JainUse SHASH_DESC_ON_STACK macro to allocate memory for ipad/opad calculation.
--- drivers/crypto/chelsio/chcr_algo.c | 63 +++++++++++++++--------------------- drivers/crypto/chelsio/chcr_crypto.h | 2 +- 2 files changed, 27 insertions(+), 38 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +26 -37
@@ -228,40 +228,29 @@ static void get_aes_decrypt_key(unsigned char *dec_key, } } -static struct shash_desc *chcr_alloc_shash (unsigned int ds) +static struct crypto_shash *chcr_alloc_shash (unsigned int ds) {struct crypto_shash *base_hash =NULL ; -struct shash_desc *desc;switch (ds) {case SHA1_DIGEST_SIZE : - base_hash =crypto_alloc_shash ("sha1-generic" ,0 ,0 ); + base_hash =crypto_alloc_shash ("sha1" ,0 ,0 );break ;case SHA224_DIGEST_SIZE : - base_hash =crypto_alloc_shash ("sha224-generic" ,0 ,0 ); + base_hash =crypto_alloc_shash ("sha224" ,0 ,0 );break ;case SHA256_DIGEST_SIZE : - base_hash =crypto_alloc_shash ("sha256-generic" ,0 ,0 ); + base_hash =crypto_alloc_shash ("sha256" ,0 ,0 );break ;case SHA384_DIGEST_SIZE : - base_hash =crypto_alloc_shash ("sha384-generic" ,0 ,0 ); + base_hash =crypto_alloc_shash ("sha384" ,0 ,0 );break ;case SHA512_DIGEST_SIZE : - base_hash =crypto_alloc_shash ("sha512-generic" ,0 ,0 ); + base_hash =crypto_alloc_shash ("sha512" ,0 ,0 );break ; } -if (IS_ERR (base_hash)) { -pr_err ("Can not allocate sha-generic algo.\n" ); -return (void *)base_hash; - } - desc =kmalloc (sizeof (*desc) +crypto_shash_descsize (base_hash), -GFP_KERNEL ); -if (!desc) -return ERR_PTR (-ENOMEM ); - desc->tfm = base_hash; - desc->flags =crypto_shash_get_flags (base_hash); -return desc; +return base_hash; } static int chcr_compute_partial_hash(struct shash_desc *desc,
@@ -770,6 +759,11 @@ static int get_alg_config(struct algo_param *params,return 0 ; } +static inline void chcr_free_shash (struct crypto_shash *base_hash) +{ +crypto_free_shash (base_hash); +} +/** * create_hash_wr - Create hash work request * @req - Cipher req base
@@ -1106,15 +1100,16 @@ static int chcr_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,unsigned int bs =crypto_tfm_alg_blocksize (crypto_ahash_tfm (tfm));unsigned int i, err =0 , updated_digestsize; -/* -* use the key to calculate the ipad and opad. ipad will sent with the +SHASH_DESC_ON_STACK (shash, hmacctx->base_hash); + +/* use the key to calculate the ipad and opad. ipad will sent with the * first request's data. opad will be sent with the final hash result * ipad in hmacctx->ipad and opad in hmacctx->opad location */ -if (!hmacctx->desc) -return -EINVAL ; + shash->tfm = hmacctx->base_hash; + shash->flags =crypto_shash_get_flags (hmacctx->base_hash);if (keylen > bs) { - err =crypto_shash_digest (hmacctx->desc, key, keylen, + err =crypto_shash_digest (shash, key, keylen, hmacctx->ipad);if (err) goto out;
@@ -1135,13 +1130,13 @@ static int chcr_ahash_setkey(struct crypto_ahash *tfm, const u8 *key, updated_digestsize =SHA256_DIGEST_SIZE ; else if (digestsize == SHA384_DIGEST_SIZE) updated_digestsize =SHA512_DIGEST_SIZE ; - err =chcr_compute_partial_hash (hmacctx->desc, hmacctx->ipad, + err =chcr_compute_partial_hash (shash, hmacctx->ipad, hmacctx->ipad, digestsize);if (err) goto out;chcr_change_order (hmacctx->ipad, updated_digestsize); - err =chcr_compute_partial_hash (hmacctx->desc, hmacctx->opad, + err =chcr_compute_partial_hash (shash, hmacctx->opad, hmacctx->opad, digestsize);if (err) goto out;
@@ -1237,26 +1232,20 @@ static int chcr_hmac_cra_init(struct crypto_tfm *tfm)crypto_ahash_set_reqsize (__crypto_ahash_cast (tfm),sizeof (struct chcr_ahash_req_ctx )); - hmacctx->desc =chcr_alloc_shash (digestsize); -if (IS_ERR (hmacctx->desc)) -return PTR_ERR (hmacctx->desc); + hmacctx->base_hash =chcr_alloc_shash (digestsize); +if (IS_ERR (hmacctx->base_hash)) +return PTR_ERR (hmacctx->base_hash);return chcr_device_init (crypto_tfm_ctx (tfm)); } -static void chcr_free_shash (struct shash_desc *desc) -{ -crypto_free_shash (desc->tfm); -kfree (desc); -} -static void chcr_hmac_cra_exit (struct crypto_tfm *tfm) {struct chcr_context *ctx =crypto_tfm_ctx (tfm);struct hmac_ctx *hmacctx =HMAC_CTX (ctx); -if (hmacctx->desc) { -chcr_free_shash (hmacctx->desc); - hmacctx->desc =NULL ; +if (hmacctx->base_hash) { +chcr_free_shash (hmacctx->base_hash); + hmacctx->base_hash =NULL ; } }
drivers/crypto/chelsio/chcr_crypto.h +1 -1
@@ -132,7 +132,7 @@ struct ablk_ctx { };struct hmac_ctx { -struct shash_desc *desc; +struct crypto_shash *base_hash;u8 ipad[CHCR_HASH_MAX_BLOCK_SIZE_128 ];u8 opad[CHCR_HASH_MAX_BLOCK_SIZE_128 ]; };
Signature · 1 line
1.8.2.3
PATCH v2 8/9 crypto/chcr: Move tfm ctx variable to request context
In reply to Harsh JainMove request specific data in request context.
--- drivers/crypto/chelsio/chcr_algo.c | 26 +++++++++++++------------- drivers/crypto/chelsio/chcr_crypto.h | 9 ++++----- 2 files changed, 17 insertions(+), 18 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +13 -13
@@ -119,7 +119,7 @@ int chcr_handle_resp(struct crypto_async_request *req, unsigned char *input, AES_BLOCK_SIZE); }dma_unmap_sg (&u_ctx->lldi.pdev->dev, ctx_req.req.ablk_req->dst, -ABLK_CTX (ctx)->dst_nents,DMA_FROM_DEVICE ); + ctx_req.ctx.ablk_ctx->dst_nents,DMA_FROM_DEVICE );if (ctx_req.ctx.ablk_ctx->skb) {kfree_skb (ctx_req.ctx.ablk_ctx->skb); ctx_req.ctx.ablk_ctx->skb =NULL ;
@@ -138,8 +138,10 @@ int chcr_handle_resp(struct crypto_async_request *req, unsigned char *input, updated_digestsize =SHA256_DIGEST_SIZE ; else if (digestsize == SHA384_DIGEST_SIZE) updated_digestsize =SHA512_DIGEST_SIZE ; -if (ctx_req.ctx.ahash_ctx->skb) +if (ctx_req.ctx.ahash_ctx->skb) { +kfree_skb (ctx_req.ctx.ahash_ctx->skb); ctx_req.ctx.ahash_ctx->skb =NULL ; + }if (ctx_req.ctx.ahash_ctx->result ==1 ) { ctx_req.ctx.ahash_ctx->result =0 ; memcpy(ctx_req.req.ahash_req->result, input +
@@ -318,8 +320,7 @@ static inline int is_hmac(struct crypto_tfm *tfm)struct chcr_alg_template *chcr_crypto_alg = container_of(__crypto_ahash_alg(alg), struct chcr_alg_template, alg.hash); -if ((chcr_crypto_alg->type &CRYPTO_ALG_SUB_TYPE_MASK ) == -CRYPTO_ALG_SUB_TYPE_HASH_HMAC ) +if (chcr_crypto_alg->type ==CRYPTO_ALG_TYPE_HMAC )return 1 ;return 0 ; }
@@ -505,7 +506,7 @@ static inline void create_wreq(struct chcr_context *ctx,struct sk_buff *skb =NULL ;struct chcr_wr *chcr_req;struct cpl_rx_phys_dsgl *phys_cpl; -struct chcr_blkcipher_req_ctx *req_ctx =ablkcipher_request_ctx (req); +struct chcr_blkcipher_req_ctx *reqctx =ablkcipher_request_ctx (req);struct phys_sge_parm sg_param;unsigned int frags =0 , transhdr_len, phys_dsgl;unsigned int ivsize =crypto_ablkcipher_ivsize (tfm), kctx_len;
@@ -514,12 +515,11 @@ static inline void create_wreq(struct chcr_context *ctx,if (!req->info)return ERR_PTR (-EINVAL ); - ablkctx->dst_nents =sg_nents_for_len (req->dst, req->nbytes); -if (ablkctx->dst_nents <=0 ) { + reqctx->dst_nents =sg_nents_for_len (req->dst, req->nbytes); +if (reqctx->dst_nents <=0 ) {pr_err ("AES:Invalid Destination sg lists\n" );return ERR_PTR (-EINVAL ); } - ablkctx->enc = op_type;if ((ablkctx->enckey_len ==0 ) || (ivsize >AES_BLOCK_SIZE ) || (req->nbytes <=0 ) || (req->nbytes %AES_BLOCK_SIZE )) { pr_err("AES: Invalid value of Key Len %d nbytes %d IV Len %d\n",
@@ -527,7 +527,7 @@ static inline void create_wreq(struct chcr_context *ctx,return ERR_PTR (-EINVAL ); } - phys_dsgl =get_space_for_phys_dsgl (ablkctx->dst_nents); + phys_dsgl =get_space_for_phys_dsgl (reqctx->dst_nents); kctx_len = (DIV_ROUND_UP (ablkctx->enckey_len,16 ) *16 ); transhdr_len =CIPHER_TRANSHDR_SIZE (kctx_len, phys_dsgl);
@@ -570,7 +570,7 @@ static inline void create_wreq(struct chcr_context *ctx, } } phys_cpl = (struct cpl_rx_phys_dsgl *)((u8 *)(chcr_req +1 ) + kctx_len); - sg_param.nents = ablkctx->dst_nents; + sg_param.nents = reqctx->dst_nents; sg_param.obsize = req->nbytes; sg_param.qid = qid; sg_param.align =1 ;
@@ -579,11 +579,11 @@ static inline void create_wreq(struct chcr_context *ctx, goto map_fail1;skb_set_transport_header (skb, transhdr_len); -memcpy (ablkctx->iv, req->info, ivsize); -write_buffer_to_skb (skb, &frags, ablkctx->iv, ivsize); +memcpy (reqctx->iv, req->info, ivsize); +write_buffer_to_skb (skb, &frags, reqctx->iv, ivsize);write_sg_to_skb (skb, &frags, req->src, req->nbytes);create_wreq (ctx, chcr_req, req, skb, kctx_len,0 , phys_dsgl); - req_ctx->skb = skb; + reqctx->skb = skb;skb_get (skb);return skb; map_fail1:
drivers/crypto/chelsio/chcr_crypto.h +4 -5
@@ -120,17 +120,14 @@/* Aligned to 128 bit boundary */ struct ablk_ctx { -u8 enc; -unsigned int processed_len;__be32 key_ctx_hdr;unsigned int enckey_len; -unsigned int dst_nents;u8 key[CHCR_AES_MAX_KEY_LEN ]; -u8 rrkey[AES_MAX_KEY_SIZE ]; -u8 iv[CHCR_MAX_CRYPTO_IV_LEN ];unsigned char ciph_mode; +u8 rrkey[AES_MAX_KEY_SIZE ]; }; +struct hmac_ctx {struct crypto_shash *base_hash;u8 ipad[CHCR_HASH_MAX_BLOCK_SIZE_128 ];
@@ -164,6 +161,8 @@ struct chcr_ahash_req_ctx {struct chcr_blkcipher_req_ctx {struct sk_buff *skb; +unsigned int dst_nents; +u8 iv[CHCR_MAX_CRYPTO_IV_LEN ]; };struct chcr_alg_template {
Signature · 1 line
1.8.2.3
PATCH v2 9/9 crypto/chcr: Add AEAD algos
In reply to Harsh JainAdd support for following AEAD algos.
GCM,CCM,RFC4106,RFC4309,authenc(hmac(shaXXX),cbc(aes)).
--- drivers/crypto/chelsio/Kconfig | 1 + drivers/crypto/chelsio/chcr_algo.c | 1482 +++++++++++++++++++++++++++++++++- drivers/crypto/chelsio/chcr_algo.h | 16 +- drivers/crypto/chelsio/chcr_core.c | 8 +- drivers/crypto/chelsio/chcr_core.h | 2 - drivers/crypto/chelsio/chcr_crypto.h | 90 ++- 6 files changed, 1558 insertions(+), 41 deletions(-)
drivers/crypto/chelsio/Kconfig +1 -0
@@ -4,6 +4,7 @@ config CRYPTO_DEV_CHELSIO select CRYPTO_SHA1 select CRYPTO_SHA256 select CRYPTO_SHA512 + select CRYPTO_AUTHENC ---help--- The Chelsio Crypto Co-processor driver for T6 adapters.
drivers/crypto/chelsio/chcr_algo.c +1462 -20
1,633 lines not on this page · raw message
drivers/crypto/chelsio/chcr_algo.h +9 -7
@@ -258,13 +258,15 @@ enum {* where they indicate the size of the integrity check value (ICV) */ enum { -AES_CCM_ICV_4 =4 , -AES_CCM_ICV_6 =6 , -AES_CCM_ICV_8 =8 , -AES_CCM_ICV_10 =10 , -AES_CCM_ICV_12 =12 , -AES_CCM_ICV_14 =14 , -AES_CCM_ICV_16 =16 +ICV_4 =4 , +ICV_6 =6 , +ICV_8 =8 , +ICV_10 =10 , +ICV_12 =12 , +ICV_13 =13 , +ICV_14 =14 , +ICV_15 =15 , +ICV_16 =16 };struct hash_op_params {
drivers/crypto/chelsio/chcr_core.c +3 -5
@@ -109,14 +109,12 @@ static int cpl_fw6_pld_handler(struct chcr_dev *dev,if (ack_err_status) {if (CHK_MAC_ERR_BIT (ack_err_status) ||CHK_PAD_ERR_BIT (ack_err_status)) - error_status = -EINVAL ; + error_status = -EBADMSG ; }/* call completion callback with failure status */ if (req) { -if (!chcr_handle_resp (req, input, error_status)) - req->complete (req, error_status); -else -return -EINVAL ; + error_status =chcr_handle_resp (req, input, error_status); + req->complete (req, error_status); }else {pr_err ("Incorrect request address from the firmware\n" );return -EFAULT ;
drivers/crypto/chelsio/chcr_core.h +0 -2
@@ -72,9 +72,7 @@ struct chcr_wr { };struct chcr_dev { -/* Request submited to h/w and waiting for response. */ spinlock_t lock_chcr_dev; -struct crypto_queue pending_queue;struct uld_ctx *u_ctx;unsigned char tx_channel_id; };
drivers/crypto/chelsio/chcr_crypto.h +83 -7
160 lines not on this page · raw message
Signature · 1 line
1.8.2.3
Herbert Xu
maintainerRe: [PATCH v2 1/9] crypto/chcr:Fix memory corruption done
In reply to Harsh JainQuoted 3 lines · Harsh Jain
Fix memory corruption done by *((u32 *)dec_key + k) operation.
Signed-off-by Jitendra Lulla <[email protected]>
Please don't mix substantial changes with cosmetic ones such as moving a function. This should be split into two patches, the first one being the fix and the second one doing the cosmetic fixup.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt