lib/crypto/tests/hash-test-template.h

Source file repositories/reference/linux-study-clean/lib/crypto/tests/hash-test-template.h

File Facts

System
Linux kernel
Corpus path
lib/crypto/tests/hash-test-template.h
Extension
.h
Size
17587 bytes
Lines
569
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: implementation source
Status
source 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

struct hash_irq_test1_state {
	u8 expected_hashes[IRQ_TEST_NUM_BUFFERS][HASH_SIZE];
	atomic_t seqno;
};

/*
 * Compute the hash of one of the test messages and verify that it matches the
 * expected hash from @state->expected_hashes.  To increase the chance of
 * detecting problems, cycle through multiple messages.
 */
static bool hash_irq_test1_func(void *state_)
{
	struct hash_irq_test1_state *state = state_;
	u32 i = (u32)atomic_inc_return(&state->seqno) % IRQ_TEST_NUM_BUFFERS;
	u8 actual_hash[HASH_SIZE];

	HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN, actual_hash);
	return memcmp(actual_hash, state->expected_hashes[i], HASH_SIZE) == 0;
}

/*
 * Test that if hashes are computed in task, softirq, and hardirq context
 * concurrently, then all results are as expected.
 */
static void test_hash_interrupt_context_1(struct kunit *test)
{
	struct hash_irq_test1_state state = {};

	/* Prepare some test messages and compute the expected hash of each. */
	rand_bytes(test_buf, IRQ_TEST_NUM_BUFFERS * IRQ_TEST_DATA_LEN);
	for (int i = 0; i < IRQ_TEST_NUM_BUFFERS; i++)
		HASH(&test_buf[i * IRQ_TEST_DATA_LEN], IRQ_TEST_DATA_LEN,
		     state.expected_hashes[i]);

	kunit_run_irq_test(test, hash_irq_test1_func, 100000, &state);
}

struct hash_irq_test2_hash_ctx {
	struct HASH_CTX hash_ctx;
	atomic_t in_use;
	int offset;
	int step;
};

struct hash_irq_test2_state {
	struct hash_irq_test2_hash_ctx ctxs[IRQ_TEST_NUM_BUFFERS];
	u8 expected_hash[HASH_SIZE];
	u16 update_lens[32];
	int num_steps;
};

static bool hash_irq_test2_func(void *state_)
{
	struct hash_irq_test2_state *state = state_;
	struct hash_irq_test2_hash_ctx *ctx;
	bool ret = true;

	for (ctx = &state->ctxs[0]; ctx < &state->ctxs[ARRAY_SIZE(state->ctxs)];
	     ctx++) {
		if (atomic_cmpxchg(&ctx->in_use, 0, 1) == 0)
			break;
	}
	if (WARN_ON_ONCE(ctx == &state->ctxs[ARRAY_SIZE(state->ctxs)])) {
		/*
		 * This should never happen, as the number of contexts is equal
		 * to the maximum concurrency level of kunit_run_irq_test().
		 */
		return false;
	}

	if (ctx->step == 0) {
		/* Init step */
		HASH_INIT(&ctx->hash_ctx);
		ctx->offset = 0;
		ctx->step++;
	} else if (ctx->step < state->num_steps - 1) {
		/* Update step */
		HASH_UPDATE(&ctx->hash_ctx, &test_buf[ctx->offset],
			    state->update_lens[ctx->step - 1]);
		ctx->offset += state->update_lens[ctx->step - 1];
		ctx->step++;
	} else {
		/* Final step */
		u8 actual_hash[HASH_SIZE];

		if (WARN_ON_ONCE(ctx->offset != TEST_BUF_LEN))
			ret = false;
		HASH_FINAL(&ctx->hash_ctx, actual_hash);
		if (memcmp(actual_hash, state->expected_hash, HASH_SIZE) != 0)
			ret = false;

Annotation

Implementation Notes