tools/testing/selftests/net/tcp_ao/key-management.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/tcp_ao/key-management.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/tcp_ao/key-management.c
Extension
.c
Size
34253 bytes
Lines
1164
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct test_key {
	char password[TCP_AO_MAXKEYLEN];
	const char *alg;
	unsigned int len;
	uint8_t client_keyid;
	uint8_t server_keyid;
	uint8_t maclen;
	uint8_t matches_client		: 1,
		matches_server		: 1,
		matches_vrf		: 1,
		is_current		: 1,
		is_rnext		: 1,
		used_on_server_tx	: 1,
		used_on_client_tx	: 1,
		skip_counters_checks	: 1;
};

struct key_collection {
	unsigned int nr_keys;
	struct test_key *keys;
};

static struct key_collection collection;

#define TEST_MAX_MACLEN		16
const char *test_algos[] = { "cmac(aes128)", "hmac(sha1)", "hmac(sha256)" };
const unsigned int test_maclens[] = { 1, 4, 12, 16 };
#define MACLEN_SHIFT		2
#define ALGOS_SHIFT		4

static unsigned int make_mask(unsigned int shift, unsigned int prev_shift)
{
	unsigned int ret = BIT(shift) - 1;

	return ret << prev_shift;
}

static void init_key_in_collection(unsigned int index, bool randomized)
{
	struct test_key *key = &collection.keys[index];
	unsigned int algos_index;

	/* Same for randomized and non-randomized test flows */
	key->client_keyid = index;
	key->server_keyid = 127 + index;
	key->matches_client = 1;
	key->matches_server = 1;
	key->matches_vrf = 1;
	/* not really even random, but good enough for a test */
	key->len = rand() % (TCP_AO_MAXKEYLEN - TEST_TCP_AO_MINKEYLEN);
	key->len += TEST_TCP_AO_MINKEYLEN;
	randomize_buffer(key->password, key->len);

	if (randomized) {
		key->maclen = (rand() % TEST_MAX_MACLEN) + 1;
		algos_index = rand();
	} else {
		unsigned int shift = MACLEN_SHIFT;

		key->maclen = test_maclens[index & make_mask(shift, 0)];
		algos_index = index & make_mask(ALGOS_SHIFT, shift);
	}
	key->alg = test_algos[algos_index % ARRAY_SIZE(test_algos)];
}

static int init_default_key_collection(unsigned int nr_keys, bool randomized)
{
	size_t key_sz = sizeof(collection.keys[0]);

	if (!nr_keys) {
		free(collection.keys);
		collection.keys = NULL;
		return 0;
	}

	/*
	 * All keys have uniq sndid/rcvid and sndid != rcvid in order to
	 * check for any bugs/issues for different keyids, visible to both
	 * peers. Keyid == 254 is unused.
	 */
	if (nr_keys > 127)
		test_error("Test requires too many keys, correct the source");

	collection.keys = reallocarray(collection.keys, nr_keys, key_sz);
	if (!collection.keys)
		return -ENOMEM;

	memset(collection.keys, 0, nr_keys * key_sz);
	collection.nr_keys = nr_keys;
	while (nr_keys--)

Annotation

Implementation Notes