Commit 339412841d7620f93fea805fbd7469f08186f458
Committed by
David S. Miller
1 parent
8b815477f3
Exists in
master
and in
39 other branches
RxRPC: Allow key payloads to be passed in XDR form
Allow add_key() and KEYCTL_INSTANTIATE to accept key payloads in XDR form as described by openafs-1.4.10/src/auth/afs_token.xg. This provides a way of passing kaserver, Kerberos 4, Kerberos 5 and GSSAPI keys from userspace, and allows for future expansion. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 5 changed files with 353 additions and 75 deletions Side-by-side Diff
include/keys/rxrpc-type.h
... | ... | @@ -21,5 +21,60 @@ |
21 | 21 | |
22 | 22 | extern struct key *rxrpc_get_null_key(const char *); |
23 | 23 | |
24 | +/* | |
25 | + * RxRPC key for Kerberos IV (type-2 security) | |
26 | + */ | |
27 | +struct rxkad_key { | |
28 | + u32 vice_id; | |
29 | + u32 start; /* time at which ticket starts */ | |
30 | + u32 expiry; /* time at which ticket expires */ | |
31 | + u32 kvno; /* key version number */ | |
32 | + u8 primary_flag; /* T if key for primary cell for this user */ | |
33 | + u16 ticket_len; /* length of ticket[] */ | |
34 | + u8 session_key[8]; /* DES session key */ | |
35 | + u8 ticket[0]; /* the encrypted ticket */ | |
36 | +}; | |
37 | + | |
38 | +/* | |
39 | + * list of tokens attached to an rxrpc key | |
40 | + */ | |
41 | +struct rxrpc_key_token { | |
42 | + u16 security_index; /* RxRPC header security index */ | |
43 | + struct rxrpc_key_token *next; /* the next token in the list */ | |
44 | + union { | |
45 | + struct rxkad_key *kad; | |
46 | + }; | |
47 | +}; | |
48 | + | |
49 | +/* | |
50 | + * structure of raw payloads passed to add_key() or instantiate key | |
51 | + */ | |
52 | +struct rxrpc_key_data_v1 { | |
53 | + u32 kif_version; /* 1 */ | |
54 | + u16 security_index; | |
55 | + u16 ticket_length; | |
56 | + u32 expiry; /* time_t */ | |
57 | + u32 kvno; | |
58 | + u8 session_key[8]; | |
59 | + u8 ticket[0]; | |
60 | +}; | |
61 | + | |
62 | +/* | |
63 | + * AF_RXRPC key payload derived from XDR format | |
64 | + * - based on openafs-1.4.10/src/auth/afs_token.xg | |
65 | + */ | |
66 | +#define AFSTOKEN_LENGTH_MAX 16384 /* max payload size */ | |
67 | +#define AFSTOKEN_CELL_MAX 64 /* max cellname length */ | |
68 | +#define AFSTOKEN_MAX 8 /* max tokens per payload */ | |
69 | +#define AFSTOKEN_RK_TIX_MAX 12000 /* max RxKAD ticket size */ | |
70 | +#define AFSTOKEN_GK_KEY_MAX 64 /* max GSSAPI key size */ | |
71 | +#define AFSTOKEN_GK_TOKEN_MAX 16384 /* max GSSAPI token size */ | |
72 | +#define AFSTOKEN_K5_COMPONENTS_MAX 16 /* max K5 components */ | |
73 | +#define AFSTOKEN_K5_NAME_MAX 128 /* max K5 name length */ | |
74 | +#define AFSTOKEN_K5_REALM_MAX 64 /* max K5 realm name length */ | |
75 | +#define AFSTOKEN_K5_TIX_MAX 16384 /* max K5 ticket size */ | |
76 | +#define AFSTOKEN_K5_ADDRESSES_MAX 16 /* max K5 addresses */ | |
77 | +#define AFSTOKEN_K5_AUTHDATA_MAX 16 /* max K5 pieces of auth data */ | |
78 | + | |
24 | 79 | #endif /* _KEYS_RXRPC_TYPE_H */ |
net/rxrpc/ar-internal.h
... | ... | @@ -402,22 +402,6 @@ |
402 | 402 | }; |
403 | 403 | |
404 | 404 | /* |
405 | - * RxRPC key for Kerberos (type-2 security) | |
406 | - */ | |
407 | -struct rxkad_key { | |
408 | - u16 security_index; /* RxRPC header security index */ | |
409 | - u16 ticket_len; /* length of ticket[] */ | |
410 | - u32 expiry; /* time at which expires */ | |
411 | - u32 kvno; /* key version number */ | |
412 | - u8 session_key[8]; /* DES session key */ | |
413 | - u8 ticket[0]; /* the encrypted ticket */ | |
414 | -}; | |
415 | - | |
416 | -struct rxrpc_key_payload { | |
417 | - struct rxkad_key k; | |
418 | -}; | |
419 | - | |
420 | -/* | |
421 | 405 | * locally abort an RxRPC call |
422 | 406 | */ |
423 | 407 | static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code) |
net/rxrpc/ar-key.c
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | #include <linux/skbuff.h> |
18 | 18 | #include <linux/key-type.h> |
19 | 19 | #include <linux/crypto.h> |
20 | +#include <linux/ctype.h> | |
20 | 21 | #include <net/sock.h> |
21 | 22 | #include <net/af_rxrpc.h> |
22 | 23 | #include <keys/rxrpc-type.h> |
... | ... | @@ -55,6 +56,202 @@ |
55 | 56 | }; |
56 | 57 | |
57 | 58 | /* |
59 | + * parse an RxKAD type XDR format token | |
60 | + * - the caller guarantees we have at least 4 words | |
61 | + */ | |
62 | +static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, | |
63 | + unsigned toklen) | |
64 | +{ | |
65 | + struct rxrpc_key_token *token; | |
66 | + size_t plen; | |
67 | + u32 tktlen; | |
68 | + int ret; | |
69 | + | |
70 | + _enter(",{%x,%x,%x,%x},%u", | |
71 | + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), | |
72 | + toklen); | |
73 | + | |
74 | + if (toklen <= 8 * 4) | |
75 | + return -EKEYREJECTED; | |
76 | + tktlen = ntohl(xdr[7]); | |
77 | + _debug("tktlen: %x", tktlen); | |
78 | + if (tktlen > AFSTOKEN_RK_TIX_MAX) | |
79 | + return -EKEYREJECTED; | |
80 | + if (8 * 4 + tktlen != toklen) | |
81 | + return -EKEYREJECTED; | |
82 | + | |
83 | + plen = sizeof(*token) + sizeof(*token->kad) + tktlen; | |
84 | + ret = key_payload_reserve(key, key->datalen + plen); | |
85 | + if (ret < 0) | |
86 | + return ret; | |
87 | + | |
88 | + plen -= sizeof(*token); | |
89 | + token = kmalloc(sizeof(*token), GFP_KERNEL); | |
90 | + if (!token) | |
91 | + return -ENOMEM; | |
92 | + | |
93 | + token->kad = kmalloc(plen, GFP_KERNEL); | |
94 | + if (!token->kad) { | |
95 | + kfree(token); | |
96 | + return -ENOMEM; | |
97 | + } | |
98 | + | |
99 | + token->security_index = RXRPC_SECURITY_RXKAD; | |
100 | + token->kad->ticket_len = tktlen; | |
101 | + token->kad->vice_id = ntohl(xdr[0]); | |
102 | + token->kad->kvno = ntohl(xdr[1]); | |
103 | + token->kad->start = ntohl(xdr[4]); | |
104 | + token->kad->expiry = ntohl(xdr[5]); | |
105 | + token->kad->primary_flag = ntohl(xdr[6]); | |
106 | + memcpy(&token->kad->session_key, &xdr[2], 8); | |
107 | + memcpy(&token->kad->ticket, &xdr[8], tktlen); | |
108 | + | |
109 | + _debug("SCIX: %u", token->security_index); | |
110 | + _debug("TLEN: %u", token->kad->ticket_len); | |
111 | + _debug("EXPY: %x", token->kad->expiry); | |
112 | + _debug("KVNO: %u", token->kad->kvno); | |
113 | + _debug("PRIM: %u", token->kad->primary_flag); | |
114 | + _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", | |
115 | + token->kad->session_key[0], token->kad->session_key[1], | |
116 | + token->kad->session_key[2], token->kad->session_key[3], | |
117 | + token->kad->session_key[4], token->kad->session_key[5], | |
118 | + token->kad->session_key[6], token->kad->session_key[7]); | |
119 | + if (token->kad->ticket_len >= 8) | |
120 | + _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", | |
121 | + token->kad->ticket[0], token->kad->ticket[1], | |
122 | + token->kad->ticket[2], token->kad->ticket[3], | |
123 | + token->kad->ticket[4], token->kad->ticket[5], | |
124 | + token->kad->ticket[6], token->kad->ticket[7]); | |
125 | + | |
126 | + /* count the number of tokens attached */ | |
127 | + key->type_data.x[0]++; | |
128 | + | |
129 | + /* attach the data */ | |
130 | + token->next = key->payload.data; | |
131 | + key->payload.data = token; | |
132 | + if (token->kad->expiry < key->expiry) | |
133 | + key->expiry = token->kad->expiry; | |
134 | + | |
135 | + _leave(" = 0"); | |
136 | + return 0; | |
137 | +} | |
138 | + | |
139 | +/* | |
140 | + * attempt to parse the data as the XDR format | |
141 | + * - the caller guarantees we have more than 7 words | |
142 | + */ | |
143 | +static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) | |
144 | +{ | |
145 | + const __be32 *xdr = data, *token; | |
146 | + const char *cp; | |
147 | + unsigned len, tmp, loop, ntoken, toklen, sec_ix; | |
148 | + int ret; | |
149 | + | |
150 | + _enter(",{%x,%x,%x,%x},%zu", | |
151 | + ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), | |
152 | + datalen); | |
153 | + | |
154 | + if (datalen > AFSTOKEN_LENGTH_MAX) | |
155 | + goto not_xdr; | |
156 | + | |
157 | + /* XDR is an array of __be32's */ | |
158 | + if (datalen & 3) | |
159 | + goto not_xdr; | |
160 | + | |
161 | + /* the flags should be 0 (the setpag bit must be handled by | |
162 | + * userspace) */ | |
163 | + if (ntohl(*xdr++) != 0) | |
164 | + goto not_xdr; | |
165 | + datalen -= 4; | |
166 | + | |
167 | + /* check the cell name */ | |
168 | + len = ntohl(*xdr++); | |
169 | + if (len < 1 || len > AFSTOKEN_CELL_MAX) | |
170 | + goto not_xdr; | |
171 | + datalen -= 4; | |
172 | + tmp = (len + 3) & ~3; | |
173 | + if (tmp > datalen) | |
174 | + goto not_xdr; | |
175 | + | |
176 | + cp = (const char *) xdr; | |
177 | + for (loop = 0; loop < len; loop++) | |
178 | + if (!isprint(cp[loop])) | |
179 | + goto not_xdr; | |
180 | + if (len < tmp) | |
181 | + for (; loop < tmp; loop++) | |
182 | + if (cp[loop]) | |
183 | + goto not_xdr; | |
184 | + _debug("cellname: [%u/%u] '%*.*s'", | |
185 | + len, tmp, len, len, (const char *) xdr); | |
186 | + datalen -= tmp; | |
187 | + xdr += tmp >> 2; | |
188 | + | |
189 | + /* get the token count */ | |
190 | + if (datalen < 12) | |
191 | + goto not_xdr; | |
192 | + ntoken = ntohl(*xdr++); | |
193 | + datalen -= 4; | |
194 | + _debug("ntoken: %x", ntoken); | |
195 | + if (ntoken < 1 || ntoken > AFSTOKEN_MAX) | |
196 | + goto not_xdr; | |
197 | + | |
198 | + /* check each token wrapper */ | |
199 | + token = xdr; | |
200 | + loop = ntoken; | |
201 | + do { | |
202 | + if (datalen < 8) | |
203 | + goto not_xdr; | |
204 | + toklen = ntohl(*xdr++); | |
205 | + sec_ix = ntohl(*xdr); | |
206 | + datalen -= 4; | |
207 | + _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix); | |
208 | + if (toklen < 20 || toklen > datalen) | |
209 | + goto not_xdr; | |
210 | + datalen -= (toklen + 3) & ~3; | |
211 | + xdr += (toklen + 3) >> 2; | |
212 | + | |
213 | + } while (--loop > 0); | |
214 | + | |
215 | + _debug("remainder: %zu", datalen); | |
216 | + if (datalen != 0) | |
217 | + goto not_xdr; | |
218 | + | |
219 | + /* okay: we're going to assume it's valid XDR format | |
220 | + * - we ignore the cellname, relying on the key to be correctly named | |
221 | + */ | |
222 | + do { | |
223 | + xdr = token; | |
224 | + toklen = ntohl(*xdr++); | |
225 | + token = xdr + ((toklen + 3) >> 2); | |
226 | + sec_ix = ntohl(*xdr++); | |
227 | + toklen -= 4; | |
228 | + | |
229 | + switch (sec_ix) { | |
230 | + case RXRPC_SECURITY_RXKAD: | |
231 | + ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); | |
232 | + if (ret != 0) | |
233 | + goto error; | |
234 | + break; | |
235 | + | |
236 | + default: | |
237 | + ret = -EPROTONOSUPPORT; | |
238 | + goto error; | |
239 | + } | |
240 | + | |
241 | + } while (--ntoken > 0); | |
242 | + | |
243 | + _leave(" = 0"); | |
244 | + return 0; | |
245 | + | |
246 | +not_xdr: | |
247 | + _leave(" = -EPROTO"); | |
248 | + return -EPROTO; | |
249 | +error: | |
250 | + _leave(" = %d", ret); | |
251 | + return ret; | |
252 | +} | |
253 | + | |
254 | +/* | |
58 | 255 | * instantiate an rxrpc defined key |
59 | 256 | * data should be of the form: |
60 | 257 | * OFFSET LEN CONTENT |
... | ... | @@ -70,8 +267,8 @@ |
70 | 267 | */ |
71 | 268 | static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) |
72 | 269 | { |
73 | - const struct rxkad_key *tsec; | |
74 | - struct rxrpc_key_payload *upayload; | |
270 | + const struct rxrpc_key_data_v1 *v1; | |
271 | + struct rxrpc_key_token *token, **pp; | |
75 | 272 | size_t plen; |
76 | 273 | u32 kver; |
77 | 274 | int ret; |
... | ... | @@ -82,6 +279,13 @@ |
82 | 279 | if (!data && datalen == 0) |
83 | 280 | return 0; |
84 | 281 | |
282 | + /* determine if the XDR payload format is being used */ | |
283 | + if (datalen > 7 * 4) { | |
284 | + ret = rxrpc_instantiate_xdr(key, data, datalen); | |
285 | + if (ret != -EPROTO) | |
286 | + return ret; | |
287 | + } | |
288 | + | |
85 | 289 | /* get the key interface version number */ |
86 | 290 | ret = -EINVAL; |
87 | 291 | if (datalen <= 4 || !data) |
88 | 292 | |
89 | 293 | |
90 | 294 | |
91 | 295 | |
92 | 296 | |
93 | 297 | |
94 | 298 | |
95 | 299 | |
96 | 300 | |
97 | 301 | |
98 | 302 | |
... | ... | @@ -98,53 +302,67 @@ |
98 | 302 | |
99 | 303 | /* deal with a version 1 key */ |
100 | 304 | ret = -EINVAL; |
101 | - if (datalen < sizeof(*tsec)) | |
305 | + if (datalen < sizeof(*v1)) | |
102 | 306 | goto error; |
103 | 307 | |
104 | - tsec = data; | |
105 | - if (datalen != sizeof(*tsec) + tsec->ticket_len) | |
308 | + v1 = data; | |
309 | + if (datalen != sizeof(*v1) + v1->ticket_length) | |
106 | 310 | goto error; |
107 | 311 | |
108 | - _debug("SCIX: %u", tsec->security_index); | |
109 | - _debug("TLEN: %u", tsec->ticket_len); | |
110 | - _debug("EXPY: %x", tsec->expiry); | |
111 | - _debug("KVNO: %u", tsec->kvno); | |
312 | + _debug("SCIX: %u", v1->security_index); | |
313 | + _debug("TLEN: %u", v1->ticket_length); | |
314 | + _debug("EXPY: %x", v1->expiry); | |
315 | + _debug("KVNO: %u", v1->kvno); | |
112 | 316 | _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", |
113 | - tsec->session_key[0], tsec->session_key[1], | |
114 | - tsec->session_key[2], tsec->session_key[3], | |
115 | - tsec->session_key[4], tsec->session_key[5], | |
116 | - tsec->session_key[6], tsec->session_key[7]); | |
117 | - if (tsec->ticket_len >= 8) | |
317 | + v1->session_key[0], v1->session_key[1], | |
318 | + v1->session_key[2], v1->session_key[3], | |
319 | + v1->session_key[4], v1->session_key[5], | |
320 | + v1->session_key[6], v1->session_key[7]); | |
321 | + if (v1->ticket_length >= 8) | |
118 | 322 | _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", |
119 | - tsec->ticket[0], tsec->ticket[1], | |
120 | - tsec->ticket[2], tsec->ticket[3], | |
121 | - tsec->ticket[4], tsec->ticket[5], | |
122 | - tsec->ticket[6], tsec->ticket[7]); | |
323 | + v1->ticket[0], v1->ticket[1], | |
324 | + v1->ticket[2], v1->ticket[3], | |
325 | + v1->ticket[4], v1->ticket[5], | |
326 | + v1->ticket[6], v1->ticket[7]); | |
123 | 327 | |
124 | 328 | ret = -EPROTONOSUPPORT; |
125 | - if (tsec->security_index != RXRPC_SECURITY_RXKAD) | |
329 | + if (v1->security_index != RXRPC_SECURITY_RXKAD) | |
126 | 330 | goto error; |
127 | 331 | |
128 | - key->type_data.x[0] = tsec->security_index; | |
129 | - | |
130 | - plen = sizeof(*upayload) + tsec->ticket_len; | |
131 | - ret = key_payload_reserve(key, plen); | |
332 | + plen = sizeof(*token->kad) + v1->ticket_length; | |
333 | + ret = key_payload_reserve(key, plen + sizeof(*token)); | |
132 | 334 | if (ret < 0) |
133 | 335 | goto error; |
134 | 336 | |
135 | 337 | ret = -ENOMEM; |
136 | - upayload = kmalloc(plen, GFP_KERNEL); | |
137 | - if (!upayload) | |
338 | + token = kmalloc(sizeof(*token), GFP_KERNEL); | |
339 | + if (!token) | |
138 | 340 | goto error; |
341 | + token->kad = kmalloc(plen, GFP_KERNEL); | |
342 | + if (!token->kad) | |
343 | + goto error_free; | |
139 | 344 | |
345 | + token->security_index = RXRPC_SECURITY_RXKAD; | |
346 | + token->kad->ticket_len = v1->ticket_length; | |
347 | + token->kad->expiry = v1->expiry; | |
348 | + token->kad->kvno = v1->kvno; | |
349 | + memcpy(&token->kad->session_key, &v1->session_key, 8); | |
350 | + memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); | |
351 | + | |
140 | 352 | /* attach the data */ |
141 | - memcpy(&upayload->k, tsec, sizeof(*tsec)); | |
142 | - memcpy(&upayload->k.ticket, (void *)tsec + sizeof(*tsec), | |
143 | - tsec->ticket_len); | |
144 | - key->payload.data = upayload; | |
145 | - key->expiry = tsec->expiry; | |
353 | + key->type_data.x[0]++; | |
354 | + | |
355 | + pp = (struct rxrpc_key_token **)&key->payload.data; | |
356 | + while (*pp) | |
357 | + pp = &(*pp)->next; | |
358 | + *pp = token; | |
359 | + if (token->kad->expiry < key->expiry) | |
360 | + key->expiry = token->kad->expiry; | |
361 | + token = NULL; | |
146 | 362 | ret = 0; |
147 | 363 | |
364 | +error_free: | |
365 | + kfree(token); | |
148 | 366 | error: |
149 | 367 | return ret; |
150 | 368 | } |
... | ... | @@ -184,7 +402,22 @@ |
184 | 402 | */ |
185 | 403 | static void rxrpc_destroy(struct key *key) |
186 | 404 | { |
187 | - kfree(key->payload.data); | |
405 | + struct rxrpc_key_token *token; | |
406 | + | |
407 | + while ((token = key->payload.data)) { | |
408 | + key->payload.data = token->next; | |
409 | + switch (token->security_index) { | |
410 | + case RXRPC_SECURITY_RXKAD: | |
411 | + kfree(token->kad); | |
412 | + break; | |
413 | + default: | |
414 | + printk(KERN_ERR "Unknown token type %x on rxrpc key\n", | |
415 | + token->security_index); | |
416 | + BUG(); | |
417 | + } | |
418 | + | |
419 | + kfree(token); | |
420 | + } | |
188 | 421 | } |
189 | 422 | |
190 | 423 | /* |
... | ... | @@ -293,7 +526,7 @@ |
293 | 526 | |
294 | 527 | struct { |
295 | 528 | u32 kver; |
296 | - struct rxkad_key tsec; | |
529 | + struct rxrpc_key_data_v1 v1; | |
297 | 530 | } data; |
298 | 531 | |
299 | 532 | _enter(""); |
300 | 533 | |
... | ... | @@ -308,13 +541,12 @@ |
308 | 541 | _debug("key %d", key_serial(key)); |
309 | 542 | |
310 | 543 | data.kver = 1; |
311 | - data.tsec.security_index = RXRPC_SECURITY_RXKAD; | |
312 | - data.tsec.ticket_len = 0; | |
313 | - data.tsec.expiry = expiry; | |
314 | - data.tsec.kvno = 0; | |
544 | + data.v1.security_index = RXRPC_SECURITY_RXKAD; | |
545 | + data.v1.ticket_length = 0; | |
546 | + data.v1.expiry = expiry; | |
547 | + data.v1.kvno = 0; | |
315 | 548 | |
316 | - memcpy(&data.tsec.session_key, session_key, | |
317 | - sizeof(data.tsec.session_key)); | |
549 | + memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); | |
318 | 550 | |
319 | 551 | ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); |
320 | 552 | if (ret < 0) |
net/rxrpc/ar-security.c
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | #include <linux/crypto.h> |
17 | 17 | #include <net/sock.h> |
18 | 18 | #include <net/af_rxrpc.h> |
19 | +#include <keys/rxrpc-type.h> | |
19 | 20 | #include "ar-internal.h" |
20 | 21 | |
21 | 22 | static LIST_HEAD(rxrpc_security_methods); |
... | ... | @@ -122,6 +123,7 @@ |
122 | 123 | */ |
123 | 124 | int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) |
124 | 125 | { |
126 | + struct rxrpc_key_token *token; | |
125 | 127 | struct rxrpc_security *sec; |
126 | 128 | struct key *key = conn->key; |
127 | 129 | int ret; |
... | ... | @@ -135,7 +137,11 @@ |
135 | 137 | if (ret < 0) |
136 | 138 | return ret; |
137 | 139 | |
138 | - sec = rxrpc_security_lookup(key->type_data.x[0]); | |
140 | + if (!key->payload.data) | |
141 | + return -EKEYREJECTED; | |
142 | + token = key->payload.data; | |
143 | + | |
144 | + sec = rxrpc_security_lookup(token->security_index); | |
139 | 145 | if (!sec) |
140 | 146 | return -EKEYREJECTED; |
141 | 147 | conn->security = sec; |
net/rxrpc/rxkad.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | #include <linux/ctype.h> |
19 | 19 | #include <net/sock.h> |
20 | 20 | #include <net/af_rxrpc.h> |
21 | +#include <keys/rxrpc-type.h> | |
21 | 22 | #define rxrpc_debug rxkad_debug |
22 | 23 | #include "ar-internal.h" |
23 | 24 | |
24 | 25 | |
25 | 26 | |
... | ... | @@ -59,14 +60,14 @@ |
59 | 60 | */ |
60 | 61 | static int rxkad_init_connection_security(struct rxrpc_connection *conn) |
61 | 62 | { |
62 | - struct rxrpc_key_payload *payload; | |
63 | 63 | struct crypto_blkcipher *ci; |
64 | + struct rxrpc_key_token *token; | |
64 | 65 | int ret; |
65 | 66 | |
66 | 67 | _enter("{%d},{%x}", conn->debug_id, key_serial(conn->key)); |
67 | 68 | |
68 | - payload = conn->key->payload.data; | |
69 | - conn->security_ix = payload->k.security_index; | |
69 | + token = conn->key->payload.data; | |
70 | + conn->security_ix = token->security_index; | |
70 | 71 | |
71 | 72 | ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); |
72 | 73 | if (IS_ERR(ci)) { |
... | ... | @@ -75,8 +76,8 @@ |
75 | 76 | goto error; |
76 | 77 | } |
77 | 78 | |
78 | - if (crypto_blkcipher_setkey(ci, payload->k.session_key, | |
79 | - sizeof(payload->k.session_key)) < 0) | |
79 | + if (crypto_blkcipher_setkey(ci, token->kad->session_key, | |
80 | + sizeof(token->kad->session_key)) < 0) | |
80 | 81 | BUG(); |
81 | 82 | |
82 | 83 | switch (conn->security_level) { |
... | ... | @@ -110,7 +111,7 @@ |
110 | 111 | */ |
111 | 112 | static void rxkad_prime_packet_security(struct rxrpc_connection *conn) |
112 | 113 | { |
113 | - struct rxrpc_key_payload *payload; | |
114 | + struct rxrpc_key_token *token; | |
114 | 115 | struct blkcipher_desc desc; |
115 | 116 | struct scatterlist sg[2]; |
116 | 117 | struct rxrpc_crypt iv; |
... | ... | @@ -123,8 +124,8 @@ |
123 | 124 | if (!conn->key) |
124 | 125 | return; |
125 | 126 | |
126 | - payload = conn->key->payload.data; | |
127 | - memcpy(&iv, payload->k.session_key, sizeof(iv)); | |
127 | + token = conn->key->payload.data; | |
128 | + memcpy(&iv, token->kad->session_key, sizeof(iv)); | |
128 | 129 | |
129 | 130 | desc.tfm = conn->cipher; |
130 | 131 | desc.info = iv.x; |
... | ... | @@ -197,7 +198,7 @@ |
197 | 198 | u32 data_size, |
198 | 199 | void *sechdr) |
199 | 200 | { |
200 | - const struct rxrpc_key_payload *payload; | |
201 | + const struct rxrpc_key_token *token; | |
201 | 202 | struct rxkad_level2_hdr rxkhdr |
202 | 203 | __attribute__((aligned(8))); /* must be all on one page */ |
203 | 204 | struct rxrpc_skb_priv *sp; |
... | ... | @@ -219,8 +220,8 @@ |
219 | 220 | rxkhdr.checksum = 0; |
220 | 221 | |
221 | 222 | /* encrypt from the session key */ |
222 | - payload = call->conn->key->payload.data; | |
223 | - memcpy(&iv, payload->k.session_key, sizeof(iv)); | |
223 | + token = call->conn->key->payload.data; | |
224 | + memcpy(&iv, token->kad->session_key, sizeof(iv)); | |
224 | 225 | desc.tfm = call->conn->cipher; |
225 | 226 | desc.info = iv.x; |
226 | 227 | desc.flags = 0; |
... | ... | @@ -400,7 +401,7 @@ |
400 | 401 | struct sk_buff *skb, |
401 | 402 | u32 *_abort_code) |
402 | 403 | { |
403 | - const struct rxrpc_key_payload *payload; | |
404 | + const struct rxrpc_key_token *token; | |
404 | 405 | struct rxkad_level2_hdr sechdr; |
405 | 406 | struct rxrpc_skb_priv *sp; |
406 | 407 | struct blkcipher_desc desc; |
... | ... | @@ -431,8 +432,8 @@ |
431 | 432 | skb_to_sgvec(skb, sg, 0, skb->len); |
432 | 433 | |
433 | 434 | /* decrypt from the session key */ |
434 | - payload = call->conn->key->payload.data; | |
435 | - memcpy(&iv, payload->k.session_key, sizeof(iv)); | |
435 | + token = call->conn->key->payload.data; | |
436 | + memcpy(&iv, token->kad->session_key, sizeof(iv)); | |
436 | 437 | desc.tfm = call->conn->cipher; |
437 | 438 | desc.info = iv.x; |
438 | 439 | desc.flags = 0; |
... | ... | @@ -737,7 +738,7 @@ |
737 | 738 | struct sk_buff *skb, |
738 | 739 | u32 *_abort_code) |
739 | 740 | { |
740 | - const struct rxrpc_key_payload *payload; | |
741 | + const struct rxrpc_key_token *token; | |
741 | 742 | struct rxkad_challenge challenge; |
742 | 743 | struct rxkad_response resp |
743 | 744 | __attribute__((aligned(8))); /* must be aligned for crypto */ |
... | ... | @@ -778,7 +779,7 @@ |
778 | 779 | if (conn->security_level < min_level) |
779 | 780 | goto protocol_error; |
780 | 781 | |
781 | - payload = conn->key->payload.data; | |
782 | + token = conn->key->payload.data; | |
782 | 783 | |
783 | 784 | /* build the response packet */ |
784 | 785 | memset(&resp, 0, sizeof(resp)); |
785 | 786 | |
... | ... | @@ -797,13 +798,13 @@ |
797 | 798 | (conn->channels[3] ? conn->channels[3]->call_id : 0); |
798 | 799 | resp.encrypted.inc_nonce = htonl(nonce + 1); |
799 | 800 | resp.encrypted.level = htonl(conn->security_level); |
800 | - resp.kvno = htonl(payload->k.kvno); | |
801 | - resp.ticket_len = htonl(payload->k.ticket_len); | |
801 | + resp.kvno = htonl(token->kad->kvno); | |
802 | + resp.ticket_len = htonl(token->kad->ticket_len); | |
802 | 803 | |
803 | 804 | /* calculate the response checksum and then do the encryption */ |
804 | 805 | rxkad_calc_response_checksum(&resp); |
805 | - rxkad_encrypt_response(conn, &resp, &payload->k); | |
806 | - return rxkad_send_response(conn, &sp->hdr, &resp, &payload->k); | |
806 | + rxkad_encrypt_response(conn, &resp, token->kad); | |
807 | + return rxkad_send_response(conn, &sp->hdr, &resp, token->kad); | |
807 | 808 | |
808 | 809 | protocol_error: |
809 | 810 | *_abort_code = abort_code; |