mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-18 06:40:49 +07:00
Merge branch 'tipc-add-more-features-to-TIPC-encryption'
Tuong Lien says: ==================== tipc: add more features to TIPC encryption This series adds some new features to TIPC encryption: - Patch 1 ("tipc: optimize key switching time and logic") optimizes the code and logic in preparation for the following commits. - Patch 2 ("tipc: introduce encryption master key") introduces support of 'master key' for authentication of new nodes and key exchange. A master key can be set/changed by user via netlink (eg. using the same 'tipc node set key' command in iproute2/tipc). - Patch 3 ("tipc: add automatic session key exchange") allows a session key to be securely exchanged between nodes as needed. - Patch 4 ("tipc: add automatic rekeying for encryption key") adds automatic 'rekeying' of session keys a specific interval. The new key will be distributed automatically to peer nodes, so become active then. The rekeying interval is configurable via netlink as well. v2: update the "tipc: add automatic session key exchange" patch to fix "implicit declaration" issue when built without "CONFIG_TIPC_CRYPTO". v3: update the patches according to David comments by using the "genl_info->extack" for messages in response to netlink user config requests. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
5d7d28e5ff
@ -254,6 +254,8 @@ static inline int tipc_aead_key_size(struct tipc_aead_key *key)
|
||||
return sizeof(*key) + key->keylen;
|
||||
}
|
||||
|
||||
#define TIPC_REKEYING_NOW (~0U)
|
||||
|
||||
/* The macros and functions below are deprecated:
|
||||
*/
|
||||
|
||||
|
@ -165,6 +165,8 @@ enum {
|
||||
TIPC_NLA_NODE_UP, /* flag */
|
||||
TIPC_NLA_NODE_ID, /* data */
|
||||
TIPC_NLA_NODE_KEY, /* data */
|
||||
TIPC_NLA_NODE_KEY_MASTER, /* flag */
|
||||
TIPC_NLA_NODE_REKEYING, /* u32 */
|
||||
|
||||
__TIPC_NLA_NODE_MAX,
|
||||
TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -67,6 +67,7 @@ enum {
|
||||
};
|
||||
|
||||
extern int sysctl_tipc_max_tfms __read_mostly;
|
||||
extern int sysctl_tipc_key_exchange_enabled __read_mostly;
|
||||
|
||||
/**
|
||||
* TIPC encryption message format:
|
||||
@ -74,7 +75,7 @@ extern int sysctl_tipc_max_tfms __read_mostly;
|
||||
* 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
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* w0:|Ver=7| User |D|TX |RX |K| Rsvd |
|
||||
* w0:|Ver=7| User |D|TX |RX |K|M|N| Rsvd |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* w1:| Seqno |
|
||||
* w2:| (8 octets) |
|
||||
@ -101,6 +102,9 @@ extern int sysctl_tipc_max_tfms __read_mostly;
|
||||
* RX : Currently RX active key corresponding to the destination
|
||||
* node's TX key (when the "D" bit is set)
|
||||
* K : Keep-alive bit (for RPS, LINK_PROTOCOL/STATE_MSG only)
|
||||
* M : Bit indicates if sender has master key
|
||||
* N : Bit indicates if sender has no RX keys corresponding to the
|
||||
* receiver's TX (when the "D" bit is set)
|
||||
* Rsvd : Reserved bit, field
|
||||
* Word1-2:
|
||||
* Seqno : The 64-bit sequence number of the encrypted message, also
|
||||
@ -117,7 +121,9 @@ struct tipc_ehdr {
|
||||
__u8 destined:1,
|
||||
user:4,
|
||||
version:3;
|
||||
__u8 reserved_1:3,
|
||||
__u8 reserved_1:1,
|
||||
rx_nokey:1,
|
||||
master_key:1,
|
||||
keepalive:1,
|
||||
rx_key_active:2,
|
||||
tx_key:2;
|
||||
@ -128,7 +134,9 @@ struct tipc_ehdr {
|
||||
__u8 tx_key:2,
|
||||
rx_key_active:2,
|
||||
keepalive:1,
|
||||
reserved_1:3;
|
||||
master_key:1,
|
||||
rx_nokey:1,
|
||||
reserved_1:1;
|
||||
#else
|
||||
#error "Please fix <asm/byteorder.h>"
|
||||
#endif
|
||||
@ -158,10 +166,35 @@ int tipc_crypto_xmit(struct net *net, struct sk_buff **skb,
|
||||
int tipc_crypto_rcv(struct net *net, struct tipc_crypto *rx,
|
||||
struct sk_buff **skb, struct tipc_bearer *b);
|
||||
int tipc_crypto_key_init(struct tipc_crypto *c, struct tipc_aead_key *ukey,
|
||||
u8 mode);
|
||||
u8 mode, bool master_key);
|
||||
void tipc_crypto_key_flush(struct tipc_crypto *c);
|
||||
int tipc_aead_key_validate(struct tipc_aead_key *ukey);
|
||||
int tipc_crypto_key_distr(struct tipc_crypto *tx, u8 key,
|
||||
struct tipc_node *dest);
|
||||
void tipc_crypto_msg_rcv(struct net *net, struct sk_buff *skb);
|
||||
void tipc_crypto_rekeying_sched(struct tipc_crypto *tx, bool changed,
|
||||
u32 new_intv);
|
||||
int tipc_aead_key_validate(struct tipc_aead_key *ukey, struct genl_info *info);
|
||||
bool tipc_ehdr_validate(struct sk_buff *skb);
|
||||
|
||||
static inline u32 msg_key_gen(struct tipc_msg *m)
|
||||
{
|
||||
return msg_bits(m, 4, 16, 0xffff);
|
||||
}
|
||||
|
||||
static inline void msg_set_key_gen(struct tipc_msg *m, u32 gen)
|
||||
{
|
||||
msg_set_bits(m, 4, 16, 0xffff, gen);
|
||||
}
|
||||
|
||||
static inline u32 msg_key_mode(struct tipc_msg *m)
|
||||
{
|
||||
return msg_bits(m, 4, 0, 0xf);
|
||||
}
|
||||
|
||||
static inline void msg_set_key_mode(struct tipc_msg *m, u32 mode)
|
||||
{
|
||||
msg_set_bits(m, 4, 0, 0xf, mode);
|
||||
}
|
||||
|
||||
#endif /* _TIPC_CRYPTO_H */
|
||||
#endif
|
||||
|
@ -1250,6 +1250,11 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb,
|
||||
case MSG_FRAGMENTER:
|
||||
case BCAST_PROTOCOL:
|
||||
return false;
|
||||
#ifdef CONFIG_TIPC_CRYPTO
|
||||
case MSG_CRYPTO:
|
||||
tipc_crypto_msg_rcv(l->net, skb);
|
||||
return true;
|
||||
#endif
|
||||
default:
|
||||
pr_warn("Dropping received illegal msg type\n");
|
||||
kfree_skb(skb);
|
||||
|
@ -82,6 +82,7 @@ struct plist;
|
||||
#define NAME_DISTRIBUTOR 11
|
||||
#define MSG_FRAGMENTER 12
|
||||
#define LINK_CONFIG 13
|
||||
#define MSG_CRYPTO 14
|
||||
#define SOCK_WAKEUP 14 /* pseudo user */
|
||||
#define TOP_SRV 15 /* pseudo user */
|
||||
|
||||
@ -127,7 +128,9 @@ struct tipc_skb_cb {
|
||||
#ifdef CONFIG_TIPC_CRYPTO
|
||||
u8 encrypted:1;
|
||||
u8 decrypted:1;
|
||||
u8 probe:1;
|
||||
#define SKB_PROBING 1
|
||||
#define SKB_GRACING 2
|
||||
u8 xmit_type:2;
|
||||
u8 tx_clone_deferred:1;
|
||||
#endif
|
||||
};
|
||||
@ -747,6 +750,9 @@ static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
|
||||
#define GRP_RECLAIM_MSG 4
|
||||
#define GRP_REMIT_MSG 5
|
||||
|
||||
/* Crypto message types */
|
||||
#define KEY_DISTR_MSG 0
|
||||
|
||||
/*
|
||||
* Word 1
|
||||
*/
|
||||
|
@ -108,6 +108,8 @@ const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
|
||||
.len = TIPC_NODEID_LEN},
|
||||
[TIPC_NLA_NODE_KEY] = { .type = NLA_BINARY,
|
||||
.len = TIPC_AEAD_KEY_SIZE_MAX},
|
||||
[TIPC_NLA_NODE_KEY_MASTER] = { .type = NLA_FLAG },
|
||||
[TIPC_NLA_NODE_REKEYING] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
/* Properties valid for media, bearer and link */
|
||||
|
@ -278,6 +278,14 @@ struct tipc_crypto *tipc_node_crypto_rx_by_list(struct list_head *pos)
|
||||
{
|
||||
return container_of(pos, struct tipc_node, list)->crypto_rx;
|
||||
}
|
||||
|
||||
struct tipc_crypto *tipc_node_crypto_rx_by_addr(struct net *net, u32 addr)
|
||||
{
|
||||
struct tipc_node *n;
|
||||
|
||||
n = tipc_node_find(net, addr);
|
||||
return (n) ? n->crypto_rx : NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tipc_node_free(struct rcu_head *rp)
|
||||
@ -303,7 +311,7 @@ void tipc_node_put(struct tipc_node *node)
|
||||
kref_put(&node->kref, tipc_node_kref_release);
|
||||
}
|
||||
|
||||
static void tipc_node_get(struct tipc_node *node)
|
||||
void tipc_node_get(struct tipc_node *node)
|
||||
{
|
||||
kref_get(&node->kref);
|
||||
}
|
||||
@ -584,6 +592,9 @@ static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
|
||||
|
||||
static void tipc_node_delete_from_list(struct tipc_node *node)
|
||||
{
|
||||
#ifdef CONFIG_TIPC_CRYPTO
|
||||
tipc_crypto_key_flush(node->crypto_rx);
|
||||
#endif
|
||||
list_del_rcu(&node->list);
|
||||
hlist_del_rcu(&node->hash);
|
||||
tipc_node_put(node);
|
||||
@ -2868,15 +2879,27 @@ static int tipc_nl_retrieve_nodeid(struct nlattr **attrs, u8 **node_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tipc_nl_retrieve_rekeying(struct nlattr **attrs, u32 *intv)
|
||||
{
|
||||
struct nlattr *attr = attrs[TIPC_NLA_NODE_REKEYING];
|
||||
|
||||
if (!attr)
|
||||
return -ENODATA;
|
||||
|
||||
*intv = nla_get_u32(attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1];
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct tipc_net *tn = tipc_net(net);
|
||||
struct tipc_crypto *tx = tipc_net(net)->crypto_tx, *c = tx;
|
||||
struct tipc_node *n = NULL;
|
||||
struct tipc_aead_key *ukey;
|
||||
struct tipc_crypto *c;
|
||||
u8 *id, *own_id;
|
||||
bool rekeying = true, master_key = false;
|
||||
u8 *id, *own_id, mode;
|
||||
u32 intv = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!info->attrs[TIPC_NLA_NODE])
|
||||
@ -2886,52 +2909,66 @@ static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
|
||||
info->attrs[TIPC_NLA_NODE],
|
||||
tipc_nl_node_policy, info->extack);
|
||||
if (rc)
|
||||
goto exit;
|
||||
return rc;
|
||||
|
||||
own_id = tipc_own_id(net);
|
||||
if (!own_id) {
|
||||
rc = -EPERM;
|
||||
goto exit;
|
||||
GENL_SET_ERR_MSG(info, "not found own node identity (set id?)");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
rc = tipc_nl_retrieve_key(attrs, &ukey);
|
||||
if (rc)
|
||||
goto exit;
|
||||
rc = tipc_nl_retrieve_rekeying(attrs, &intv);
|
||||
if (rc == -ENODATA)
|
||||
rekeying = false;
|
||||
|
||||
rc = tipc_aead_key_validate(ukey);
|
||||
rc = tipc_nl_retrieve_key(attrs, &ukey);
|
||||
if (rc == -ENODATA && rekeying)
|
||||
goto rekeying;
|
||||
else if (rc)
|
||||
return rc;
|
||||
|
||||
rc = tipc_aead_key_validate(ukey, info);
|
||||
if (rc)
|
||||
goto exit;
|
||||
return rc;
|
||||
|
||||
rc = tipc_nl_retrieve_nodeid(attrs, &id);
|
||||
switch (rc) {
|
||||
case -ENODATA:
|
||||
/* Cluster key mode */
|
||||
rc = tipc_crypto_key_init(tn->crypto_tx, ukey, CLUSTER_KEY);
|
||||
mode = CLUSTER_KEY;
|
||||
master_key = !!(attrs[TIPC_NLA_NODE_KEY_MASTER]);
|
||||
break;
|
||||
case 0:
|
||||
/* Per-node key mode */
|
||||
if (!memcmp(id, own_id, NODE_ID_LEN)) {
|
||||
c = tn->crypto_tx;
|
||||
} else {
|
||||
mode = PER_NODE_KEY;
|
||||
if (memcmp(id, own_id, NODE_ID_LEN)) {
|
||||
n = tipc_node_find_by_id(net, id) ?:
|
||||
tipc_node_create(net, 0, id, 0xffffu, 0, true);
|
||||
if (unlikely(!n)) {
|
||||
rc = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (unlikely(!n))
|
||||
return -ENOMEM;
|
||||
c = n->crypto_rx;
|
||||
}
|
||||
|
||||
rc = tipc_crypto_key_init(c, ukey, PER_NODE_KEY);
|
||||
if (n)
|
||||
tipc_node_put(n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return rc;
|
||||
}
|
||||
|
||||
exit:
|
||||
return (rc < 0) ? rc : 0;
|
||||
/* Initiate the TX/RX key */
|
||||
rc = tipc_crypto_key_init(c, ukey, mode, master_key);
|
||||
if (n)
|
||||
tipc_node_put(n);
|
||||
|
||||
if (unlikely(rc < 0)) {
|
||||
GENL_SET_ERR_MSG(info, "unable to initiate or attach new key");
|
||||
return rc;
|
||||
} else if (c == tx) {
|
||||
/* Distribute TX key but not master one */
|
||||
if (!master_key && tipc_crypto_key_distr(tx, rc, NULL))
|
||||
GENL_SET_ERR_MSG(info, "failed to replicate new key");
|
||||
rekeying:
|
||||
/* Schedule TX rekeying if needed */
|
||||
tipc_crypto_rekeying_sched(tx, rekeying, intv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
|
||||
@ -2958,7 +2995,6 @@ static int __tipc_nl_node_flush_key(struct sk_buff *skb,
|
||||
tipc_crypto_key_flush(n->crypto_rx);
|
||||
rcu_read_unlock();
|
||||
|
||||
pr_info("All keys are flushed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -79,12 +79,14 @@ bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);
|
||||
u32 tipc_node_get_addr(struct tipc_node *node);
|
||||
char *tipc_node_get_id_str(struct tipc_node *node);
|
||||
void tipc_node_put(struct tipc_node *node);
|
||||
void tipc_node_get(struct tipc_node *node);
|
||||
struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id,
|
||||
u16 capabilities, u32 hash_mixes,
|
||||
bool preliminary);
|
||||
#ifdef CONFIG_TIPC_CRYPTO
|
||||
struct tipc_crypto *tipc_node_crypto_rx(struct tipc_node *__n);
|
||||
struct tipc_crypto *tipc_node_crypto_rx_by_list(struct list_head *pos);
|
||||
struct tipc_crypto *tipc_node_crypto_rx_by_addr(struct net *net, u32 addr);
|
||||
#endif
|
||||
u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr);
|
||||
void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128,
|
||||
|
@ -74,6 +74,15 @@ static struct ctl_table tipc_table[] = {
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = SYSCTL_ONE,
|
||||
},
|
||||
{
|
||||
.procname = "key_exchange_enabled",
|
||||
.data = &sysctl_tipc_key_exchange_enabled,
|
||||
.maxlen = sizeof(sysctl_tipc_key_exchange_enabled),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = SYSCTL_ONE,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.procname = "bc_retruni",
|
||||
|
Loading…
Reference in New Issue
Block a user