Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-or-later */
2 : /*
3 : * CIPSO - Commercial IP Security Option
4 : *
5 : * This is an implementation of the CIPSO 2.2 protocol as specified in
6 : * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
7 : * FIPS-188, copies of both documents can be found in the Documentation
8 : * directory. While CIPSO never became a full IETF RFC standard many vendors
9 : * have chosen to adopt the protocol and over the years it has become a
10 : * de-facto standard for labeled networking.
11 : *
12 : * Author: Paul Moore <paul@paul-moore.com>
13 : */
14 :
15 : /*
16 : * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
17 : */
18 :
19 : #ifndef _CIPSO_IPV4_H
20 : #define _CIPSO_IPV4_H
21 :
22 : #include <linux/types.h>
23 : #include <linux/rcupdate.h>
24 : #include <linux/list.h>
25 : #include <linux/net.h>
26 : #include <linux/skbuff.h>
27 : #include <net/netlabel.h>
28 : #include <net/request_sock.h>
29 : #include <linux/atomic.h>
30 : #include <linux/refcount.h>
31 : #include <asm/unaligned.h>
32 :
33 : /* known doi values */
34 : #define CIPSO_V4_DOI_UNKNOWN 0x00000000
35 :
36 : /* standard tag types */
37 : #define CIPSO_V4_TAG_INVALID 0
38 : #define CIPSO_V4_TAG_RBITMAP 1
39 : #define CIPSO_V4_TAG_ENUM 2
40 : #define CIPSO_V4_TAG_RANGE 5
41 : #define CIPSO_V4_TAG_PBITMAP 6
42 : #define CIPSO_V4_TAG_FREEFORM 7
43 :
44 : /* non-standard tag types (tags > 127) */
45 : #define CIPSO_V4_TAG_LOCAL 128
46 :
47 : /* doi mapping types */
48 : #define CIPSO_V4_MAP_UNKNOWN 0
49 : #define CIPSO_V4_MAP_TRANS 1
50 : #define CIPSO_V4_MAP_PASS 2
51 : #define CIPSO_V4_MAP_LOCAL 3
52 :
53 : /* limits */
54 : #define CIPSO_V4_MAX_REM_LVLS 255
55 : #define CIPSO_V4_INV_LVL 0x80000000
56 : #define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1)
57 : #define CIPSO_V4_MAX_REM_CATS 65534
58 : #define CIPSO_V4_INV_CAT 0x80000000
59 : #define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1)
60 :
61 : /*
62 : * CIPSO DOI definitions
63 : */
64 :
65 : /* DOI definition struct */
66 : #define CIPSO_V4_TAG_MAXCNT 5
67 : struct cipso_v4_doi {
68 : u32 doi;
69 : u32 type;
70 : union {
71 : struct cipso_v4_std_map_tbl *std;
72 : } map;
73 : u8 tags[CIPSO_V4_TAG_MAXCNT];
74 :
75 : refcount_t refcount;
76 : struct list_head list;
77 : struct rcu_head rcu;
78 : };
79 :
80 : /* Standard CIPSO mapping table */
81 : /* NOTE: the highest order bit (i.e. 0x80000000) is an 'invalid' flag, if the
82 : * bit is set then consider that value as unspecified, meaning the
83 : * mapping for that particular level/category is invalid */
84 : struct cipso_v4_std_map_tbl {
85 : struct {
86 : u32 *cipso;
87 : u32 *local;
88 : u32 cipso_size;
89 : u32 local_size;
90 : } lvl;
91 : struct {
92 : u32 *cipso;
93 : u32 *local;
94 : u32 cipso_size;
95 : u32 local_size;
96 : } cat;
97 : };
98 :
99 : /*
100 : * Sysctl Variables
101 : */
102 :
103 : #ifdef CONFIG_NETLABEL
104 : extern int cipso_v4_cache_enabled;
105 : extern int cipso_v4_cache_bucketsize;
106 : extern int cipso_v4_rbm_optfmt;
107 : extern int cipso_v4_rbm_strictvalid;
108 : #endif
109 :
110 : /*
111 : * DOI List Functions
112 : */
113 :
114 : #ifdef CONFIG_NETLABEL
115 : int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
116 : struct netlbl_audit *audit_info);
117 : void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
118 : int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
119 : struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
120 : void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def);
121 : int cipso_v4_doi_walk(u32 *skip_cnt,
122 : int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
123 : void *cb_arg);
124 : #else
125 : static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
126 : struct netlbl_audit *audit_info)
127 : {
128 : return -ENOSYS;
129 : }
130 :
131 : static inline void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
132 : {
133 : return;
134 : }
135 :
136 : static inline int cipso_v4_doi_remove(u32 doi,
137 : struct netlbl_audit *audit_info)
138 : {
139 : return 0;
140 : }
141 :
142 : static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
143 : {
144 : return NULL;
145 : }
146 :
147 : static inline int cipso_v4_doi_walk(u32 *skip_cnt,
148 : int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
149 : void *cb_arg)
150 : {
151 : return 0;
152 : }
153 : #endif /* CONFIG_NETLABEL */
154 :
155 : /*
156 : * Label Mapping Cache Functions
157 : */
158 :
159 : #ifdef CONFIG_NETLABEL
160 : void cipso_v4_cache_invalidate(void);
161 : int cipso_v4_cache_add(const unsigned char *cipso_ptr,
162 : const struct netlbl_lsm_secattr *secattr);
163 : #else
164 : static inline void cipso_v4_cache_invalidate(void)
165 : {
166 : return;
167 : }
168 :
169 : static inline int cipso_v4_cache_add(const unsigned char *cipso_ptr,
170 : const struct netlbl_lsm_secattr *secattr)
171 : {
172 : return 0;
173 : }
174 : #endif /* CONFIG_NETLABEL */
175 :
176 : /*
177 : * Protocol Handling Functions
178 : */
179 :
180 : #ifdef CONFIG_NETLABEL
181 : void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
182 : int cipso_v4_getattr(const unsigned char *cipso,
183 : struct netlbl_lsm_secattr *secattr);
184 : int cipso_v4_sock_setattr(struct sock *sk,
185 : const struct cipso_v4_doi *doi_def,
186 : const struct netlbl_lsm_secattr *secattr);
187 : void cipso_v4_sock_delattr(struct sock *sk);
188 : int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
189 : int cipso_v4_req_setattr(struct request_sock *req,
190 : const struct cipso_v4_doi *doi_def,
191 : const struct netlbl_lsm_secattr *secattr);
192 : void cipso_v4_req_delattr(struct request_sock *req);
193 : int cipso_v4_skbuff_setattr(struct sk_buff *skb,
194 : const struct cipso_v4_doi *doi_def,
195 : const struct netlbl_lsm_secattr *secattr);
196 : int cipso_v4_skbuff_delattr(struct sk_buff *skb);
197 : int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
198 : struct netlbl_lsm_secattr *secattr);
199 : unsigned char *cipso_v4_optptr(const struct sk_buff *skb);
200 : int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option);
201 : #else
202 : static inline void cipso_v4_error(struct sk_buff *skb,
203 : int error,
204 : u32 gateway)
205 : {
206 : return;
207 : }
208 :
209 : static inline int cipso_v4_getattr(const unsigned char *cipso,
210 : struct netlbl_lsm_secattr *secattr)
211 : {
212 : return -ENOSYS;
213 : }
214 :
215 : static inline int cipso_v4_sock_setattr(struct sock *sk,
216 : const struct cipso_v4_doi *doi_def,
217 : const struct netlbl_lsm_secattr *secattr)
218 : {
219 : return -ENOSYS;
220 : }
221 :
222 : static inline void cipso_v4_sock_delattr(struct sock *sk)
223 : {
224 : }
225 :
226 : static inline int cipso_v4_sock_getattr(struct sock *sk,
227 : struct netlbl_lsm_secattr *secattr)
228 : {
229 : return -ENOSYS;
230 : }
231 :
232 : static inline int cipso_v4_req_setattr(struct request_sock *req,
233 : const struct cipso_v4_doi *doi_def,
234 : const struct netlbl_lsm_secattr *secattr)
235 : {
236 : return -ENOSYS;
237 : }
238 :
239 : static inline void cipso_v4_req_delattr(struct request_sock *req)
240 : {
241 : return;
242 : }
243 :
244 : static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
245 : const struct cipso_v4_doi *doi_def,
246 : const struct netlbl_lsm_secattr *secattr)
247 : {
248 : return -ENOSYS;
249 : }
250 :
251 : static inline int cipso_v4_skbuff_delattr(struct sk_buff *skb)
252 : {
253 : return -ENOSYS;
254 : }
255 :
256 : static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
257 : struct netlbl_lsm_secattr *secattr)
258 : {
259 : return -ENOSYS;
260 : }
261 :
262 : static inline unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
263 : {
264 : return NULL;
265 : }
266 :
267 0 : static inline int cipso_v4_validate(const struct sk_buff *skb,
268 : unsigned char **option)
269 : {
270 0 : unsigned char *opt = *option;
271 0 : unsigned char err_offset = 0;
272 0 : u8 opt_len = opt[1];
273 0 : u8 opt_iter;
274 0 : u8 tag_len;
275 :
276 0 : if (opt_len < 8) {
277 0 : err_offset = 1;
278 0 : goto out;
279 : }
280 :
281 0 : if (get_unaligned_be32(&opt[2]) == 0) {
282 0 : err_offset = 2;
283 0 : goto out;
284 : }
285 :
286 0 : for (opt_iter = 6; opt_iter < opt_len;) {
287 0 : if (opt_iter + 1 == opt_len) {
288 0 : err_offset = opt_iter;
289 0 : goto out;
290 : }
291 0 : tag_len = opt[opt_iter + 1];
292 0 : if ((tag_len == 0) || (tag_len > (opt_len - opt_iter))) {
293 0 : err_offset = opt_iter + 1;
294 0 : goto out;
295 : }
296 0 : opt_iter += tag_len;
297 : }
298 :
299 0 : out:
300 0 : *option = opt + err_offset;
301 0 : return err_offset;
302 :
303 : }
304 : #endif /* CONFIG_NETLABEL */
305 :
306 : #endif /* _CIPSO_IPV4_H */
|