162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * net/tipc/crypto.h: Include file for TIPC crypto
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2019, Ericsson AB
662306a36Sopenharmony_ci * All rights reserved.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
962306a36Sopenharmony_ci * modification, are permitted provided that the following conditions are met:
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright
1262306a36Sopenharmony_ci *    notice, this list of conditions and the following disclaimer.
1362306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright
1462306a36Sopenharmony_ci *    notice, this list of conditions and the following disclaimer in the
1562306a36Sopenharmony_ci *    documentation and/or other materials provided with the distribution.
1662306a36Sopenharmony_ci * 3. Neither the names of the copyright holders nor the names of its
1762306a36Sopenharmony_ci *    contributors may be used to endorse or promote products derived from
1862306a36Sopenharmony_ci *    this software without specific prior written permission.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the
2162306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free
2262306a36Sopenharmony_ci * Software Foundation.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2562306a36Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2662306a36Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2762306a36Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2862306a36Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2962306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3062306a36Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3162306a36Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3262306a36Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3362306a36Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3462306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGE.
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_ci#ifdef CONFIG_TIPC_CRYPTO
3762306a36Sopenharmony_ci#ifndef _TIPC_CRYPTO_H
3862306a36Sopenharmony_ci#define _TIPC_CRYPTO_H
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#include "core.h"
4162306a36Sopenharmony_ci#include "node.h"
4262306a36Sopenharmony_ci#include "msg.h"
4362306a36Sopenharmony_ci#include "bearer.h"
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define TIPC_EVERSION			7
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* AEAD aes(gcm) */
4862306a36Sopenharmony_ci#define TIPC_AES_GCM_KEY_SIZE_128	16
4962306a36Sopenharmony_ci#define TIPC_AES_GCM_KEY_SIZE_192	24
5062306a36Sopenharmony_ci#define TIPC_AES_GCM_KEY_SIZE_256	32
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define TIPC_AES_GCM_SALT_SIZE		4
5362306a36Sopenharmony_ci#define TIPC_AES_GCM_IV_SIZE		12
5462306a36Sopenharmony_ci#define TIPC_AES_GCM_TAG_SIZE		16
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/*
5762306a36Sopenharmony_ci * TIPC crypto modes:
5862306a36Sopenharmony_ci * - CLUSTER_KEY:
5962306a36Sopenharmony_ci *	One single key is used for both TX & RX in all nodes in the cluster.
6062306a36Sopenharmony_ci * - PER_NODE_KEY:
6162306a36Sopenharmony_ci *	Each nodes in the cluster has one TX key, for RX a node needs to know
6262306a36Sopenharmony_ci *	its peers' TX key for the decryption of messages from those nodes.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_cienum {
6562306a36Sopenharmony_ci	CLUSTER_KEY = 1,
6662306a36Sopenharmony_ci	PER_NODE_KEY = (1 << 1),
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ciextern int sysctl_tipc_max_tfms __read_mostly;
7062306a36Sopenharmony_ciextern int sysctl_tipc_key_exchange_enabled __read_mostly;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*
7362306a36Sopenharmony_ci * TIPC encryption message format:
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci *     3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
7662306a36Sopenharmony_ci *     1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0
7762306a36Sopenharmony_ci *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
7862306a36Sopenharmony_ci * w0:|Ver=7| User  |D|TX |RX |K|M|N|             Rsvd                |
7962306a36Sopenharmony_ci *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8062306a36Sopenharmony_ci * w1:|                             Seqno                             |
8162306a36Sopenharmony_ci * w2:|                           (8 octets)                          |
8262306a36Sopenharmony_ci *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8362306a36Sopenharmony_ci * w3:\                            Prevnode                           \
8462306a36Sopenharmony_ci *    /                        (4 or 16 octets)                       /
8562306a36Sopenharmony_ci *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8662306a36Sopenharmony_ci *    \                                                               \
8762306a36Sopenharmony_ci *    /       Encrypted complete TIPC V2 header and user data         /
8862306a36Sopenharmony_ci *    \                                                               \
8962306a36Sopenharmony_ci *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
9062306a36Sopenharmony_ci *    |                                                               |
9162306a36Sopenharmony_ci *    |                             AuthTag                           |
9262306a36Sopenharmony_ci *    |                           (16 octets)                         |
9362306a36Sopenharmony_ci *    |                                                               |
9462306a36Sopenharmony_ci *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
9562306a36Sopenharmony_ci *
9662306a36Sopenharmony_ci * Word0:
9762306a36Sopenharmony_ci *	Ver	: = 7 i.e. TIPC encryption message version
9862306a36Sopenharmony_ci *	User	: = 7 (for LINK_PROTOCOL); = 13 (for LINK_CONFIG) or = 0
9962306a36Sopenharmony_ci *	D	: The destined bit i.e. the message's destination node is
10062306a36Sopenharmony_ci *	          "known" or not at the message encryption
10162306a36Sopenharmony_ci *	TX	: TX key used for the message encryption
10262306a36Sopenharmony_ci *	RX	: Currently RX active key corresponding to the destination
10362306a36Sopenharmony_ci *	          node's TX key (when the "D" bit is set)
10462306a36Sopenharmony_ci *	K	: Keep-alive bit (for RPS, LINK_PROTOCOL/STATE_MSG only)
10562306a36Sopenharmony_ci *	M       : Bit indicates if sender has master key
10662306a36Sopenharmony_ci *	N	: Bit indicates if sender has no RX keys corresponding to the
10762306a36Sopenharmony_ci *	          receiver's TX (when the "D" bit is set)
10862306a36Sopenharmony_ci *	Rsvd	: Reserved bit, field
10962306a36Sopenharmony_ci * Word1-2:
11062306a36Sopenharmony_ci *	Seqno	: The 64-bit sequence number of the encrypted message, also
11162306a36Sopenharmony_ci *		  part of the nonce used for the message encryption/decryption
11262306a36Sopenharmony_ci * Word3-:
11362306a36Sopenharmony_ci *	Prevnode: The source node address, or ID in case LINK_CONFIG only
11462306a36Sopenharmony_ci *	AuthTag	: The authentication tag for the message integrity checking
11562306a36Sopenharmony_ci *		  generated by the message encryption
11662306a36Sopenharmony_ci */
11762306a36Sopenharmony_cistruct tipc_ehdr {
11862306a36Sopenharmony_ci	union {
11962306a36Sopenharmony_ci		struct {
12062306a36Sopenharmony_ci#if defined(__LITTLE_ENDIAN_BITFIELD)
12162306a36Sopenharmony_ci			__u8	destined:1,
12262306a36Sopenharmony_ci				user:4,
12362306a36Sopenharmony_ci				version:3;
12462306a36Sopenharmony_ci			__u8	reserved_1:1,
12562306a36Sopenharmony_ci				rx_nokey:1,
12662306a36Sopenharmony_ci				master_key:1,
12762306a36Sopenharmony_ci				keepalive:1,
12862306a36Sopenharmony_ci				rx_key_active:2,
12962306a36Sopenharmony_ci				tx_key:2;
13062306a36Sopenharmony_ci#elif defined(__BIG_ENDIAN_BITFIELD)
13162306a36Sopenharmony_ci			__u8	version:3,
13262306a36Sopenharmony_ci				user:4,
13362306a36Sopenharmony_ci				destined:1;
13462306a36Sopenharmony_ci			__u8	tx_key:2,
13562306a36Sopenharmony_ci				rx_key_active:2,
13662306a36Sopenharmony_ci				keepalive:1,
13762306a36Sopenharmony_ci				master_key:1,
13862306a36Sopenharmony_ci				rx_nokey:1,
13962306a36Sopenharmony_ci				reserved_1:1;
14062306a36Sopenharmony_ci#else
14162306a36Sopenharmony_ci#error  "Please fix <asm/byteorder.h>"
14262306a36Sopenharmony_ci#endif
14362306a36Sopenharmony_ci			__be16	reserved_2;
14462306a36Sopenharmony_ci		} __packed;
14562306a36Sopenharmony_ci		__be32 w0;
14662306a36Sopenharmony_ci	};
14762306a36Sopenharmony_ci	__be64 seqno;
14862306a36Sopenharmony_ci	union {
14962306a36Sopenharmony_ci		__be32 addr;
15062306a36Sopenharmony_ci		__u8 id[NODE_ID_LEN]; /* For a LINK_CONFIG message only! */
15162306a36Sopenharmony_ci	};
15262306a36Sopenharmony_ci#define EHDR_SIZE	(offsetof(struct tipc_ehdr, addr) + sizeof(__be32))
15362306a36Sopenharmony_ci#define EHDR_CFG_SIZE	(sizeof(struct tipc_ehdr))
15462306a36Sopenharmony_ci#define EHDR_MIN_SIZE	(EHDR_SIZE)
15562306a36Sopenharmony_ci#define EHDR_MAX_SIZE	(EHDR_CFG_SIZE)
15662306a36Sopenharmony_ci#define EMSG_OVERHEAD	(EHDR_SIZE + TIPC_AES_GCM_TAG_SIZE)
15762306a36Sopenharmony_ci} __packed;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ciint tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,
16062306a36Sopenharmony_ci		      struct tipc_node *node);
16162306a36Sopenharmony_civoid tipc_crypto_stop(struct tipc_crypto **crypto);
16262306a36Sopenharmony_civoid tipc_crypto_timeout(struct tipc_crypto *rx);
16362306a36Sopenharmony_ciint tipc_crypto_xmit(struct net *net, struct sk_buff **skb,
16462306a36Sopenharmony_ci		     struct tipc_bearer *b, struct tipc_media_addr *dst,
16562306a36Sopenharmony_ci		     struct tipc_node *__dnode);
16662306a36Sopenharmony_ciint tipc_crypto_rcv(struct net *net, struct tipc_crypto *rx,
16762306a36Sopenharmony_ci		    struct sk_buff **skb, struct tipc_bearer *b);
16862306a36Sopenharmony_ciint tipc_crypto_key_init(struct tipc_crypto *c, struct tipc_aead_key *ukey,
16962306a36Sopenharmony_ci			 u8 mode, bool master_key);
17062306a36Sopenharmony_civoid tipc_crypto_key_flush(struct tipc_crypto *c);
17162306a36Sopenharmony_ciint tipc_crypto_key_distr(struct tipc_crypto *tx, u8 key,
17262306a36Sopenharmony_ci			  struct tipc_node *dest);
17362306a36Sopenharmony_civoid tipc_crypto_msg_rcv(struct net *net, struct sk_buff *skb);
17462306a36Sopenharmony_civoid tipc_crypto_rekeying_sched(struct tipc_crypto *tx, bool changed,
17562306a36Sopenharmony_ci				u32 new_intv);
17662306a36Sopenharmony_ciint tipc_aead_key_validate(struct tipc_aead_key *ukey, struct genl_info *info);
17762306a36Sopenharmony_cibool tipc_ehdr_validate(struct sk_buff *skb);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cistatic inline u32 msg_key_gen(struct tipc_msg *m)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	return msg_bits(m, 4, 16, 0xffff);
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistatic inline void msg_set_key_gen(struct tipc_msg *m, u32 gen)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	msg_set_bits(m, 4, 16, 0xffff, gen);
18762306a36Sopenharmony_ci}
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistatic inline u32 msg_key_mode(struct tipc_msg *m)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	return msg_bits(m, 4, 0, 0xf);
19262306a36Sopenharmony_ci}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cistatic inline void msg_set_key_mode(struct tipc_msg *m, u32 mode)
19562306a36Sopenharmony_ci{
19662306a36Sopenharmony_ci	msg_set_bits(m, 4, 0, 0xf, mode);
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci#endif /* _TIPC_CRYPTO_H */
20062306a36Sopenharmony_ci#endif
201