linux/drivers/net/wireguard/noise.h
<<
>>
Prefs
   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_H
   6#define _WG_NOISE_H
   7
   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_RESPONSE
  63};
  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
 119bool
 120wg_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