136 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.4 */5#ifndef _WG_NOISE_H6#define _WG_NOISE_H7 8#include "messages.h"9#include "peerlookup.h"10 11#include <linux/types.h>12#include <linux/spinlock.h>13#include <linux/atomic.h>14#include <linux/rwsem.h>15#include <linux/mutex.h>16#include <linux/kref.h>17 18struct noise_replay_counter {19 u64 counter;20 spinlock_t lock;21 unsigned long backtrack[COUNTER_BITS_TOTAL / BITS_PER_LONG];22};23 24struct noise_symmetric_key {25 u8 key[NOISE_SYMMETRIC_KEY_LEN];26 u64 birthdate;27 bool is_valid;28};29 30struct noise_keypair {31 struct index_hashtable_entry entry;32 struct noise_symmetric_key sending;33 atomic64_t sending_counter;34 struct noise_symmetric_key receiving;35 struct noise_replay_counter receiving_counter;36 __le32 remote_index;37 bool i_am_the_initiator;38 struct kref refcount;39 struct rcu_head rcu;40 u64 internal_id;41};42 43struct noise_keypairs {44 struct noise_keypair __rcu *current_keypair;45 struct noise_keypair __rcu *previous_keypair;46 struct noise_keypair __rcu *next_keypair;47 spinlock_t keypair_update_lock;48};49 50struct noise_static_identity {51 u8 static_public[NOISE_PUBLIC_KEY_LEN];52 u8 static_private[NOISE_PUBLIC_KEY_LEN];53 struct rw_semaphore lock;54 bool has_identity;55};56 57enum noise_handshake_state {58 HANDSHAKE_ZEROED,59 HANDSHAKE_CREATED_INITIATION,60 HANDSHAKE_CONSUMED_INITIATION,61 HANDSHAKE_CREATED_RESPONSE,62 HANDSHAKE_CONSUMED_RESPONSE63};64 65struct noise_handshake {66 struct index_hashtable_entry entry;67 68 enum noise_handshake_state state;69 u64 last_initiation_consumption;70 71 struct noise_static_identity *static_identity;72 73 u8 ephemeral_private[NOISE_PUBLIC_KEY_LEN];74 u8 remote_static[NOISE_PUBLIC_KEY_LEN];75 u8 remote_ephemeral[NOISE_PUBLIC_KEY_LEN];76 u8 precomputed_static_static[NOISE_PUBLIC_KEY_LEN];77 78 u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN];79 80 u8 hash[NOISE_HASH_LEN];81 u8 chaining_key[NOISE_HASH_LEN];82 83 u8 latest_timestamp[NOISE_TIMESTAMP_LEN];84 __le32 remote_index;85 86 /* Protects all members except the immutable (after noise_handshake_87 * init): remote_static, precomputed_static_static, static_identity.88 */89 struct rw_semaphore lock;90};91 92struct wg_device;93 94void wg_noise_init(void);95void wg_noise_handshake_init(struct noise_handshake *handshake,96 struct noise_static_identity *static_identity,97 const u8 peer_public_key[NOISE_PUBLIC_KEY_LEN],98 const u8 peer_preshared_key[NOISE_SYMMETRIC_KEY_LEN],99 struct wg_peer *peer);100void wg_noise_handshake_clear(struct noise_handshake *handshake);101static inline void wg_noise_reset_last_sent_handshake(atomic64_t *handshake_ns)102{103 atomic64_set(handshake_ns, ktime_get_coarse_boottime_ns() -104 (u64)(REKEY_TIMEOUT + 1) * NSEC_PER_SEC);105}106 107void wg_noise_keypair_put(struct noise_keypair *keypair, bool unreference_now);108struct noise_keypair *wg_noise_keypair_get(struct noise_keypair *keypair);109void wg_noise_keypairs_clear(struct noise_keypairs *keypairs);110bool wg_noise_received_with_keypair(struct noise_keypairs *keypairs,111 struct noise_keypair *received_keypair);112void wg_noise_expire_current_peer_keypairs(struct wg_peer *peer);113 114void wg_noise_set_static_identity_private_key(115 struct noise_static_identity *static_identity,116 const u8 private_key[NOISE_PUBLIC_KEY_LEN]);117void wg_noise_precompute_static_static(struct wg_peer *peer);118 119bool120wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,121 struct noise_handshake *handshake);122struct wg_peer *123wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,124 struct wg_device *wg);125 126bool wg_noise_handshake_create_response(struct message_handshake_response *dst,127 struct noise_handshake *handshake);128struct wg_peer *129wg_noise_handshake_consume_response(struct message_handshake_response *src,130 struct wg_device *wg);131 132bool wg_noise_handshake_begin_session(struct noise_handshake *handshake,133 struct noise_keypairs *keypairs);134 135#endif /* _WG_NOISE_H */136