drivers/crypto/chelsio/chcr_algo.c

Source file repositories/reference/linux-study-clean/drivers/crypto/chelsio/chcr_algo.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/chelsio/chcr_algo.c
Extension
.c
Size
126643 bytes
Lines
4402
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (sg_dma_len(sg) <= skip) {
			skip -= sg_dma_len(sg);
			skip_len = 0;
			sg = sg_next(sg);
		} else {
			skip_len = skip;
			skip = 0;
		}
	}

	while (sg && reqlen) {
		less = min(reqlen, sg_dma_len(sg) - skip_len);
		nents += DIV_ROUND_UP(less, entlen);
		reqlen -= less;
		skip_len = 0;
		sg = sg_next(sg);
	}
	return nents;
}

static inline int get_aead_subtype(struct crypto_aead *aead)
{
	struct aead_alg *alg = crypto_aead_alg(aead);
	struct chcr_alg_template *chcr_crypto_alg =
		container_of(alg, struct chcr_alg_template, alg.aead);
	return chcr_crypto_alg->type & CRYPTO_ALG_SUB_TYPE_MASK;
}

void chcr_verify_tag(struct aead_request *req, u8 *input, int *err)
{
	u8 temp[SHA512_DIGEST_SIZE];
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	int authsize = crypto_aead_authsize(tfm);
	struct cpl_fw6_pld *fw6_pld;
	int cmp = 0;

	fw6_pld = (struct cpl_fw6_pld *)input;
	if ((get_aead_subtype(tfm) == CRYPTO_ALG_SUB_TYPE_AEAD_RFC4106) ||
	    (get_aead_subtype(tfm) == CRYPTO_ALG_SUB_TYPE_AEAD_GCM)) {
		cmp = crypto_memneq(&fw6_pld->data[2], (fw6_pld + 1), authsize);
	} else {

		sg_pcopy_to_buffer(req->src, sg_nents(req->src), temp,
				authsize, req->assoclen +
				req->cryptlen - authsize);
		cmp = crypto_memneq(temp, (fw6_pld + 1), authsize);
	}
	if (cmp)
		*err = -EBADMSG;
	else
		*err = 0;
}

static int chcr_inc_wrcount(struct chcr_dev *dev)
{
	if (dev->state == CHCR_DETACH)
		return 1;
	atomic_inc(&dev->inflight);
	return 0;
}

static inline void chcr_dec_wrcount(struct chcr_dev *dev)
{
	atomic_dec(&dev->inflight);
}

static inline int chcr_handle_aead_resp(struct aead_request *req,
					 unsigned char *input,
					 int err)
{
	struct chcr_aead_reqctx *reqctx = aead_request_ctx_dma(req);
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct chcr_dev *dev = a_ctx(tfm)->dev;

	chcr_aead_common_exit(req);
	if (reqctx->verify == VERIFY_SW) {
		chcr_verify_tag(req, input, &err);
		reqctx->verify = VERIFY_HW;
	}
	chcr_dec_wrcount(dev);
	aead_request_complete(req, err);

	return err;
}

static void get_aes_decrypt_key(unsigned char *dec_key,
				       const unsigned char *key,
				       unsigned int keylength)
{
	u32 temp;

Annotation

Implementation Notes