drivers/net/wireguard/noise.c
Source file repositories/reference/linux-study-clean/drivers/net/wireguard/noise.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireguard/noise.c- Extension
.c- Size
- 27779 bytes
- Lines
- 862
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
noise.hdevice.hpeer.hmessages.hqueueing.hpeerlookup.hlinux/rcupdate.hlinux/slab.hlinux/bitmap.hlinux/scatterlist.hlinux/highmem.hcrypto/utils.h
Detected Declarations
function wg_noise_initfunction wg_noise_precompute_static_staticfunction wg_noise_handshake_initfunction handshake_zerofunction wg_noise_handshake_clearfunction keypair_free_rcufunction keypair_free_kreffunction wg_noise_keypair_putfunction wg_noise_keypairs_clearfunction wg_noise_expire_current_peer_keypairsfunction add_new_keypairfunction wg_noise_received_with_keypairfunction rcu_dereference_protectedfunction wg_noise_set_static_identity_private_keyfunction hmacfunction kdffunction derive_keysfunction mix_dhfunction mix_precomputed_dhfunction mix_hashfunction mix_pskfunction handshake_initfunction message_encryptfunction message_decryptfunction message_ephemeralfunction tai64n_nowfunction wg_noise_handshake_create_initiationfunction wg_noise_handshake_consume_initiationfunction wg_noise_handshake_create_responsefunction wg_noise_handshake_consume_responsefunction wg_noise_handshake_begin_session
Annotated Snippet
if (next_keypair) {
/* If there already was a next keypair pending, we
* demote it to be the previous keypair, and free the
* existing current. Note that this means KCI can result
* in this transition. It would perhaps be more sound to
* always just get rid of the unused next keypair
* instead of putting it in the previous slot, but this
* might be a bit less robust. Something to think about
* for the future.
*/
RCU_INIT_POINTER(keypairs->next_keypair, NULL);
rcu_assign_pointer(keypairs->previous_keypair,
next_keypair);
wg_noise_keypair_put(current_keypair, true);
} else /* If there wasn't an existing next keypair, we replace
* the previous with the current one.
*/
rcu_assign_pointer(keypairs->previous_keypair,
current_keypair);
/* At this point we can get rid of the old previous keypair, and
* set up the new keypair.
*/
wg_noise_keypair_put(previous_keypair, true);
rcu_assign_pointer(keypairs->current_keypair, new_keypair);
} else {
/* If we're the responder, it means we can't use the new keypair
* until we receive confirmation via the first data packet, so
* we get rid of the existing previous one, the possibly
* existing next one, and slide in the new next one.
*/
rcu_assign_pointer(keypairs->next_keypair, new_keypair);
wg_noise_keypair_put(next_keypair, true);
RCU_INIT_POINTER(keypairs->previous_keypair, NULL);
wg_noise_keypair_put(previous_keypair, true);
}
spin_unlock_bh(&keypairs->keypair_update_lock);
}
bool wg_noise_received_with_keypair(struct noise_keypairs *keypairs,
struct noise_keypair *received_keypair)
{
struct noise_keypair *old_keypair;
bool key_is_new;
/* We first check without taking the spinlock. */
key_is_new = received_keypair ==
rcu_access_pointer(keypairs->next_keypair);
if (likely(!key_is_new))
return false;
spin_lock_bh(&keypairs->keypair_update_lock);
/* After locking, we double check that things didn't change from
* beneath us.
*/
if (unlikely(received_keypair !=
rcu_dereference_protected(keypairs->next_keypair,
lockdep_is_held(&keypairs->keypair_update_lock)))) {
spin_unlock_bh(&keypairs->keypair_update_lock);
return false;
}
/* When we've finally received the confirmation, we slide the next
* into the current, the current into the previous, and get rid of
* the old previous.
*/
old_keypair = rcu_dereference_protected(keypairs->previous_keypair,
lockdep_is_held(&keypairs->keypair_update_lock));
rcu_assign_pointer(keypairs->previous_keypair,
rcu_dereference_protected(keypairs->current_keypair,
lockdep_is_held(&keypairs->keypair_update_lock)));
wg_noise_keypair_put(old_keypair, true);
rcu_assign_pointer(keypairs->current_keypair, received_keypair);
RCU_INIT_POINTER(keypairs->next_keypair, NULL);
spin_unlock_bh(&keypairs->keypair_update_lock);
return true;
}
/* Must hold static_identity->lock */
void wg_noise_set_static_identity_private_key(
struct noise_static_identity *static_identity,
const u8 private_key[NOISE_PUBLIC_KEY_LEN])
{
memcpy(static_identity->static_private, private_key,
NOISE_PUBLIC_KEY_LEN);
curve25519_clamp_secret(static_identity->static_private);
static_identity->has_identity = curve25519_generate_public(
static_identity->static_public, private_key);
}
Annotation
- Immediate include surface: `noise.h`, `device.h`, `peer.h`, `messages.h`, `queueing.h`, `peerlookup.h`, `linux/rcupdate.h`, `linux/slab.h`.
- Detected declarations: `function wg_noise_init`, `function wg_noise_precompute_static_static`, `function wg_noise_handshake_init`, `function handshake_zero`, `function wg_noise_handshake_clear`, `function keypair_free_rcu`, `function keypair_free_kref`, `function wg_noise_keypair_put`, `function wg_noise_keypairs_clear`, `function wg_noise_expire_current_peer_keypairs`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.