drivers/crypto/cavium/nitrox/nitrox_skcipher.c

Source file repositories/reference/linux-study-clean/drivers/crypto/cavium/nitrox/nitrox_skcipher.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/cavium/nitrox/nitrox_skcipher.c
Extension
.c
Size
14125 bytes
Lines
532
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

struct nitrox_cipher {
	const char *name;
	enum flexi_cipher value;
};

/*
 * supported cipher list
 */
static const struct nitrox_cipher flexi_cipher_table[] = {
	{ "null",		CIPHER_NULL },
	{ "cbc(des3_ede)",	CIPHER_3DES_CBC },
	{ "ecb(des3_ede)",	CIPHER_3DES_ECB },
	{ "cbc(aes)",		CIPHER_AES_CBC },
	{ "ecb(aes)",		CIPHER_AES_ECB },
	{ "cfb(aes)",		CIPHER_AES_CFB },
	{ "rfc3686(ctr(aes))",	CIPHER_AES_CTR },
	{ "xts(aes)",		CIPHER_AES_XTS },
	{ "cts(cbc(aes))",	CIPHER_AES_CBC_CTS },
	{ NULL,			CIPHER_INVALID }
};

static enum flexi_cipher flexi_cipher_type(const char *name)
{
	const struct nitrox_cipher *cipher = flexi_cipher_table;

	while (cipher->name) {
		if (!strcmp(cipher->name, name))
			break;
		cipher++;
	}
	return cipher->value;
}

static void free_src_sglist(struct skcipher_request *skreq)
{
	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);

	kfree(nkreq->src);
}

static void free_dst_sglist(struct skcipher_request *skreq)
{
	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);

	kfree(nkreq->dst);
}

static void nitrox_skcipher_callback(void *arg, int err)
{
	struct skcipher_request *skreq = arg;

	free_src_sglist(skreq);
	free_dst_sglist(skreq);
	if (err) {
		pr_err_ratelimited("request failed status 0x%0x\n", err);
		err = -EINVAL;
	}

	skcipher_request_complete(skreq, err);
}

static void nitrox_cbc_cipher_callback(void *arg, int err)
{
	struct skcipher_request *skreq = arg;
	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq);
	int ivsize = crypto_skcipher_ivsize(cipher);
	unsigned int start = skreq->cryptlen - ivsize;

	if (err) {
		nitrox_skcipher_callback(arg, err);
		return;
	}

	if (nkreq->creq.ctrl.s.arg == ENCRYPT) {
		scatterwalk_map_and_copy(skreq->iv, skreq->dst, start, ivsize,
					 0);
	} else {
		if (skreq->src != skreq->dst) {
			scatterwalk_map_and_copy(skreq->iv, skreq->src, start,
						 ivsize, 0);
		} else {
			memcpy(skreq->iv, nkreq->iv_out, ivsize);
			kfree(nkreq->iv_out);
		}
	}

	nitrox_skcipher_callback(arg, err);
}

Annotation

Implementation Notes