cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cookie.c (7187B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
      4 */
      5
      6#include "cookie.h"
      7#include "peer.h"
      8#include "device.h"
      9#include "messages.h"
     10#include "ratelimiter.h"
     11#include "timers.h"
     12
     13#include <crypto/blake2s.h>
     14#include <crypto/chacha20poly1305.h>
     15
     16#include <net/ipv6.h>
     17#include <crypto/algapi.h>
     18
     19void wg_cookie_checker_init(struct cookie_checker *checker,
     20			    struct wg_device *wg)
     21{
     22	init_rwsem(&checker->secret_lock);
     23	checker->secret_birthdate = ktime_get_coarse_boottime_ns();
     24	get_random_bytes(checker->secret, NOISE_HASH_LEN);
     25	checker->device = wg;
     26}
     27
     28enum { COOKIE_KEY_LABEL_LEN = 8 };
     29static const u8 mac1_key_label[COOKIE_KEY_LABEL_LEN] = "mac1----";
     30static const u8 cookie_key_label[COOKIE_KEY_LABEL_LEN] = "cookie--";
     31
     32static void precompute_key(u8 key[NOISE_SYMMETRIC_KEY_LEN],
     33			   const u8 pubkey[NOISE_PUBLIC_KEY_LEN],
     34			   const u8 label[COOKIE_KEY_LABEL_LEN])
     35{
     36	struct blake2s_state blake;
     37
     38	blake2s_init(&blake, NOISE_SYMMETRIC_KEY_LEN);
     39	blake2s_update(&blake, label, COOKIE_KEY_LABEL_LEN);
     40	blake2s_update(&blake, pubkey, NOISE_PUBLIC_KEY_LEN);
     41	blake2s_final(&blake, key);
     42}
     43
     44/* Must hold peer->handshake.static_identity->lock */
     45void wg_cookie_checker_precompute_device_keys(struct cookie_checker *checker)
     46{
     47	if (likely(checker->device->static_identity.has_identity)) {
     48		precompute_key(checker->cookie_encryption_key,
     49			       checker->device->static_identity.static_public,
     50			       cookie_key_label);
     51		precompute_key(checker->message_mac1_key,
     52			       checker->device->static_identity.static_public,
     53			       mac1_key_label);
     54	} else {
     55		memset(checker->cookie_encryption_key, 0,
     56		       NOISE_SYMMETRIC_KEY_LEN);
     57		memset(checker->message_mac1_key, 0, NOISE_SYMMETRIC_KEY_LEN);
     58	}
     59}
     60
     61void wg_cookie_checker_precompute_peer_keys(struct wg_peer *peer)
     62{
     63	precompute_key(peer->latest_cookie.cookie_decryption_key,
     64		       peer->handshake.remote_static, cookie_key_label);
     65	precompute_key(peer->latest_cookie.message_mac1_key,
     66		       peer->handshake.remote_static, mac1_key_label);
     67}
     68
     69void wg_cookie_init(struct cookie *cookie)
     70{
     71	memset(cookie, 0, sizeof(*cookie));
     72	init_rwsem(&cookie->lock);
     73}
     74
     75static void compute_mac1(u8 mac1[COOKIE_LEN], const void *message, size_t len,
     76			 const u8 key[NOISE_SYMMETRIC_KEY_LEN])
     77{
     78	len = len - sizeof(struct message_macs) +
     79	      offsetof(struct message_macs, mac1);
     80	blake2s(mac1, message, key, COOKIE_LEN, len, NOISE_SYMMETRIC_KEY_LEN);
     81}
     82
     83static void compute_mac2(u8 mac2[COOKIE_LEN], const void *message, size_t len,
     84			 const u8 cookie[COOKIE_LEN])
     85{
     86	len = len - sizeof(struct message_macs) +
     87	      offsetof(struct message_macs, mac2);
     88	blake2s(mac2, message, cookie, COOKIE_LEN, len, COOKIE_LEN);
     89}
     90
     91static void make_cookie(u8 cookie[COOKIE_LEN], struct sk_buff *skb,
     92			struct cookie_checker *checker)
     93{
     94	struct blake2s_state state;
     95
     96	if (wg_birthdate_has_expired(checker->secret_birthdate,
     97				     COOKIE_SECRET_MAX_AGE)) {
     98		down_write(&checker->secret_lock);
     99		checker->secret_birthdate = ktime_get_coarse_boottime_ns();
    100		get_random_bytes(checker->secret, NOISE_HASH_LEN);
    101		up_write(&checker->secret_lock);
    102	}
    103
    104	down_read(&checker->secret_lock);
    105
    106	blake2s_init_key(&state, COOKIE_LEN, checker->secret, NOISE_HASH_LEN);
    107	if (skb->protocol == htons(ETH_P_IP))
    108		blake2s_update(&state, (u8 *)&ip_hdr(skb)->saddr,
    109			       sizeof(struct in_addr));
    110	else if (skb->protocol == htons(ETH_P_IPV6))
    111		blake2s_update(&state, (u8 *)&ipv6_hdr(skb)->saddr,
    112			       sizeof(struct in6_addr));
    113	blake2s_update(&state, (u8 *)&udp_hdr(skb)->source, sizeof(__be16));
    114	blake2s_final(&state, cookie);
    115
    116	up_read(&checker->secret_lock);
    117}
    118
    119enum cookie_mac_state wg_cookie_validate_packet(struct cookie_checker *checker,
    120						struct sk_buff *skb,
    121						bool check_cookie)
    122{
    123	struct message_macs *macs = (struct message_macs *)
    124		(skb->data + skb->len - sizeof(*macs));
    125	enum cookie_mac_state ret;
    126	u8 computed_mac[COOKIE_LEN];
    127	u8 cookie[COOKIE_LEN];
    128
    129	ret = INVALID_MAC;
    130	compute_mac1(computed_mac, skb->data, skb->len,
    131		     checker->message_mac1_key);
    132	if (crypto_memneq(computed_mac, macs->mac1, COOKIE_LEN))
    133		goto out;
    134
    135	ret = VALID_MAC_BUT_NO_COOKIE;
    136
    137	if (!check_cookie)
    138		goto out;
    139
    140	make_cookie(cookie, skb, checker);
    141
    142	compute_mac2(computed_mac, skb->data, skb->len, cookie);
    143	if (crypto_memneq(computed_mac, macs->mac2, COOKIE_LEN))
    144		goto out;
    145
    146	ret = VALID_MAC_WITH_COOKIE_BUT_RATELIMITED;
    147	if (!wg_ratelimiter_allow(skb, dev_net(checker->device->dev)))
    148		goto out;
    149
    150	ret = VALID_MAC_WITH_COOKIE;
    151
    152out:
    153	return ret;
    154}
    155
    156void wg_cookie_add_mac_to_packet(void *message, size_t len,
    157				 struct wg_peer *peer)
    158{
    159	struct message_macs *macs = (struct message_macs *)
    160		((u8 *)message + len - sizeof(*macs));
    161
    162	down_write(&peer->latest_cookie.lock);
    163	compute_mac1(macs->mac1, message, len,
    164		     peer->latest_cookie.message_mac1_key);
    165	memcpy(peer->latest_cookie.last_mac1_sent, macs->mac1, COOKIE_LEN);
    166	peer->latest_cookie.have_sent_mac1 = true;
    167	up_write(&peer->latest_cookie.lock);
    168
    169	down_read(&peer->latest_cookie.lock);
    170	if (peer->latest_cookie.is_valid &&
    171	    !wg_birthdate_has_expired(peer->latest_cookie.birthdate,
    172				COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY))
    173		compute_mac2(macs->mac2, message, len,
    174			     peer->latest_cookie.cookie);
    175	else
    176		memset(macs->mac2, 0, COOKIE_LEN);
    177	up_read(&peer->latest_cookie.lock);
    178}
    179
    180void wg_cookie_message_create(struct message_handshake_cookie *dst,
    181			      struct sk_buff *skb, __le32 index,
    182			      struct cookie_checker *checker)
    183{
    184	struct message_macs *macs = (struct message_macs *)
    185		((u8 *)skb->data + skb->len - sizeof(*macs));
    186	u8 cookie[COOKIE_LEN];
    187
    188	dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE);
    189	dst->receiver_index = index;
    190	get_random_bytes_wait(dst->nonce, COOKIE_NONCE_LEN);
    191
    192	make_cookie(cookie, skb, checker);
    193	xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN,
    194				  macs->mac1, COOKIE_LEN, dst->nonce,
    195				  checker->cookie_encryption_key);
    196}
    197
    198void wg_cookie_message_consume(struct message_handshake_cookie *src,
    199			       struct wg_device *wg)
    200{
    201	struct wg_peer *peer = NULL;
    202	u8 cookie[COOKIE_LEN];
    203	bool ret;
    204
    205	if (unlikely(!wg_index_hashtable_lookup(wg->index_hashtable,
    206						INDEX_HASHTABLE_HANDSHAKE |
    207						INDEX_HASHTABLE_KEYPAIR,
    208						src->receiver_index, &peer)))
    209		return;
    210
    211	down_read(&peer->latest_cookie.lock);
    212	if (unlikely(!peer->latest_cookie.have_sent_mac1)) {
    213		up_read(&peer->latest_cookie.lock);
    214		goto out;
    215	}
    216	ret = xchacha20poly1305_decrypt(
    217		cookie, src->encrypted_cookie, sizeof(src->encrypted_cookie),
    218		peer->latest_cookie.last_mac1_sent, COOKIE_LEN, src->nonce,
    219		peer->latest_cookie.cookie_decryption_key);
    220	up_read(&peer->latest_cookie.lock);
    221
    222	if (ret) {
    223		down_write(&peer->latest_cookie.lock);
    224		memcpy(peer->latest_cookie.cookie, cookie, COOKIE_LEN);
    225		peer->latest_cookie.birthdate = ktime_get_coarse_boottime_ns();
    226		peer->latest_cookie.is_valid = true;
    227		peer->latest_cookie.have_sent_mac1 = false;
    228		up_write(&peer->latest_cookie.lock);
    229	} else {
    230		net_dbg_ratelimited("%s: Could not decrypt invalid cookie response\n",
    231				    wg->dev->name);
    232	}
    233
    234out:
    235	wg_peer_put(peer);
    236}