Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
0004  */
0005 
0006 #ifndef _WG_MESSAGES_H
0007 #define _WG_MESSAGES_H
0008 
0009 #include <crypto/curve25519.h>
0010 #include <crypto/chacha20poly1305.h>
0011 #include <crypto/blake2s.h>
0012 
0013 #include <linux/kernel.h>
0014 #include <linux/param.h>
0015 #include <linux/skbuff.h>
0016 
0017 enum noise_lengths {
0018     NOISE_PUBLIC_KEY_LEN = CURVE25519_KEY_SIZE,
0019     NOISE_SYMMETRIC_KEY_LEN = CHACHA20POLY1305_KEY_SIZE,
0020     NOISE_TIMESTAMP_LEN = sizeof(u64) + sizeof(u32),
0021     NOISE_AUTHTAG_LEN = CHACHA20POLY1305_AUTHTAG_SIZE,
0022     NOISE_HASH_LEN = BLAKE2S_HASH_SIZE
0023 };
0024 
0025 #define noise_encrypted_len(plain_len) ((plain_len) + NOISE_AUTHTAG_LEN)
0026 
0027 enum cookie_values {
0028     COOKIE_SECRET_MAX_AGE = 2 * 60,
0029     COOKIE_SECRET_LATENCY = 5,
0030     COOKIE_NONCE_LEN = XCHACHA20POLY1305_NONCE_SIZE,
0031     COOKIE_LEN = 16
0032 };
0033 
0034 enum counter_values {
0035     COUNTER_BITS_TOTAL = 8192,
0036     COUNTER_REDUNDANT_BITS = BITS_PER_LONG,
0037     COUNTER_WINDOW_SIZE = COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS
0038 };
0039 
0040 enum limits {
0041     REKEY_AFTER_MESSAGES = 1ULL << 60,
0042     REJECT_AFTER_MESSAGES = U64_MAX - COUNTER_WINDOW_SIZE - 1,
0043     REKEY_TIMEOUT = 5,
0044     REKEY_TIMEOUT_JITTER_MAX_JIFFIES = HZ / 3,
0045     REKEY_AFTER_TIME = 120,
0046     REJECT_AFTER_TIME = 180,
0047     INITIATIONS_PER_SECOND = 50,
0048     MAX_PEERS_PER_DEVICE = 1U << 20,
0049     KEEPALIVE_TIMEOUT = 10,
0050     MAX_TIMER_HANDSHAKES = 90 / REKEY_TIMEOUT,
0051     MAX_QUEUED_INCOMING_HANDSHAKES = 4096, /* TODO: replace this with DQL */
0052     MAX_STAGED_PACKETS = 128,
0053     MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */
0054 };
0055 
0056 enum message_type {
0057     MESSAGE_INVALID = 0,
0058     MESSAGE_HANDSHAKE_INITIATION = 1,
0059     MESSAGE_HANDSHAKE_RESPONSE = 2,
0060     MESSAGE_HANDSHAKE_COOKIE = 3,
0061     MESSAGE_DATA = 4
0062 };
0063 
0064 struct message_header {
0065     /* The actual layout of this that we want is:
0066      * u8 type
0067      * u8 reserved_zero[3]
0068      *
0069      * But it turns out that by encoding this as little endian,
0070      * we achieve the same thing, and it makes checking faster.
0071      */
0072     __le32 type;
0073 };
0074 
0075 struct message_macs {
0076     u8 mac1[COOKIE_LEN];
0077     u8 mac2[COOKIE_LEN];
0078 };
0079 
0080 struct message_handshake_initiation {
0081     struct message_header header;
0082     __le32 sender_index;
0083     u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN];
0084     u8 encrypted_static[noise_encrypted_len(NOISE_PUBLIC_KEY_LEN)];
0085     u8 encrypted_timestamp[noise_encrypted_len(NOISE_TIMESTAMP_LEN)];
0086     struct message_macs macs;
0087 };
0088 
0089 struct message_handshake_response {
0090     struct message_header header;
0091     __le32 sender_index;
0092     __le32 receiver_index;
0093     u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN];
0094     u8 encrypted_nothing[noise_encrypted_len(0)];
0095     struct message_macs macs;
0096 };
0097 
0098 struct message_handshake_cookie {
0099     struct message_header header;
0100     __le32 receiver_index;
0101     u8 nonce[COOKIE_NONCE_LEN];
0102     u8 encrypted_cookie[noise_encrypted_len(COOKIE_LEN)];
0103 };
0104 
0105 struct message_data {
0106     struct message_header header;
0107     __le32 key_idx;
0108     __le64 counter;
0109     u8 encrypted_data[];
0110 };
0111 
0112 #define message_data_len(plain_len) \
0113     (noise_encrypted_len(plain_len) + sizeof(struct message_data))
0114 
0115 enum message_alignments {
0116     MESSAGE_PADDING_MULTIPLE = 16,
0117     MESSAGE_MINIMUM_LENGTH = message_data_len(0)
0118 };
0119 
0120 #define SKB_HEADER_LEN                                       \
0121     (max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \
0122      sizeof(struct udphdr) + NET_SKB_PAD)
0123 #define DATA_PACKET_HEAD_ROOM \
0124     ALIGN(sizeof(struct message_data) + SKB_HEADER_LEN, 4)
0125 
0126 enum { HANDSHAKE_DSCP = 0x88 /* AF41, plus 00 ECN */ };
0127 
0128 #endif /* _WG_MESSAGES_H */