crypto/algapi.c

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

File Facts

System
Linux kernel
Corpus path
crypto/algapi.c
Extension
.c
Size
25143 bytes
Lines
1120
Domain
Kernel Services
Bucket
crypto
Inferred role
Kernel Services: exported/initcall integration point
Status
integration 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

while (!list_empty(spawns)) {
			struct crypto_instance *inst;

			spawn = list_first_entry(spawns, struct crypto_spawn,
						 list);
			inst = spawn->inst;

			list_move(&spawn->list, &stack);
			spawn->dead = !spawn->registered || &inst->alg != nalg;

			if (!spawn->registered)
				break;

			BUG_ON(&inst->alg == alg);

			if (&inst->alg == nalg)
				break;

			spawns = &inst->alg.cra_users;

			/*
			 * Even if spawn->registered is true, the
			 * instance itself may still be unregistered.
			 * This is because it may have failed during
			 * registration.  Therefore we still need to
			 * make the following test.
			 *
			 * We may encounter an unregistered instance here, since
			 * an instance's spawns are set up prior to the instance
			 * being registered.  An unregistered instance will have
			 * NULL ->cra_users.next, since ->cra_users isn't
			 * properly initialized until registration.  But an
			 * unregistered instance cannot have any users, so treat
			 * it the same as ->cra_users being empty.
			 */
			if (spawns->next == NULL)
				break;
		}
	} while ((spawns = crypto_more_spawns(alg, &stack, &top,
					      &secondary_spawns)));

	/*
	 * Remove all instances that are marked as dead.  Also
	 * complete the resurrection of the others by moving them
	 * back to the cra_users list.
	 */
	list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
		if (!spawn->dead)
			list_move(&spawn->list, &spawn->alg->cra_users);
		else if (spawn->registered)
			crypto_remove_instance(spawn->inst, list);
	}
}
EXPORT_SYMBOL_GPL(crypto_remove_spawns);

static void crypto_alg_finish_registration(struct crypto_alg *alg,
					   struct list_head *algs_to_put)
	__must_hold(&crypto_alg_sem)
{
	struct crypto_alg *q;

	list_for_each_entry(q, &crypto_alg_list, cra_list) {
		if (q == alg)
			continue;

		if (crypto_is_moribund(q))
			continue;

		if (crypto_is_larval(q))
			continue;

		if (strcmp(alg->cra_name, q->cra_name))
			continue;

		if (strcmp(alg->cra_driver_name, q->cra_driver_name) &&
		    q->cra_priority > alg->cra_priority)
			continue;

		crypto_remove_spawns(q, algs_to_put, alg);
	}

	crypto_notify(CRYPTO_MSG_ALG_LOADED, alg);
}

static struct crypto_larval *crypto_alloc_test_larval(struct crypto_alg *alg)
{
	struct crypto_larval *larval;

	if (!IS_ENABLED(CONFIG_CRYPTO_SELFTESTS) ||
	    (alg->cra_flags & CRYPTO_ALG_INTERNAL))

Annotation

Implementation Notes