drivers/net/wireguard/cookie.c

Source file repositories/reference/linux-study-clean/drivers/net/wireguard/cookie.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireguard/cookie.c
Extension
.c
Size
7206 bytes
Lines
237
Domain
Driver Families
Bucket
drivers/net
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 */

#include "cookie.h"
#include "peer.h"
#include "device.h"
#include "messages.h"
#include "ratelimiter.h"
#include "timers.h"

#include <crypto/blake2s.h>
#include <crypto/chacha20poly1305.h>
#include <crypto/utils.h>

#include <net/ipv6.h>

void wg_cookie_checker_init(struct cookie_checker *checker,
			    struct wg_device *wg)
{
	init_rwsem(&checker->secret_lock);
	checker->secret_birthdate = ktime_get_coarse_boottime_ns();
	get_random_bytes(checker->secret, NOISE_HASH_LEN);
	checker->device = wg;
}

enum { COOKIE_KEY_LABEL_LEN = 8 };
static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] __nonstring = "mac1----";
static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] __nonstring = "cookie--";

static void precompute_key(u8 key[NOISE_SYMMETRIC_KEY_LEN],
			   const u8 pubkey[NOISE_PUBLIC_KEY_LEN],
			   const u8 label[COOKIE_KEY_LABEL_LEN])
{
	struct blake2s_ctx blake;

	blake2s_init(&blake, NOISE_SYMMETRIC_KEY_LEN);
	blake2s_update(&blake, label, COOKIE_KEY_LABEL_LEN);
	blake2s_update(&blake, pubkey, NOISE_PUBLIC_KEY_LEN);
	blake2s_final(&blake, key);
}

/* Must hold peer->handshake.static_identity->lock */
void wg_cookie_checker_precompute_device_keys(struct cookie_checker *checker)
{
	if (likely(checker->device->static_identity.has_identity)) {
		precompute_key(checker->cookie_encryption_key,
			       checker->device->static_identity.static_public,
			       cookie_key_label);
		precompute_key(checker->message_mac1_key,
			       checker->device->static_identity.static_public,
			       mac1_key_label);
	} else {
		memset(checker->cookie_encryption_key, 0,
		       NOISE_SYMMETRIC_KEY_LEN);
		memset(checker->message_mac1_key, 0, NOISE_SYMMETRIC_KEY_LEN);
	}
}

void wg_cookie_checker_precompute_peer_keys(struct wg_peer *peer)
{
	precompute_key(peer->latest_cookie.cookie_decryption_key,
		       peer->handshake.remote_static, cookie_key_label);
	precompute_key(peer->latest_cookie.message_mac1_key,
		       peer->handshake.remote_static, mac1_key_label);
}

void wg_cookie_init(struct cookie *cookie)
{
	memset(cookie, 0, sizeof(*cookie));
	init_rwsem(&cookie->lock);
}

static void compute_mac1(u8 mac1[COOKIE_LEN], const void *message, size_t len,
			 const u8 key[NOISE_SYMMETRIC_KEY_LEN])
{
	len = len - sizeof(struct message_macs) +
	      offsetof(struct message_macs, mac1);
	blake2s(key, NOISE_SYMMETRIC_KEY_LEN, message, len, mac1, COOKIE_LEN);
}

static void compute_mac2(u8 mac2[COOKIE_LEN], const void *message, size_t len,
			 const u8 cookie[COOKIE_LEN])
{
	len = len - sizeof(struct message_macs) +
	      offsetof(struct message_macs, mac2);
	blake2s(cookie, COOKIE_LEN, message, len, mac2, COOKIE_LEN);
}

Annotation

Implementation Notes