162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _WG_MESSAGES_H 762306a36Sopenharmony_ci#define _WG_MESSAGES_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <crypto/curve25519.h> 1062306a36Sopenharmony_ci#include <crypto/chacha20poly1305.h> 1162306a36Sopenharmony_ci#include <crypto/blake2s.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/param.h> 1562306a36Sopenharmony_ci#include <linux/skbuff.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cienum noise_lengths { 1862306a36Sopenharmony_ci NOISE_PUBLIC_KEY_LEN = CURVE25519_KEY_SIZE, 1962306a36Sopenharmony_ci NOISE_SYMMETRIC_KEY_LEN = CHACHA20POLY1305_KEY_SIZE, 2062306a36Sopenharmony_ci NOISE_TIMESTAMP_LEN = sizeof(u64) + sizeof(u32), 2162306a36Sopenharmony_ci NOISE_AUTHTAG_LEN = CHACHA20POLY1305_AUTHTAG_SIZE, 2262306a36Sopenharmony_ci NOISE_HASH_LEN = BLAKE2S_HASH_SIZE 2362306a36Sopenharmony_ci}; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define noise_encrypted_len(plain_len) ((plain_len) + NOISE_AUTHTAG_LEN) 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cienum cookie_values { 2862306a36Sopenharmony_ci COOKIE_SECRET_MAX_AGE = 2 * 60, 2962306a36Sopenharmony_ci COOKIE_SECRET_LATENCY = 5, 3062306a36Sopenharmony_ci COOKIE_NONCE_LEN = XCHACHA20POLY1305_NONCE_SIZE, 3162306a36Sopenharmony_ci COOKIE_LEN = 16 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cienum counter_values { 3562306a36Sopenharmony_ci COUNTER_BITS_TOTAL = 8192, 3662306a36Sopenharmony_ci COUNTER_REDUNDANT_BITS = BITS_PER_LONG, 3762306a36Sopenharmony_ci COUNTER_WINDOW_SIZE = COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS 3862306a36Sopenharmony_ci}; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cienum limits { 4162306a36Sopenharmony_ci REKEY_AFTER_MESSAGES = 1ULL << 60, 4262306a36Sopenharmony_ci REJECT_AFTER_MESSAGES = U64_MAX - COUNTER_WINDOW_SIZE - 1, 4362306a36Sopenharmony_ci REKEY_TIMEOUT = 5, 4462306a36Sopenharmony_ci REKEY_TIMEOUT_JITTER_MAX_JIFFIES = HZ / 3, 4562306a36Sopenharmony_ci REKEY_AFTER_TIME = 120, 4662306a36Sopenharmony_ci REJECT_AFTER_TIME = 180, 4762306a36Sopenharmony_ci INITIATIONS_PER_SECOND = 50, 4862306a36Sopenharmony_ci MAX_PEERS_PER_DEVICE = 1U << 20, 4962306a36Sopenharmony_ci KEEPALIVE_TIMEOUT = 10, 5062306a36Sopenharmony_ci MAX_TIMER_HANDSHAKES = 90 / REKEY_TIMEOUT, 5162306a36Sopenharmony_ci MAX_QUEUED_INCOMING_HANDSHAKES = 4096, /* TODO: replace this with DQL */ 5262306a36Sopenharmony_ci MAX_STAGED_PACKETS = 128, 5362306a36Sopenharmony_ci MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */ 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cienum message_type { 5762306a36Sopenharmony_ci MESSAGE_INVALID = 0, 5862306a36Sopenharmony_ci MESSAGE_HANDSHAKE_INITIATION = 1, 5962306a36Sopenharmony_ci MESSAGE_HANDSHAKE_RESPONSE = 2, 6062306a36Sopenharmony_ci MESSAGE_HANDSHAKE_COOKIE = 3, 6162306a36Sopenharmony_ci MESSAGE_DATA = 4 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistruct message_header { 6562306a36Sopenharmony_ci /* The actual layout of this that we want is: 6662306a36Sopenharmony_ci * u8 type 6762306a36Sopenharmony_ci * u8 reserved_zero[3] 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * But it turns out that by encoding this as little endian, 7062306a36Sopenharmony_ci * we achieve the same thing, and it makes checking faster. 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_ci __le32 type; 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistruct message_macs { 7662306a36Sopenharmony_ci u8 mac1[COOKIE_LEN]; 7762306a36Sopenharmony_ci u8 mac2[COOKIE_LEN]; 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistruct message_handshake_initiation { 8162306a36Sopenharmony_ci struct message_header header; 8262306a36Sopenharmony_ci __le32 sender_index; 8362306a36Sopenharmony_ci u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; 8462306a36Sopenharmony_ci u8 encrypted_static[noise_encrypted_len(NOISE_PUBLIC_KEY_LEN)]; 8562306a36Sopenharmony_ci u8 encrypted_timestamp[noise_encrypted_len(NOISE_TIMESTAMP_LEN)]; 8662306a36Sopenharmony_ci struct message_macs macs; 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistruct message_handshake_response { 9062306a36Sopenharmony_ci struct message_header header; 9162306a36Sopenharmony_ci __le32 sender_index; 9262306a36Sopenharmony_ci __le32 receiver_index; 9362306a36Sopenharmony_ci u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; 9462306a36Sopenharmony_ci u8 encrypted_nothing[noise_encrypted_len(0)]; 9562306a36Sopenharmony_ci struct message_macs macs; 9662306a36Sopenharmony_ci}; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistruct message_handshake_cookie { 9962306a36Sopenharmony_ci struct message_header header; 10062306a36Sopenharmony_ci __le32 receiver_index; 10162306a36Sopenharmony_ci u8 nonce[COOKIE_NONCE_LEN]; 10262306a36Sopenharmony_ci u8 encrypted_cookie[noise_encrypted_len(COOKIE_LEN)]; 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistruct message_data { 10662306a36Sopenharmony_ci struct message_header header; 10762306a36Sopenharmony_ci __le32 key_idx; 10862306a36Sopenharmony_ci __le64 counter; 10962306a36Sopenharmony_ci u8 encrypted_data[]; 11062306a36Sopenharmony_ci}; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci#define message_data_len(plain_len) \ 11362306a36Sopenharmony_ci (noise_encrypted_len(plain_len) + sizeof(struct message_data)) 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cienum message_alignments { 11662306a36Sopenharmony_ci MESSAGE_PADDING_MULTIPLE = 16, 11762306a36Sopenharmony_ci MESSAGE_MINIMUM_LENGTH = message_data_len(0) 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci#define SKB_HEADER_LEN \ 12162306a36Sopenharmony_ci (max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \ 12262306a36Sopenharmony_ci sizeof(struct udphdr) + NET_SKB_PAD) 12362306a36Sopenharmony_ci#define DATA_PACKET_HEAD_ROOM \ 12462306a36Sopenharmony_ci ALIGN(sizeof(struct message_data) + SKB_HEADER_LEN, 4) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cienum { HANDSHAKE_DSCP = 0x88 /* AF41, plus 00 ECN */ }; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#endif /* _WG_MESSAGES_H */ 129