xref: /linux/net/psp/psp_main.c (revision e78851058b35deb9f2d60ecf698fbf7ae7790d09)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #include <linux/list.h>
4 #include <linux/netdevice.h>
5 #include <linux/xarray.h>
6 #include <net/net_namespace.h>
7 #include <net/psp.h>
8 
9 #include "psp.h"
10 #include "psp-nl-gen.h"
11 
12 DEFINE_XARRAY_ALLOC1(psp_devs);
13 struct mutex psp_devs_lock;
14 
15 /**
16  * DOC: PSP locking
17  *
18  * psp_devs_lock protects the psp_devs xarray.
19  * Ordering is take the psp_devs_lock and then the instance lock.
20  * Each instance is protected by RCU, and has a refcount.
21  * When driver unregisters the instance gets flushed, but struct sticks around.
22  */
23 
24 /**
25  * psp_dev_check_access() - check if user in a given net ns can access PSP dev
26  * @psd:	PSP device structure user is trying to access
27  * @net:	net namespace user is in
28  *
29  * Return: 0 if PSP device should be visible in @net, errno otherwise.
30  */
31 int psp_dev_check_access(struct psp_dev *psd, struct net *net)
32 {
33 	if (dev_net(psd->main_netdev) == net)
34 		return 0;
35 	return -ENOENT;
36 }
37 
38 /**
39  * psp_dev_create() - create and register PSP device
40  * @netdev:	main netdevice
41  * @psd_ops:	driver callbacks
42  * @psd_caps:	device capabilities
43  * @priv_ptr:	back-pointer to driver private data
44  *
45  * Return: pointer to allocated PSP device, or ERR_PTR.
46  */
47 struct psp_dev *
48 psp_dev_create(struct net_device *netdev,
49 	       struct psp_dev_ops *psd_ops, struct psp_dev_caps *psd_caps,
50 	       void *priv_ptr)
51 {
52 	struct psp_dev *psd;
53 	static u32 last_id;
54 	int err;
55 
56 	if (WARN_ON(!psd_caps->versions ||
57 		    !psd_ops->set_config ||
58 		    !psd_ops->key_rotate ||
59 		    !psd_ops->rx_spi_alloc ||
60 		    !psd_ops->tx_key_add ||
61 		    !psd_ops->tx_key_del))
62 		return ERR_PTR(-EINVAL);
63 
64 	psd = kzalloc(sizeof(*psd), GFP_KERNEL);
65 	if (!psd)
66 		return ERR_PTR(-ENOMEM);
67 
68 	psd->main_netdev = netdev;
69 	psd->ops = psd_ops;
70 	psd->caps = psd_caps;
71 	psd->drv_priv = priv_ptr;
72 
73 	mutex_init(&psd->lock);
74 	INIT_LIST_HEAD(&psd->active_assocs);
75 	INIT_LIST_HEAD(&psd->prev_assocs);
76 	INIT_LIST_HEAD(&psd->stale_assocs);
77 	refcount_set(&psd->refcnt, 1);
78 
79 	mutex_lock(&psp_devs_lock);
80 	err = xa_alloc_cyclic(&psp_devs, &psd->id, psd, xa_limit_16b,
81 			      &last_id, GFP_KERNEL);
82 	if (err) {
83 		mutex_unlock(&psp_devs_lock);
84 		kfree(psd);
85 		return ERR_PTR(err);
86 	}
87 	mutex_lock(&psd->lock);
88 	mutex_unlock(&psp_devs_lock);
89 
90 	psp_nl_notify_dev(psd, PSP_CMD_DEV_ADD_NTF);
91 
92 	rcu_assign_pointer(netdev->psp_dev, psd);
93 
94 	mutex_unlock(&psd->lock);
95 
96 	return psd;
97 }
98 EXPORT_SYMBOL(psp_dev_create);
99 
100 void psp_dev_destroy(struct psp_dev *psd)
101 {
102 	mutex_lock(&psp_devs_lock);
103 	xa_erase(&psp_devs, psd->id);
104 	mutex_unlock(&psp_devs_lock);
105 
106 	mutex_destroy(&psd->lock);
107 	kfree_rcu(psd, rcu);
108 }
109 
110 /**
111  * psp_dev_unregister() - unregister PSP device
112  * @psd:	PSP device structure
113  */
114 void psp_dev_unregister(struct psp_dev *psd)
115 {
116 	struct psp_assoc *pas, *next;
117 
118 	mutex_lock(&psp_devs_lock);
119 	mutex_lock(&psd->lock);
120 
121 	psp_nl_notify_dev(psd, PSP_CMD_DEV_DEL_NTF);
122 
123 	/* Wait until psp_dev_destroy() to call xa_erase() to prevent a
124 	 * different psd from being added to the xarray with this id, while
125 	 * there are still references to this psd being held.
126 	 */
127 	xa_store(&psp_devs, psd->id, NULL, GFP_KERNEL);
128 	mutex_unlock(&psp_devs_lock);
129 
130 	list_splice_init(&psd->active_assocs, &psd->prev_assocs);
131 	list_splice_init(&psd->prev_assocs, &psd->stale_assocs);
132 	list_for_each_entry_safe(pas, next, &psd->stale_assocs, assocs_list)
133 		psp_dev_tx_key_del(psd, pas);
134 
135 	rcu_assign_pointer(psd->main_netdev->psp_dev, NULL);
136 
137 	psd->ops = NULL;
138 	psd->drv_priv = NULL;
139 
140 	mutex_unlock(&psd->lock);
141 
142 	psp_dev_put(psd);
143 }
144 EXPORT_SYMBOL(psp_dev_unregister);
145 
146 unsigned int psp_key_size(u32 version)
147 {
148 	switch (version) {
149 	case PSP_VERSION_HDR0_AES_GCM_128:
150 	case PSP_VERSION_HDR0_AES_GMAC_128:
151 		return 16;
152 	case PSP_VERSION_HDR0_AES_GCM_256:
153 	case PSP_VERSION_HDR0_AES_GMAC_256:
154 		return 32;
155 	default:
156 		return 0;
157 	}
158 }
159 EXPORT_SYMBOL(psp_key_size);
160 
161 static int __init psp_init(void)
162 {
163 	mutex_init(&psp_devs_lock);
164 
165 	return genl_register_family(&psp_nl_family);
166 }
167 
168 subsys_initcall(psp_init);
169