crypto/algif_rng.c

Source file repositories/reference/linux-study-clean/crypto/algif_rng.c

File Facts

System
Linux kernel
Corpus path
crypto/algif_rng.c
Extension
.c
Size
8514 bytes
Lines
340
Domain
Kernel Services
Bucket
crypto
Inferred role
Kernel Services: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct proto_ops algif_rng_ops = {
	.family		=	PF_ALG,

	.connect	=	sock_no_connect,
	.socketpair	=	sock_no_socketpair,
	.getname	=	sock_no_getname,
	.ioctl		=	sock_no_ioctl,
	.listen		=	sock_no_listen,
	.shutdown	=	sock_no_shutdown,
	.mmap		=	sock_no_mmap,
	.bind		=	sock_no_bind,
	.accept		=	sock_no_accept,
	.sendmsg	=	sock_no_sendmsg,

	.release	=	af_alg_release,
	.recvmsg	=	rng_recvmsg,
};

static struct proto_ops __maybe_unused algif_rng_test_ops = {
	.family		=	PF_ALG,

	.connect	=	sock_no_connect,
	.socketpair	=	sock_no_socketpair,
	.getname	=	sock_no_getname,
	.ioctl		=	sock_no_ioctl,
	.listen		=	sock_no_listen,
	.shutdown	=	sock_no_shutdown,
	.mmap		=	sock_no_mmap,
	.bind		=	sock_no_bind,
	.accept		=	sock_no_accept,

	.release	=	af_alg_release,
	.recvmsg	=	rng_test_recvmsg,
	.sendmsg	=	rng_test_sendmsg,
};

static void *rng_bind(const char *name)
{
	struct rng_parent_ctx *pctx;
	struct crypto_rng *rng;

	pctx = kzalloc_obj(*pctx);
	if (!pctx)
		return ERR_PTR(-ENOMEM);

	rng = crypto_alloc_rng(name, 0, AF_ALG_CRYPTOAPI_MASK);
	if (IS_ERR(rng)) {
		kfree(pctx);
		return ERR_CAST(rng);
	}

	pctx->drng = rng;
	return pctx;
}

static void rng_release(void *private)
{
	struct rng_parent_ctx *pctx = private;

	if (unlikely(!pctx))
		return;
	crypto_free_rng(pctx->drng);
	kfree_sensitive(pctx->entropy);
	kfree_sensitive(pctx);
}

static void rng_sock_destruct(struct sock *sk)
{
	struct alg_sock *ask = alg_sk(sk);
	struct rng_ctx *ctx = ask->private;

	rng_reset_addtl(ctx);
	sock_kfree_s(sk, ctx, ctx->len);
	af_alg_release_parent(sk);
}

static int rng_accept_parent(void *private, struct sock *sk)
{
	struct rng_ctx *ctx;
	struct rng_parent_ctx *pctx = private;
	struct alg_sock *ask = alg_sk(sk);
	unsigned int len = sizeof(*ctx);

	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	memset(ctx, 0, len);
	ctx->len = len;

Annotation

Implementation Notes