Skip to content

Commit fc1b6d6

Browse files
Tuong Liendavem330
authored andcommitted
tipc: introduce TIPC encryption & authentication
This commit offers an option to encrypt and authenticate all messaging, including the neighbor discovery messages. The currently most advanced algorithm supported is the AEAD AES-GCM (like IPSec or TLS). All encryption/decryption is done at the bearer layer, just before leaving or after entering TIPC. Supported features: - Encryption & authentication of all TIPC messages (header + data); - Two symmetric-key modes: Cluster and Per-node; - Automatic key switching; - Key-expired revoking (sequence number wrapped); - Lock-free encryption/decryption (RCU); - Asynchronous crypto, Intel AES-NI supported; - Multiple cipher transforms; - Logs & statistics; Two key modes: - Cluster key mode: One single key is used for both TX & RX in all nodes in the cluster. - Per-node key mode: Each nodes in the cluster has one specific TX key. For RX, a node requires its peers' TX key to be able to decrypt the messages from those peers. Key setting from user-space is performed via netlink by a user program (e.g. the iproute2 'tipc' tool). Internal key state machine: Attach Align(RX) +-+ +-+ | V | V +---------+ Attach +---------+ | IDLE |---------------->| PENDING |(user = 0) +---------+ +---------+ A A Switch| A | | | | | | Free(switch/revoked) | | (Free)| +----------------------+ | |Timeout | (TX) | | |(RX) | | | | | | v | +---------+ Switch +---------+ | PASSIVE |<----------------| ACTIVE | +---------+ (RX) +---------+ (user = 1) (user >= 1) The number of TFMs is 10 by default and can be changed via the procfs 'net/tipc/max_tfms'. At this moment, as for simplicity, this file is also used to print the crypto statistics at runtime: echo 0xfff1 > /proc/sys/net/tipc/max_tfms The patch defines a new TIPC version (v7) for the encryption message (- backward compatibility as well). The message is basically encapsulated as follows: +----------------------------------------------------------+ | TIPCv7 encryption | Original TIPCv2 | Authentication | | header | packet (encrypted) | Tag | +----------------------------------------------------------+ The throughput is about ~40% for small messages (compared with non- encryption) and ~9% for large messages. With the support from hardware crypto i.e. the Intel AES-NI CPU instructions, the throughput increases upto ~85% for small messages and ~55% for large messages. By default, the new feature is inactive (i.e. no encryption) until user sets a key for TIPC. There is however also a new option - "TIPC_CRYPTO" in the kernel configuration to enable/disable the new code when needed. MAINTAINERS | add two new files 'crypto.h' & 'crypto.c' in tipc Acked-by: Ying Xue <[email protected]> Acked-by: Jon Maloy <[email protected]> Signed-off-by: Tuong Lien <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 134bdac commit fc1b6d6

File tree

17 files changed

+2385
-46
lines changed

17 files changed

+2385
-46
lines changed

net/tipc/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@ config TIPC_MEDIA_UDP
3535
Saying Y here will enable support for running TIPC over IP/UDP
3636
bool
3737
default y
38+
config TIPC_CRYPTO
39+
bool "TIPC encryption support"
40+
depends on TIPC
41+
select CRYPTO
42+
select CRYPTO_AES
43+
select CRYPTO_GCM
44+
help
45+
Saying Y here will enable support for TIPC encryption.
46+
All TIPC messages will be encrypted/decrypted by using the currently most
47+
advanced algorithm: AEAD AES-GCM (like IPSec or TLS) before leaving/
48+
entering the TIPC stack.
49+
Key setting from user-space is performed via netlink by a user program
50+
(e.g. the iproute2 'tipc' tool).
51+
bool
52+
default y
3853

3954
config TIPC_DIAG
4055
tristate "TIPC: socket monitoring interface"

net/tipc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CFLAGS_trace.o += -I$(src)
1616
tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o
1717
tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
1818
tipc-$(CONFIG_SYSCTL) += sysctl.o
19+
tipc-$(CONFIG_TIPC_CRYPTO) += crypto.o
1920

2021

2122
obj-$(CONFIG_TIPC_DIAG) += diag.o

net/tipc/bcast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static struct tipc_bc_base *tipc_bc_base(struct net *net)
8484
*/
8585
int tipc_bcast_get_mtu(struct net *net)
8686
{
87-
return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE;
87+
return tipc_link_mss(tipc_bc_sndlink(net));
8888
}
8989

9090
void tipc_bcast_disable_rcast(struct net *net)

net/tipc/bearer.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "netlink.h"
4545
#include "udp_media.h"
4646
#include "trace.h"
47+
#include "crypto.h"
4748

4849
#define MAX_ADDR_STR 60
4950

@@ -516,18 +517,24 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
516517

517518
rcu_read_lock();
518519
b = bearer_get(net, bearer_id);
519-
if (likely(b && (test_bit(0, &b->up) || msg_is_reset(hdr))))
520-
b->media->send_msg(net, skb, b, dest);
521-
else
520+
if (likely(b && (test_bit(0, &b->up) || msg_is_reset(hdr)))) {
521+
#ifdef CONFIG_TIPC_CRYPTO
522+
tipc_crypto_xmit(net, &skb, b, dest, NULL);
523+
if (skb)
524+
#endif
525+
b->media->send_msg(net, skb, b, dest);
526+
} else {
522527
kfree_skb(skb);
528+
}
523529
rcu_read_unlock();
524530
}
525531

