18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef _WG_MESSAGES_H 78c2ecf20Sopenharmony_ci#define _WG_MESSAGES_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <crypto/curve25519.h> 108c2ecf20Sopenharmony_ci#include <crypto/chacha20poly1305.h> 118c2ecf20Sopenharmony_ci#include <crypto/blake2s.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/param.h> 158c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cienum noise_lengths { 188c2ecf20Sopenharmony_ci NOISE_PUBLIC_KEY_LEN = CURVE25519_KEY_SIZE, 198c2ecf20Sopenharmony_ci NOISE_SYMMETRIC_KEY_LEN = CHACHA20POLY1305_KEY_SIZE, 208c2ecf20Sopenharmony_ci NOISE_TIMESTAMP_LEN = sizeof(u64) + sizeof(u32), 218c2ecf20Sopenharmony_ci NOISE_AUTHTAG_LEN = CHACHA20POLY1305_AUTHTAG_SIZE, 228c2ecf20Sopenharmony_ci NOISE_HASH_LEN = BLAKE2S_HASH_SIZE 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define noise_encrypted_len(plain_len) ((plain_len) + NOISE_AUTHTAG_LEN) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cienum cookie_values { 288c2ecf20Sopenharmony_ci COOKIE_SECRET_MAX_AGE = 2 * 60, 298c2ecf20Sopenharmony_ci COOKIE_SECRET_LATENCY = 5, 308c2ecf20Sopenharmony_ci COOKIE_NONCE_LEN = XCHACHA20POLY1305_NONCE_SIZE, 318c2ecf20Sopenharmony_ci COOKIE_LEN = 16 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cienum counter_values { 358c2ecf20Sopenharmony_ci COUNTER_BITS_TOTAL = 8192, 368c2ecf20Sopenharmony_ci COUNTER_REDUNDANT_BITS = BITS_PER_LONG, 378c2ecf20Sopenharmony_ci COUNTER_WINDOW_SIZE = COUNTER_BITS_TOTAL - COUNTER_REDUNDANT_BITS 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cienum limits { 418c2ecf20Sopenharmony_ci REKEY_AFTER_MESSAGES = 1ULL << 60, 428c2ecf20Sopenharmony_ci REJECT_AFTER_MESSAGES = U64_MAX - COUNTER_WINDOW_SIZE - 1, 438c2ecf20Sopenharmony_ci REKEY_TIMEOUT = 5, 448c2ecf20Sopenharmony_ci REKEY_TIMEOUT_JITTER_MAX_JIFFIES = HZ / 3, 458c2ecf20Sopenharmony_ci REKEY_AFTER_TIME = 120, 468c2ecf20Sopenharmony_ci REJECT_AFTER_TIME = 180, 478c2ecf20Sopenharmony_ci INITIATIONS_PER_SECOND = 50, 488c2ecf20Sopenharmony_ci MAX_PEERS_PER_DEVICE = 1U << 20, 498c2ecf20Sopenharmony_ci KEEPALIVE_TIMEOUT = 10, 508c2ecf20Sopenharmony_ci MAX_TIMER_HANDSHAKES = 90 / REKEY_TIMEOUT, 518c2ecf20Sopenharmony_ci MAX_QUEUED_INCOMING_HANDSHAKES = 4096, /* TODO: replace this with DQL */ 528c2ecf20Sopenharmony_ci MAX_STAGED_PACKETS = 128, 538c2ecf20Sopenharmony_ci MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */ 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cienum message_type { 578c2ecf20Sopenharmony_ci MESSAGE_INVALID = 0, 588c2ecf20Sopenharmony_ci MESSAGE_HANDSHAKE_INITIATION = 1, 598c2ecf20Sopenharmony_ci MESSAGE_HANDSHAKE_RESPONSE = 2, 608c2ecf20Sopenharmony_ci MESSAGE_HANDSHAKE_COOKIE = 3, 618c2ecf20Sopenharmony_ci MESSAGE_DATA = 4 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistruct message_header { 658c2ecf20Sopenharmony_ci /* The actual layout of this that we want is: 668c2ecf20Sopenharmony_ci * u8 type 678c2ecf20Sopenharmony_ci * u8 reserved_zero[3] 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * But it turns out that by encoding this as little endian, 708c2ecf20Sopenharmony_ci * we achieve the same thing, and it makes checking faster. 718c2ecf20Sopenharmony_ci */ 728c2ecf20Sopenharmony_ci __le32 type; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct message_macs { 768c2ecf20Sopenharmony_ci u8 mac1[COOKIE_LEN]; 778c2ecf20Sopenharmony_ci u8 mac2[COOKIE_LEN]; 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistruct message_handshake_initiation { 818c2ecf20Sopenharmony_ci struct message_header header; 828c2ecf20Sopenharmony_ci __le32 sender_index; 838c2ecf20Sopenharmony_ci u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; 848c2ecf20Sopenharmony_ci u8 encrypted_static[noise_encrypted_len(NOISE_PUBLIC_KEY_LEN)]; 858c2ecf20Sopenharmony_ci u8 encrypted_timestamp[noise_encrypted_len(NOISE_TIMESTAMP_LEN)]; 868c2ecf20Sopenharmony_ci struct message_macs macs; 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistruct message_handshake_response { 908c2ecf20Sopenharmony_ci struct message_header header; 918c2ecf20Sopenharmony_ci __le32 sender_index; 928c2ecf20Sopenharmony_ci __le32 receiver_index; 938c2ecf20Sopenharmony_ci u8 unencrypted_ephemeral[NOISE_PUBLIC_KEY_LEN]; 948c2ecf20Sopenharmony_ci u8 encrypted_nothing[noise_encrypted_len(0)]; 958c2ecf20Sopenharmony_ci struct message_macs macs; 968c2ecf20Sopenharmony_ci}; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistruct message_handshake_cookie { 998c2ecf20Sopenharmony_ci struct message_header header; 1008c2ecf20Sopenharmony_ci __le32 receiver_index; 1018c2ecf20Sopenharmony_ci u8 nonce[COOKIE_NONCE_LEN]; 1028c2ecf20Sopenharmony_ci u8 encrypted_cookie[noise_encrypted_len(COOKIE_LEN)]; 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistruct message_data { 1068c2ecf20Sopenharmony_ci struct message_header header; 1078c2ecf20Sopenharmony_ci __le32 key_idx; 1088c2ecf20Sopenharmony_ci __le64 counter; 1098c2ecf20Sopenharmony_ci u8 encrypted_data[]; 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define message_data_len(plain_len) \ 1138c2ecf20Sopenharmony_ci (noise_encrypted_len(plain_len) + sizeof(struct message_data)) 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cienum message_alignments { 1168c2ecf20Sopenharmony_ci MESSAGE_PADDING_MULTIPLE = 16, 1178c2ecf20Sopenharmony_ci MESSAGE_MINIMUM_LENGTH = message_data_len(0) 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define SKB_HEADER_LEN \ 1218c2ecf20Sopenharmony_ci (max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \ 1228c2ecf20Sopenharmony_ci sizeof(struct udphdr) + NET_SKB_PAD) 1238c2ecf20Sopenharmony_ci#define DATA_PACKET_HEAD_ROOM \ 1248c2ecf20Sopenharmony_ci ALIGN(sizeof(struct message_data) + SKB_HEADER_LEN, 4) 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cienum { HANDSHAKE_DSCP = 0x88 /* AF41, plus 00 ECN */ }; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#endif /* _WG_MESSAGES_H */ 129