1e7096c13SJason A. Donenfeld /* SPDX-License-Identifier: GPL-2.0 */ 2e7096c13SJason A. Donenfeld /* 3e7096c13SJason A. Donenfeld * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 4e7096c13SJason A. Donenfeld */ 5e7096c13SJason A. Donenfeld 6e7096c13SJason A. Donenfeld #ifndef _WG_MESSAGES_H 7e7096c13SJason A. Donenfeld #define _WG_MESSAGES_H 8e7096c13SJason A. Donenfeld 9e7096c13SJason A. Donenfeld #include <crypto/curve25519.h> 10e7096c13SJason A. Donenfeld #include <crypto/chacha20poly1305.h> 11e7096c13SJason A. Donenfeld #include <crypto/blake2s.h> 12e7096c13SJason A. Donenfeld 13e7096c13SJason A. Donenfeld #include <linux/kernel.h> 14e7096c13SJason A. Donenfeld #include <linux/param.h> 15e7096c13SJason A. Donenfeld #include <linux/skbuff.h> 16e7096c13SJason A. Donenfeld 17e7096c13SJason A. Donenfeld enum noise_lengths { 18e7096c13SJason A. Donenfeld NOISE_PUBLIC_KEY_LEN = CURVE25519_KEY_SIZE, 19e7096c13SJason A. Donenfeld NOISE_SYMMETRIC_KEY_LEN = CHACHA20POLY1305_KEY_SIZE, 20e7096c13SJason A. Donenfeld NOISE_TIMESTAMP_LEN = sizeof(u64) + sizeof(u32), 21e7096c13SJason A. Donenfeld NOISE_AUTHTAG_LEN = CHACHA20POLY1305_AUTHTAG_SIZE, 22e7096c13SJason A. Donenfeld NOISE_HASH_LEN = BLAKE2S_HASH_SIZE 23e7096c13SJason A. Donenfeld }; 24e7096c13SJason A. Donenfeld 25e7096c13SJason A. Donenfeld #define noise_encrypted_len(plain_len) ((plain_len) + NOISE_AUTHTAG_LEN) 26e7096c13SJason A. Donenfeld 27e7096c13SJason A. Donenfeld enum cookie_values { 28e7096c13SJason A. Donenfeld COOKIE_SECRET_MAX_AGE = 2 * 60, 29e7096c13SJason A. Donenfeld COOKIE_SECRET_LATENCY = 5, 30e7096c13SJason A. Donenfeld COOKIE_NONCE_LEN = XCHACHA20POLY1305_NONCE_SIZE, 31e7096c13SJason A. Donenfeld COOKIE_LEN = 16 32e7096c13SJason A. Donenfeld }; 33e7096c13SJason A. Donenfeld 34e7096c13SJason A. Donenfeld enum counter_values { 35*c78a0b4aSJason A. Donenfeld COUNTER_BITS_TOTAL = 8192, 36e7096c13SJason A. Donenfeld COUNTER_REDUNDANT_BITS = BITS_PER_LONG, 37e7096c13SJason A. Donenfeld COUNTER_WINDOW_SIZE = COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS 38e7096c13SJason A. Donenfeld }; 39e7096c13SJason A. Donenfeld 40e7096c13SJason A. Donenfeld enum limits { 41e7096c13SJason A. Donenfeld REKEY_AFTER_MESSAGES = 1ULL << 60, 42e7096c13SJason A. Donenfeld REJECT_AFTER_MESSAGES = U64_MAX - COUNTER_WINDOW_SIZE - 1, 43e7096c13SJason A. Donenfeld REKEY_TIMEOUT = 5, 44e7096c13SJason A. Donenfeld REKEY_TIMEOUT_JITTER_MAX_JIFFIES = HZ / 3, 45e7096c13SJason A. Donenfeld REKEY_AFTER_TIME = 120, 46e7096c13SJason A. Donenfeld REJECT_AFTER_TIME = 180, 47e7096c13SJason A. Donenfeld INITIATIONS_PER_SECOND = 50, 48e7096c13SJason A. Donenfeld MAX_PEERS_PER_DEVICE = 1U << 20, 49e7096c13SJason A. Donenfeld KEEPALIVE_TIMEOUT = 10, 50e7096c13SJason A. Donenfeld MAX_TIMER_HANDSHAKES = 90 / REKEY_TIMEOUT, 51e7096c13SJason A. Donenfeld MAX_QUEUED_INCOMING_HANDSHAKES = 4096, /* TODO: replace this with DQL */ 52e7096c13SJason A. Donenfeld MAX_STAGED_PACKETS = 128, 53e7096c13SJason A. Donenfeld MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */ 54e7096c13SJason A. Donenfeld }; 55e7096c13SJason A. Donenfeld 56e7096c13SJason A. Donenfeld enum message_type { 57e7096c13SJason A. Donenfeld MESSAGE_INVALID = 0, 58e7096c13SJason A. Donenfeld MESSAGE_HANDSHAKE_INITIATION = 1, 59e7096c13SJason A. Donenfeld MESSAGE_HANDSHAKE_RESPONSE = 2, 60e7096c13SJason A. Donenfeld MESSAGE_HANDSHAKE_COOKIE = 3, 61e7096c13SJason A. Donenfeld MESSAGE_DATA = 4 62e7096c13SJason A. Donenfeld }; 63e7096c13SJason A. Donenfeld 64e7096c13SJason A. Donenfeld struct message_header { 65e7096c13SJason A. Donenfeld /* The actual layout of this that we want is: 66e7096c13SJason A. Donenfeld * u8 type 67e7096c13SJason A. Donenfeld * u8 reserved_zero[3] 68e7096c13SJason A. Donenfeld * 69e7096c13SJason A. Donenfeld * But it turns out that by encoding this as little endian, 70e7096c13SJason A. Donenfeld * we achieve the same thing, and it makes checking faster. 71e7096c13SJason A. Donenfeld */ 72e7096c13SJason A. Donenfeld __le32 type; 73e7096c13SJason A. Donenfeld }; 74e7096c13SJason A. Donenfeld 75e7096c13SJason A. Donenfeld struct message_macs { 76e7096c13SJason A. Donenfeld u8 mac1[COOKIE_LEN]; 77e7096c13SJason A. Donenfeld u8 mac2[COOKIE_LEN]; 78e7096c13SJason A. Donenfeld }; 79e7096c13SJason A. Donenfeld 80e7096c13SJason A. Donenfeld struct message_handshake_initiation { 81e7096c13SJason A. Donenfeld struct message_header header; 82e7096c13SJason A. Donenfeld __le32 sender_index; 83e7096c13SJason A. Donenfeld u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; 84e7096c13SJason A. Donenfeld u8 encrypted_static[noise_encrypted_len(NOISE_PUBLIC_KEY_LEN)]; 85e7096c13SJason A. Donenfeld u8 encrypted_timestamp[noise_encrypted_len(NOISE_TIMESTAMP_LEN)]; 86e7096c13SJason A. Donenfeld struct message_macs macs; 87e7096c13SJason A. Donenfeld }; 88e7096c13SJason A. Donenfeld 89e7096c13SJason A. Donenfeld struct message_handshake_response { 90e7096c13SJason A. Donenfeld struct message_header header; 91e7096c13SJason A. Donenfeld __le32 sender_index; 92e7096c13SJason A. Donenfeld __le32 receiver_index; 93e7096c13SJason A. Donenfeld u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; 94e7096c13SJason A. Donenfeld u8 encrypted_nothing[noise_encrypted_len(0)]; 95e7096c13SJason A. Donenfeld struct message_macs macs; 96e7096c13SJason A. Donenfeld }; 97e7096c13SJason A. Donenfeld 98e7096c13SJason A. Donenfeld struct message_handshake_cookie { 99e7096c13SJason A. Donenfeld struct message_header header; 100e7096c13SJason A. Donenfeld __le32 receiver_index; 101e7096c13SJason A. Donenfeld u8 nonce[COOKIE_NONCE_LEN]; 102e7096c13SJason A. Donenfeld u8 encrypted_cookie[noise_encrypted_len(COOKIE_LEN)]; 103e7096c13SJason A. Donenfeld }; 104e7096c13SJason A. Donenfeld 105e7096c13SJason A. Donenfeld struct message_data { 106e7096c13SJason A. Donenfeld struct message_header header; 107e7096c13SJason A. Donenfeld __le32 key_idx; 108e7096c13SJason A. Donenfeld __le64 counter; 109e7096c13SJason A. Donenfeld u8 encrypted_data[]; 110e7096c13SJason A. Donenfeld }; 111e7096c13SJason A. Donenfeld 112e7096c13SJason A. Donenfeld #define message_data_len(plain_len) \ 113e7096c13SJason A. Donenfeld (noise_encrypted_len(plain_len) + sizeof(struct message_data)) 114e7096c13SJason A. Donenfeld 115e7096c13SJason A. Donenfeld enum message_alignments { 116e7096c13SJason A. Donenfeld MESSAGE_PADDING_MULTIPLE = 16, 117e7096c13SJason A. Donenfeld MESSAGE_MINIMUM_LENGTH = message_data_len(0) 118e7096c13SJason A. Donenfeld }; 119e7096c13SJason A. Donenfeld 120e7096c13SJason A. Donenfeld #define SKB_HEADER_LEN \ 121e7096c13SJason A. Donenfeld (max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \ 122e7096c13SJason A. Donenfeld sizeof(struct udphdr) + NET_SKB_PAD) 123e7096c13SJason A. Donenfeld #define DATA_PACKET_HEAD_ROOM \ 124e7096c13SJason A. Donenfeld ALIGN(sizeof(struct message_data) + SKB_HEADER_LEN, 4) 125e7096c13SJason A. Donenfeld 126e7096c13SJason A. Donenfeld enum { HANDSHAKE_DSCP = 0x88 /* AF41, plus 00 ECN */ }; 127e7096c13SJason A. Donenfeld 128e7096c13SJason A. Donenfeld #endif /* _WG_MESSAGES_H */ 129