526532
/* tipc_bearer_xmit() -send buffer to destination over bearer
527533
*/
528534
void tipc_bearer_xmit(struct net *net, u32 bearer_id,
529535
struct sk_buff_head *xmitq,
530-
struct tipc_media_addr *dst)
536+
struct tipc_media_addr *dst,
537+
struct tipc_node *__dnode)
531538
{
532539
struct tipc_bearer *b;
533540
struct sk_buff *skb, *tmp;
@@ -541,10 +548,15 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
541548
__skb_queue_purge(xmitq);
542549
skb_queue_walk_safe(xmitq, skb, tmp) {
543550
__skb_dequeue(xmitq);
544-
if (likely(test_bit(0, &b->up) || msg_is_reset(buf_msg(skb))))
545-
b->media->send_msg(net, skb, b, dst);
546-
else
551+
if (likely(test_bit(0, &b->up) || msg_is_reset(buf_msg(skb)))) {
552+
#ifdef CONFIG_TIPC_CRYPTO
553+
tipc_crypto_xmit(net, &skb, b, dst, __dnode);
554+
if (skb)
555+
#endif
556+
b->media->send_msg(net, skb, b, dst);
557+
} else {
547558
kfree_skb(skb);
559+
}
548560
}
549561
rcu_read_unlock();
550562
}
@@ -555,6 +567,7 @@ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
555567
struct sk_buff_head *xmitq)
556568
{
557569
struct tipc_net *tn = tipc_net(net);
570+
struct tipc_media_addr *dst;
558571
int net_id = tn->net_id;
559572
struct tipc_bearer *b;
560573
struct sk_buff *skb, *tmp;
@@ -569,7 +582,12 @@ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
569582
msg_set_non_seq(hdr, 1);
570583
msg_set_mc_netid(hdr, net_id);
571584
__skb_dequeue(xmitq);
572-
b->media->send_msg(net, skb, b, &b->bcast_addr);
585+
dst = &b->bcast_addr;
586+
#ifdef CONFIG_TIPC_CRYPTO
587+
tipc_crypto_xmit(net, &skb, b, dst, NULL);
588+
if (skb)
589+
#endif
590+
b->media->send_msg(net, skb, b, dst);
573591
}
574592
rcu_read_unlock();
575593
}
@@ -596,6 +614,7 @@ static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev,
596614
if (likely(b && test_bit(0, &b->up) &&
597615
(skb->pkt_type <= PACKET_MULTICAST))) {
598616
skb_mark_not_on_list(skb);
617+
TIPC_SKB_CB(skb)->flags = 0;
599618
tipc_rcv(dev_net(b->pt.dev), skb, b);
600619
rcu_read_unlock();
601620
return NET_RX_SUCCESS;

net/tipc/bearer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
232232
struct tipc_media_addr *dest);
233233
void tipc_bearer_xmit(struct net *net, u32 bearer_id,
234234
struct sk_buff_head *xmitq,
235-
struct tipc_media_addr *dst);
235+
struct tipc_media_addr *dst,
236+
struct tipc_node *__dnode);
236237
void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
237238
struct sk_buff_head *xmitq);
238239
void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts);

net/tipc/core.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "socket.h"
4545
#include "bcast.h"
4646
#include "node.h"
47+
#include "crypto.h"
4748

4849
#include <linux/module.h>
4950

@@ -68,6 +69,11 @@ static int __net_init tipc_init_net(struct net *net)
6869
INIT_LIST_HEAD(&tn->node_list);
6970
spin_lock_init(&tn->node_list_lock);
7071

72+
#ifdef CONFIG_TIPC_CRYPTO
73+
err = tipc_crypto_start(&tn->crypto_tx, net, NULL);
74+
if (err)
75+
goto out_crypto;
76+
#endif
7177
err = tipc_sk_rht_init(net);
7278
if (err)
7379
goto out_sk_rht;
@@ -93,6 +99,11 @@ static int __net_init tipc_init_net(struct net *net)
9399
out_nametbl:
94100
tipc_sk_rht_destroy(net);
95101
out_sk_rht:
102+
103+
#ifdef CONFIG_TIPC_CRYPTO
104+
tipc_crypto_stop(&tn->crypto_tx);
105+
out_crypto:
106+
#endif
96107
return err;
97108
}
98109

@@ -103,6 +114,9 @@ static void __net_exit tipc_exit_net(struct net *net)
103114
tipc_bcast_stop(net);
104115
tipc_nametbl_stop(net);
105116
tipc_sk_rht_destroy(net);
117+
#ifdef CONFIG_TIPC_CRYPTO
118+
tipc_crypto_stop(&tipc_net(net)->crypto_tx);
119+
#endif
106120
}
107121

108122
static void __net_exit tipc_pernet_pre_exit(struct net *net)

net/tipc/core.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ struct tipc_link;
6868
struct tipc_name_table;
6969
struct tipc_topsrv;
7070
struct tipc_monitor;
71+
#ifdef CONFIG_TIPC_CRYPTO
72+
struct tipc_crypto;
73+
#endif
7174

7275
#define TIPC_MOD_VER "2.0.0"
7376

@@ -129,6 +132,11 @@ struct tipc_net {
129132

130133
/* Tracing of node internal messages */
131134
struct packet_type loopback_pt;
135+
136+
#ifdef CONFIG_TIPC_CRYPTO
137+
/* TX crypto handler */
138+
struct tipc_crypto *crypto_tx;
139+
#endif
132140
};
133141

134142
static inline struct tipc_net *tipc_net(struct net *net)

0 commit comments

Comments
 (0)