1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* Kerberos-based RxRPC security |
3 | * |
4 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
5 | * Written by David Howells (dhowells@redhat.com) |
6 | */ |
7 | |
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
9 | |
10 | #include <crypto/skcipher.h> |
11 | #include <linux/module.h> |
12 | #include <linux/net.h> |
13 | #include <linux/skbuff.h> |
14 | #include <linux/udp.h> |
15 | #include <linux/scatterlist.h> |
16 | #include <linux/ctype.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/key-type.h> |
19 | #include <net/sock.h> |
20 | #include <net/af_rxrpc.h> |
21 | #include <keys/rxrpc-type.h> |
22 | #include "ar-internal.h" |
23 | |
24 | #define RXKAD_VERSION 2 |
25 | #define MAXKRB5TICKETLEN 1024 |
26 | #define RXKAD_TKT_TYPE_KERBEROS_V5 256 |
27 | #define ANAME_SZ 40 /* size of authentication name */ |
28 | #define INST_SZ 40 /* size of principal's instance */ |
29 | #define REALM_SZ 40 /* size of principal's auth domain */ |
30 | #define SNAME_SZ 40 /* size of service name */ |
31 | #define RXKAD_ALIGN 8 |
32 | |
33 | struct rxkad_level1_hdr { |
34 | __be32 data_size; /* true data size (excluding padding) */ |
35 | }; |
36 | |
37 | struct rxkad_level2_hdr { |
38 | __be32 data_size; /* true data size (excluding padding) */ |
39 | __be32 checksum; /* decrypted data checksum */ |
40 | }; |
41 | |
42 | static int rxkad_prime_packet_security(struct rxrpc_connection *conn, |
43 | struct crypto_sync_skcipher *ci); |
44 | |
45 | /* |
46 | * this holds a pinned cipher so that keventd doesn't get called by the cipher |
47 | * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE |
48 | * packets |
49 | */ |
50 | static struct crypto_sync_skcipher *rxkad_ci; |
51 | static struct skcipher_request *rxkad_ci_req; |
52 | static DEFINE_MUTEX(rxkad_ci_mutex); |
53 | |
54 | /* |
55 | * Parse the information from a server key |
56 | * |
57 | * The data should be the 8-byte secret key. |
58 | */ |
59 | static int rxkad_preparse_server_key(struct key_preparsed_payload *prep) |
60 | { |
61 | struct crypto_skcipher *ci; |
62 | |
63 | if (prep->datalen != 8) |
64 | return -EINVAL; |
65 | |
66 | memcpy(&prep->payload.data[2], prep->data, 8); |
67 | |
68 | ci = crypto_alloc_skcipher(alg_name: "pcbc(des)" , type: 0, CRYPTO_ALG_ASYNC); |
69 | if (IS_ERR(ptr: ci)) { |
70 | _leave(" = %ld" , PTR_ERR(ci)); |
71 | return PTR_ERR(ptr: ci); |
72 | } |
73 | |
74 | if (crypto_skcipher_setkey(tfm: ci, key: prep->data, keylen: 8) < 0) |
75 | BUG(); |
76 | |
77 | prep->payload.data[0] = ci; |
78 | _leave(" = 0" ); |
79 | return 0; |
80 | } |
81 | |
82 | static void rxkad_free_preparse_server_key(struct key_preparsed_payload *prep) |
83 | { |
84 | |
85 | if (prep->payload.data[0]) |
86 | crypto_free_skcipher(tfm: prep->payload.data[0]); |
87 | } |
88 | |
89 | static void rxkad_destroy_server_key(struct key *key) |
90 | { |
91 | if (key->payload.data[0]) { |
92 | crypto_free_skcipher(tfm: key->payload.data[0]); |
93 | key->payload.data[0] = NULL; |
94 | } |
95 | } |
96 | |
97 | /* |
98 | * initialise connection security |
99 | */ |
100 | static int rxkad_init_connection_security(struct rxrpc_connection *conn, |
101 | struct rxrpc_key_token *token) |
102 | { |
103 | struct crypto_sync_skcipher *ci; |
104 | int ret; |
105 | |
106 | _enter("{%d},{%x}" , conn->debug_id, key_serial(conn->key)); |
107 | |
108 | conn->security_ix = token->security_index; |
109 | |
110 | ci = crypto_alloc_sync_skcipher(alg_name: "pcbc(fcrypt)" , type: 0, mask: 0); |
111 | if (IS_ERR(ptr: ci)) { |
112 | _debug("no cipher" ); |
113 | ret = PTR_ERR(ptr: ci); |
114 | goto error; |
115 | } |
116 | |
117 | if (crypto_sync_skcipher_setkey(tfm: ci, key: token->kad->session_key, |
118 | keylen: sizeof(token->kad->session_key)) < 0) |
119 | BUG(); |
120 | |
121 | switch (conn->security_level) { |
122 | case RXRPC_SECURITY_PLAIN: |
123 | case RXRPC_SECURITY_AUTH: |
124 | case RXRPC_SECURITY_ENCRYPT: |
125 | break; |
126 | default: |
127 | ret = -EKEYREJECTED; |
128 | goto error; |
129 | } |
130 | |
131 | ret = rxkad_prime_packet_security(conn, ci); |
132 | if (ret < 0) |
133 | goto error_ci; |
134 | |
135 | conn->rxkad.cipher = ci; |
136 | return 0; |
137 | |
138 | error_ci: |
139 | crypto_free_sync_skcipher(tfm: ci); |
140 | error: |
141 | _leave(" = %d" , ret); |
142 | return ret; |
143 | } |
144 | |
145 | /* |
146 | * Work out how much data we can put in a packet. |
147 | */ |
148 | static struct rxrpc_txbuf *rxkad_alloc_txbuf(struct rxrpc_call *call, size_t remain, gfp_t gfp) |
149 | { |
150 | struct rxrpc_txbuf *txb; |
151 | size_t shdr, space; |
152 | |
153 | remain = min(remain, 65535 - sizeof(struct rxrpc_wire_header)); |
154 | |
155 | switch (call->conn->security_level) { |
156 | default: |
157 | space = min_t(size_t, remain, RXRPC_JUMBO_DATALEN); |
158 | return rxrpc_alloc_data_txbuf(call, data_size: space, data_align: 0, gfp); |
159 | case RXRPC_SECURITY_AUTH: |
160 | shdr = sizeof(struct rxkad_level1_hdr); |
161 | break; |
162 | case RXRPC_SECURITY_ENCRYPT: |
163 | shdr = sizeof(struct rxkad_level2_hdr); |
164 | break; |
165 | } |
166 | |
167 | space = min_t(size_t, round_down(RXRPC_JUMBO_DATALEN, RXKAD_ALIGN), remain + shdr); |
168 | space = round_up(space, RXKAD_ALIGN); |
169 | |
170 | txb = rxrpc_alloc_data_txbuf(call, data_size: space, RXKAD_ALIGN, gfp); |
171 | if (!txb) |
172 | return NULL; |
173 | |
174 | txb->offset += shdr; |
175 | txb->space -= shdr; |
176 | return txb; |
177 | } |
178 | |
179 | /* |
180 | * prime the encryption state with the invariant parts of a connection's |
181 | * description |
182 | */ |
183 | static int rxkad_prime_packet_security(struct rxrpc_connection *conn, |
184 | struct crypto_sync_skcipher *ci) |
185 | { |
186 | struct skcipher_request *req; |
187 | struct rxrpc_key_token *token; |
188 | struct scatterlist sg; |
189 | struct rxrpc_crypt iv; |
190 | __be32 *tmpbuf; |
191 | size_t tmpsize = 4 * sizeof(__be32); |
192 | |
193 | _enter("" ); |
194 | |
195 | if (!conn->key) |
196 | return 0; |
197 | |
198 | tmpbuf = kmalloc(size: tmpsize, GFP_KERNEL); |
199 | if (!tmpbuf) |
200 | return -ENOMEM; |
201 | |
202 | req = skcipher_request_alloc(tfm: &ci->base, GFP_NOFS); |
203 | if (!req) { |
204 | kfree(objp: tmpbuf); |
205 | return -ENOMEM; |
206 | } |
207 | |
208 | token = conn->key->payload.data[0]; |
209 | memcpy(&iv, token->kad->session_key, sizeof(iv)); |
210 | |
211 | tmpbuf[0] = htonl(conn->proto.epoch); |
212 | tmpbuf[1] = htonl(conn->proto.cid); |
213 | tmpbuf[2] = 0; |
214 | tmpbuf[3] = htonl(conn->security_ix); |
215 | |
216 | sg_init_one(&sg, tmpbuf, tmpsize); |
217 | skcipher_request_set_sync_tfm(req, tfm: ci); |
218 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
219 | skcipher_request_set_crypt(req, src: &sg, dst: &sg, cryptlen: tmpsize, iv: iv.x); |
220 | crypto_skcipher_encrypt(req); |
221 | skcipher_request_free(req); |
222 | |
223 | memcpy(&conn->rxkad.csum_iv, tmpbuf + 2, sizeof(conn->rxkad.csum_iv)); |
224 | kfree(objp: tmpbuf); |
225 | _leave(" = 0" ); |
226 | return 0; |
227 | } |
228 | |
229 | /* |
230 | * Allocate and prepare the crypto request on a call. For any particular call, |
231 | * this is called serially for the packets, so no lock should be necessary. |
232 | */ |
233 | static struct skcipher_request *rxkad_get_call_crypto(struct rxrpc_call *call) |
234 | { |
235 | struct crypto_skcipher *tfm = &call->conn->rxkad.cipher->base; |
236 | |
237 | return skcipher_request_alloc(tfm, GFP_NOFS); |
238 | } |
239 | |
240 | /* |
241 | * Clean up the crypto on a call. |
242 | */ |
243 | static void rxkad_free_call_crypto(struct rxrpc_call *call) |
244 | { |
245 | } |
246 | |
247 | /* |
248 | * partially encrypt a packet (level 1 security) |
249 | */ |
250 | static int rxkad_secure_packet_auth(const struct rxrpc_call *call, |
251 | struct rxrpc_txbuf *txb, |
252 | struct skcipher_request *req) |
253 | { |
254 | struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base; |
255 | struct rxkad_level1_hdr *hdr = (void *)(whdr + 1); |
256 | struct rxrpc_crypt iv; |
257 | struct scatterlist sg; |
258 | size_t pad; |
259 | u16 check; |
260 | |
261 | _enter("" ); |
262 | |
263 | check = txb->seq ^ call->call_id; |
264 | hdr->data_size = htonl((u32)check << 16 | txb->len); |
265 | |
266 | txb->len += sizeof(struct rxkad_level1_hdr); |
267 | pad = txb->len; |
268 | pad = RXKAD_ALIGN - pad; |
269 | pad &= RXKAD_ALIGN - 1; |
270 | if (pad) { |
271 | memset(txb->kvec[0].iov_base + txb->offset, 0, pad); |
272 | txb->len += pad; |
273 | } |
274 | |
275 | /* start the encryption afresh */ |
276 | memset(&iv, 0, sizeof(iv)); |
277 | |
278 | sg_init_one(&sg, hdr, 8); |
279 | skcipher_request_set_sync_tfm(req, tfm: call->conn->rxkad.cipher); |
280 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
281 | skcipher_request_set_crypt(req, src: &sg, dst: &sg, cryptlen: 8, iv: iv.x); |
282 | crypto_skcipher_encrypt(req); |
283 | skcipher_request_zero(req); |
284 | |
285 | _leave(" = 0" ); |
286 | return 0; |
287 | } |
288 | |
289 | /* |
290 | * wholly encrypt a packet (level 2 security) |
291 | */ |
292 | static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, |
293 | struct rxrpc_txbuf *txb, |
294 | struct skcipher_request *req) |
295 | { |
296 | const struct rxrpc_key_token *token; |
297 | struct rxrpc_wire_header *whdr = txb->kvec[0].iov_base; |
298 | struct rxkad_level2_hdr *rxkhdr = (void *)(whdr + 1); |
299 | struct rxrpc_crypt iv; |
300 | struct scatterlist sg; |
301 | size_t pad; |
302 | u16 check; |
303 | int ret; |
304 | |
305 | _enter("" ); |
306 | |
307 | check = txb->seq ^ call->call_id; |
308 | |
309 | rxkhdr->data_size = htonl(txb->len | (u32)check << 16); |
310 | rxkhdr->checksum = 0; |
311 | |
312 | txb->len += sizeof(struct rxkad_level2_hdr); |
313 | pad = txb->len; |
314 | pad = RXKAD_ALIGN - pad; |
315 | pad &= RXKAD_ALIGN - 1; |
316 | if (pad) { |
317 | memset(txb->kvec[0].iov_base + txb->offset, 0, pad); |
318 | txb->len += pad; |
319 | } |
320 | |
321 | /* encrypt from the session key */ |
322 | token = call->conn->key->payload.data[0]; |
323 | memcpy(&iv, token->kad->session_key, sizeof(iv)); |
324 | |
325 | sg_init_one(&sg, rxkhdr, txb->len); |
326 | skcipher_request_set_sync_tfm(req, tfm: call->conn->rxkad.cipher); |
327 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
328 | skcipher_request_set_crypt(req, src: &sg, dst: &sg, cryptlen: txb->len, iv: iv.x); |
329 | ret = crypto_skcipher_encrypt(req); |
330 | skcipher_request_zero(req); |
331 | return ret; |
332 | } |
333 | |
334 | /* |
335 | * checksum an RxRPC packet header |
336 | */ |
337 | static int rxkad_secure_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb) |
338 | { |
339 | struct skcipher_request *req; |
340 | struct rxrpc_crypt iv; |
341 | struct scatterlist sg; |
342 | union { |
343 | __be32 buf[2]; |
344 | } crypto __aligned(8); |
345 | u32 x, y; |
346 | int ret; |
347 | |
348 | _enter("{%d{%x}},{#%u},%u," , |
349 | call->debug_id, key_serial(call->conn->key), |
350 | txb->seq, txb->len); |
351 | |
352 | if (!call->conn->rxkad.cipher) |
353 | return 0; |
354 | |
355 | ret = key_validate(key: call->conn->key); |
356 | if (ret < 0) |
357 | return ret; |
358 | |
359 | req = rxkad_get_call_crypto(call); |
360 | if (!req) |
361 | return -ENOMEM; |
362 | |
363 | /* continue encrypting from where we left off */ |
364 | memcpy(&iv, call->conn->rxkad.csum_iv.x, sizeof(iv)); |
365 | |
366 | /* calculate the security checksum */ |
367 | x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT); |
368 | x |= txb->seq & 0x3fffffff; |
369 | crypto.buf[0] = htonl(call->call_id); |
370 | crypto.buf[1] = htonl(x); |
371 | |
372 | sg_init_one(&sg, crypto.buf, 8); |
373 | skcipher_request_set_sync_tfm(req, tfm: call->conn->rxkad.cipher); |
374 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
375 | skcipher_request_set_crypt(req, src: &sg, dst: &sg, cryptlen: 8, iv: iv.x); |
376 | crypto_skcipher_encrypt(req); |
377 | skcipher_request_zero(req); |
378 | |
379 | y = ntohl(crypto.buf[1]); |
380 | y = (y >> 16) & 0xffff; |
381 | if (y == 0) |
382 | y = 1; /* zero checksums are not permitted */ |
383 | txb->cksum = htons(y); |
384 | |
385 | switch (call->conn->security_level) { |
386 | case RXRPC_SECURITY_PLAIN: |
387 | ret = 0; |
388 | break; |
389 | case RXRPC_SECURITY_AUTH: |
390 | ret = rxkad_secure_packet_auth(call, txb, req); |
391 | break; |
392 | case RXRPC_SECURITY_ENCRYPT: |
393 | ret = rxkad_secure_packet_encrypt(call, txb, req); |
394 | break; |
395 | default: |
396 | ret = -EPERM; |
397 | break; |
398 | } |
399 | |
400 | skcipher_request_free(req); |
401 | _leave(" = %d [set %x]" , ret, y); |
402 | return ret; |
403 | } |
404 | |
405 | /* |
406 | * decrypt partial encryption on a packet (level 1 security) |
407 | */ |
408 | static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb, |
409 | rxrpc_seq_t seq, |
410 | struct skcipher_request *req) |
411 | { |
412 | struct rxkad_level1_hdr sechdr; |
413 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
414 | struct rxrpc_crypt iv; |
415 | struct scatterlist sg[16]; |
416 | u32 data_size, buf; |
417 | u16 check; |
418 | int ret; |
419 | |
420 | _enter("" ); |
421 | |
422 | if (sp->len < 8) |
423 | return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON, |
424 | why: rxkad_abort_1_short_header); |
425 | |
426 | /* Decrypt the skbuff in-place. TODO: We really want to decrypt |
427 | * directly into the target buffer. |
428 | */ |
429 | sg_init_table(sg, ARRAY_SIZE(sg)); |
430 | ret = skb_to_sgvec(skb, sg, offset: sp->offset, len: 8); |
431 | if (unlikely(ret < 0)) |
432 | return ret; |
433 | |
434 | /* start the decryption afresh */ |
435 | memset(&iv, 0, sizeof(iv)); |
436 | |
437 | skcipher_request_set_sync_tfm(req, tfm: call->conn->rxkad.cipher); |
438 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
439 | skcipher_request_set_crypt(req, src: sg, dst: sg, cryptlen: 8, iv: iv.x); |
440 | crypto_skcipher_decrypt(req); |
441 | skcipher_request_zero(req); |
442 | |
443 | /* Extract the decrypted packet length */ |
444 | if (skb_copy_bits(skb, offset: sp->offset, to: &sechdr, len: sizeof(sechdr)) < 0) |
445 | return rxrpc_abort_eproto(call, skb, RXKADDATALEN, |
446 | why: rxkad_abort_1_short_encdata); |
447 | sp->offset += sizeof(sechdr); |
448 | sp->len -= sizeof(sechdr); |
449 | |
450 | buf = ntohl(sechdr.data_size); |
451 | data_size = buf & 0xffff; |
452 | |
453 | check = buf >> 16; |
454 | check ^= seq ^ call->call_id; |
455 | check &= 0xffff; |
456 | if (check != 0) |
457 | return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON, |
458 | why: rxkad_abort_1_short_check); |
459 | if (data_size > sp->len) |
460 | return rxrpc_abort_eproto(call, skb, RXKADDATALEN, |
461 | why: rxkad_abort_1_short_data); |
462 | sp->len = data_size; |
463 | |
464 | _leave(" = 0 [dlen=%x]" , data_size); |
465 | return 0; |
466 | } |
467 | |
468 | /* |
469 | * wholly decrypt a packet (level 2 security) |
470 | */ |
471 | static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, |
472 | rxrpc_seq_t seq, |
473 | struct skcipher_request *req) |
474 | { |
475 | const struct rxrpc_key_token *token; |
476 | struct rxkad_level2_hdr sechdr; |
477 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
478 | struct rxrpc_crypt iv; |
479 | struct scatterlist _sg[4], *sg; |
480 | u32 data_size, buf; |
481 | u16 check; |
482 | int nsg, ret; |
483 | |
484 | _enter(",{%d}" , sp->len); |
485 | |
486 | if (sp->len < 8) |
487 | return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON, |
488 | why: rxkad_abort_2_short_header); |
489 | |
490 | /* Decrypt the skbuff in-place. TODO: We really want to decrypt |
491 | * directly into the target buffer. |
492 | */ |
493 | sg = _sg; |
494 | nsg = skb_shinfo(skb)->nr_frags + 1; |
495 | if (nsg <= 4) { |
496 | nsg = 4; |
497 | } else { |
498 | sg = kmalloc_array(n: nsg, size: sizeof(*sg), GFP_NOIO); |
499 | if (!sg) |
500 | return -ENOMEM; |
501 | } |
502 | |
503 | sg_init_table(sg, nsg); |
504 | ret = skb_to_sgvec(skb, sg, offset: sp->offset, len: sp->len); |
505 | if (unlikely(ret < 0)) { |
506 | if (sg != _sg) |
507 | kfree(objp: sg); |
508 | return ret; |
509 | } |
510 | |
511 | /* decrypt from the session key */ |
512 | token = call->conn->key->payload.data[0]; |
513 | memcpy(&iv, token->kad->session_key, sizeof(iv)); |
514 | |
515 | skcipher_request_set_sync_tfm(req, tfm: call->conn->rxkad.cipher); |
516 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
517 | skcipher_request_set_crypt(req, src: sg, dst: sg, cryptlen: sp->len, iv: iv.x); |
518 | crypto_skcipher_decrypt(req); |
519 | skcipher_request_zero(req); |
520 | if (sg != _sg) |
521 | kfree(objp: sg); |
522 | |
523 | /* Extract the decrypted packet length */ |
524 | if (skb_copy_bits(skb, offset: sp->offset, to: &sechdr, len: sizeof(sechdr)) < 0) |
525 | return rxrpc_abort_eproto(call, skb, RXKADDATALEN, |
526 | why: rxkad_abort_2_short_len); |
527 | sp->offset += sizeof(sechdr); |
528 | sp->len -= sizeof(sechdr); |
529 | |
530 | buf = ntohl(sechdr.data_size); |
531 | data_size = buf & 0xffff; |
532 | |
533 | check = buf >> 16; |
534 | check ^= seq ^ call->call_id; |
535 | check &= 0xffff; |
536 | if (check != 0) |
537 | return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON, |
538 | why: rxkad_abort_2_short_check); |
539 | |
540 | if (data_size > sp->len) |
541 | return rxrpc_abort_eproto(call, skb, RXKADDATALEN, |
542 | why: rxkad_abort_2_short_data); |
543 | |
544 | sp->len = data_size; |
545 | _leave(" = 0 [dlen=%x]" , data_size); |
546 | return 0; |
547 | } |
548 | |
549 | /* |
550 | * Verify the security on a received packet and the subpackets therein. |
551 | */ |
552 | static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb) |
553 | { |
554 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
555 | struct skcipher_request *req; |
556 | struct rxrpc_crypt iv; |
557 | struct scatterlist sg; |
558 | union { |
559 | __be32 buf[2]; |
560 | } crypto __aligned(8); |
561 | rxrpc_seq_t seq = sp->hdr.seq; |
562 | int ret; |
563 | u16 cksum; |
564 | u32 x, y; |
565 | |
566 | _enter("{%d{%x}},{#%u}" , |
567 | call->debug_id, key_serial(call->conn->key), seq); |
568 | |
569 | if (!call->conn->rxkad.cipher) |
570 | return 0; |
571 | |
572 | req = rxkad_get_call_crypto(call); |
573 | if (!req) |
574 | return -ENOMEM; |
575 | |
576 | /* continue encrypting from where we left off */ |
577 | memcpy(&iv, call->conn->rxkad.csum_iv.x, sizeof(iv)); |
578 | |
579 | /* validate the security checksum */ |
580 | x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT); |
581 | x |= seq & 0x3fffffff; |
582 | crypto.buf[0] = htonl(call->call_id); |
583 | crypto.buf[1] = htonl(x); |
584 | |
585 | sg_init_one(&sg, crypto.buf, 8); |
586 | skcipher_request_set_sync_tfm(req, tfm: call->conn->rxkad.cipher); |
587 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
588 | skcipher_request_set_crypt(req, src: &sg, dst: &sg, cryptlen: 8, iv: iv.x); |
589 | crypto_skcipher_encrypt(req); |
590 | skcipher_request_zero(req); |
591 | |
592 | y = ntohl(crypto.buf[1]); |
593 | cksum = (y >> 16) & 0xffff; |
594 | if (cksum == 0) |
595 | cksum = 1; /* zero checksums are not permitted */ |
596 | |
597 | if (cksum != sp->hdr.cksum) { |
598 | ret = rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON, |
599 | why: rxkad_abort_bad_checksum); |
600 | goto out; |
601 | } |
602 | |
603 | switch (call->conn->security_level) { |
604 | case RXRPC_SECURITY_PLAIN: |
605 | ret = 0; |
606 | break; |
607 | case RXRPC_SECURITY_AUTH: |
608 | ret = rxkad_verify_packet_1(call, skb, seq, req); |
609 | break; |
610 | case RXRPC_SECURITY_ENCRYPT: |
611 | ret = rxkad_verify_packet_2(call, skb, seq, req); |
612 | break; |
613 | default: |
614 | ret = -ENOANO; |
615 | break; |
616 | } |
617 | |
618 | out: |
619 | skcipher_request_free(req); |
620 | return ret; |
621 | } |
622 | |
623 | /* |
624 | * issue a challenge |
625 | */ |
626 | static int rxkad_issue_challenge(struct rxrpc_connection *conn) |
627 | { |
628 | struct rxkad_challenge challenge; |
629 | struct rxrpc_wire_header whdr; |
630 | struct msghdr msg; |
631 | struct kvec iov[2]; |
632 | size_t len; |
633 | u32 serial; |
634 | int ret; |
635 | |
636 | _enter("{%d}" , conn->debug_id); |
637 | |
638 | get_random_bytes(buf: &conn->rxkad.nonce, len: sizeof(conn->rxkad.nonce)); |
639 | |
640 | challenge.version = htonl(2); |
641 | challenge.nonce = htonl(conn->rxkad.nonce); |
642 | challenge.min_level = htonl(0); |
643 | challenge.__padding = 0; |
644 | |
645 | msg.msg_name = &conn->peer->srx.transport; |
646 | msg.msg_namelen = conn->peer->srx.transport_len; |
647 | msg.msg_control = NULL; |
648 | msg.msg_controllen = 0; |
649 | msg.msg_flags = 0; |
650 | |
651 | whdr.epoch = htonl(conn->proto.epoch); |
652 | whdr.cid = htonl(conn->proto.cid); |
653 | whdr.callNumber = 0; |
654 | whdr.seq = 0; |
655 | whdr.type = RXRPC_PACKET_TYPE_CHALLENGE; |
656 | whdr.flags = conn->out_clientflag; |
657 | whdr.userStatus = 0; |
658 | whdr.securityIndex = conn->security_ix; |
659 | whdr._rsvd = 0; |
660 | whdr.serviceId = htons(conn->service_id); |
661 | |
662 | iov[0].iov_base = &whdr; |
663 | iov[0].iov_len = sizeof(whdr); |
664 | iov[1].iov_base = &challenge; |
665 | iov[1].iov_len = sizeof(challenge); |
666 | |
667 | len = iov[0].iov_len + iov[1].iov_len; |
668 | |
669 | serial = rxrpc_get_next_serial(conn); |
670 | whdr.serial = htonl(serial); |
671 | |
672 | ret = kernel_sendmsg(sock: conn->local->socket, msg: &msg, vec: iov, num: 2, len); |
673 | if (ret < 0) { |
674 | trace_rxrpc_tx_fail(debug_id: conn->debug_id, serial, ret, |
675 | where: rxrpc_tx_point_rxkad_challenge); |
676 | return -EAGAIN; |
677 | } |
678 | |
679 | conn->peer->last_tx_at = ktime_get_seconds(); |
680 | trace_rxrpc_tx_packet(call_id: conn->debug_id, whdr: &whdr, |
681 | where: rxrpc_tx_point_rxkad_challenge); |
682 | _leave(" = 0" ); |
683 | return 0; |
684 | } |
685 | |
686 | /* |
687 | * send a Kerberos security response |
688 | */ |
689 | static int rxkad_send_response(struct rxrpc_connection *conn, |
690 | struct rxrpc_host_header *hdr, |
691 | struct rxkad_response *resp, |
692 | const struct rxkad_key *s2) |
693 | { |
694 | struct rxrpc_wire_header whdr; |
695 | struct msghdr msg; |
696 | struct kvec iov[3]; |
697 | size_t len; |
698 | u32 serial; |
699 | int ret; |
700 | |
701 | _enter("" ); |
702 | |
703 | msg.msg_name = &conn->peer->srx.transport; |
704 | msg.msg_namelen = conn->peer->srx.transport_len; |
705 | msg.msg_control = NULL; |
706 | msg.msg_controllen = 0; |
707 | msg.msg_flags = 0; |
708 | |
709 | memset(&whdr, 0, sizeof(whdr)); |
710 | whdr.epoch = htonl(hdr->epoch); |
711 | whdr.cid = htonl(hdr->cid); |
712 | whdr.type = RXRPC_PACKET_TYPE_RESPONSE; |
713 | whdr.flags = conn->out_clientflag; |
714 | whdr.securityIndex = hdr->securityIndex; |
715 | whdr.serviceId = htons(hdr->serviceId); |
716 | |
717 | iov[0].iov_base = &whdr; |
718 | iov[0].iov_len = sizeof(whdr); |
719 | iov[1].iov_base = resp; |
720 | iov[1].iov_len = sizeof(*resp); |
721 | iov[2].iov_base = (void *)s2->ticket; |
722 | iov[2].iov_len = s2->ticket_len; |
723 | |
724 | len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len; |
725 | |
726 | serial = rxrpc_get_next_serial(conn); |
727 | whdr.serial = htonl(serial); |
728 | |
729 | rxrpc_local_dont_fragment(local: conn->local, set: false); |
730 | ret = kernel_sendmsg(sock: conn->local->socket, msg: &msg, vec: iov, num: 3, len); |
731 | if (ret < 0) { |
732 | trace_rxrpc_tx_fail(debug_id: conn->debug_id, serial, ret, |
733 | where: rxrpc_tx_point_rxkad_response); |
734 | return -EAGAIN; |
735 | } |
736 | |
737 | conn->peer->last_tx_at = ktime_get_seconds(); |
738 | _leave(" = 0" ); |
739 | return 0; |
740 | } |
741 | |
742 | /* |
743 | * calculate the response checksum |
744 | */ |
745 | static void rxkad_calc_response_checksum(struct rxkad_response *response) |
746 | { |
747 | u32 csum = 1000003; |
748 | int loop; |
749 | u8 *p = (u8 *) response; |
750 | |
751 | for (loop = sizeof(*response); loop > 0; loop--) |
752 | csum = csum * 0x10204081 + *p++; |
753 | |
754 | response->encrypted.checksum = htonl(csum); |
755 | } |
756 | |
757 | /* |
758 | * encrypt the response packet |
759 | */ |
760 | static int rxkad_encrypt_response(struct rxrpc_connection *conn, |
761 | struct rxkad_response *resp, |
762 | const struct rxkad_key *s2) |
763 | { |
764 | struct skcipher_request *req; |
765 | struct rxrpc_crypt iv; |
766 | struct scatterlist sg[1]; |
767 | |
768 | req = skcipher_request_alloc(tfm: &conn->rxkad.cipher->base, GFP_NOFS); |
769 | if (!req) |
770 | return -ENOMEM; |
771 | |
772 | /* continue encrypting from where we left off */ |
773 | memcpy(&iv, s2->session_key, sizeof(iv)); |
774 | |
775 | sg_init_table(sg, 1); |
776 | sg_set_buf(sg, buf: &resp->encrypted, buflen: sizeof(resp->encrypted)); |
777 | skcipher_request_set_sync_tfm(req, tfm: conn->rxkad.cipher); |
778 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
779 | skcipher_request_set_crypt(req, src: sg, dst: sg, cryptlen: sizeof(resp->encrypted), iv: iv.x); |
780 | crypto_skcipher_encrypt(req); |
781 | skcipher_request_free(req); |
782 | return 0; |
783 | } |
784 | |
785 | /* |
786 | * respond to a challenge packet |
787 | */ |
788 | static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, |
789 | struct sk_buff *skb) |
790 | { |
791 | const struct rxrpc_key_token *token; |
792 | struct rxkad_challenge challenge; |
793 | struct rxkad_response *resp; |
794 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
795 | u32 version, nonce, min_level; |
796 | int ret = -EPROTO; |
797 | |
798 | _enter("{%d,%x}" , conn->debug_id, key_serial(conn->key)); |
799 | |
800 | if (!conn->key) |
801 | return rxrpc_abort_conn(conn, skb, RX_PROTOCOL_ERROR, err: -EPROTO, |
802 | why: rxkad_abort_chall_no_key); |
803 | |
804 | ret = key_validate(key: conn->key); |
805 | if (ret < 0) |
806 | return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, err: ret, |
807 | why: rxkad_abort_chall_key_expired); |
808 | |
809 | if (skb_copy_bits(skb, offset: sizeof(struct rxrpc_wire_header), |
810 | to: &challenge, len: sizeof(challenge)) < 0) |
811 | return rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, err: -EPROTO, |
812 | why: rxkad_abort_chall_short); |
813 | |
814 | version = ntohl(challenge.version); |
815 | nonce = ntohl(challenge.nonce); |
816 | min_level = ntohl(challenge.min_level); |
817 | |
818 | trace_rxrpc_rx_challenge(conn, serial: sp->hdr.serial, version, nonce, min_level); |
819 | |
820 | if (version != RXKAD_VERSION) |
821 | return rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, err: -EPROTO, |
822 | why: rxkad_abort_chall_version); |
823 | |
824 | if (conn->security_level < min_level) |
825 | return rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, err: -EACCES, |
826 | why: rxkad_abort_chall_level); |
827 | |
828 | token = conn->key->payload.data[0]; |
829 | |
830 | /* build the response packet */ |
831 | resp = kzalloc(size: sizeof(struct rxkad_response), GFP_NOFS); |
832 | if (!resp) |
833 | return -ENOMEM; |
834 | |
835 | resp->version = htonl(RXKAD_VERSION); |
836 | resp->encrypted.epoch = htonl(conn->proto.epoch); |
837 | resp->encrypted.cid = htonl(conn->proto.cid); |
838 | resp->encrypted.securityIndex = htonl(conn->security_ix); |
839 | resp->encrypted.inc_nonce = htonl(nonce + 1); |
840 | resp->encrypted.level = htonl(conn->security_level); |
841 | resp->kvno = htonl(token->kad->kvno); |
842 | resp->ticket_len = htonl(token->kad->ticket_len); |
843 | resp->encrypted.call_id[0] = htonl(conn->channels[0].call_counter); |
844 | resp->encrypted.call_id[1] = htonl(conn->channels[1].call_counter); |
845 | resp->encrypted.call_id[2] = htonl(conn->channels[2].call_counter); |
846 | resp->encrypted.call_id[3] = htonl(conn->channels[3].call_counter); |
847 | |
848 | /* calculate the response checksum and then do the encryption */ |
849 | rxkad_calc_response_checksum(response: resp); |
850 | ret = rxkad_encrypt_response(conn, resp, s2: token->kad); |
851 | if (ret == 0) |
852 | ret = rxkad_send_response(conn, hdr: &sp->hdr, resp, s2: token->kad); |
853 | kfree(objp: resp); |
854 | return ret; |
855 | } |
856 | |
857 | /* |
858 | * decrypt the kerberos IV ticket in the response |
859 | */ |
860 | static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, |
861 | struct key *server_key, |
862 | struct sk_buff *skb, |
863 | void *ticket, size_t ticket_len, |
864 | struct rxrpc_crypt *_session_key, |
865 | time64_t *_expiry) |
866 | { |
867 | struct skcipher_request *req; |
868 | struct rxrpc_crypt iv, key; |
869 | struct scatterlist sg[1]; |
870 | struct in_addr addr; |
871 | unsigned int life; |
872 | time64_t issue, now; |
873 | bool little_endian; |
874 | u8 *p, *q, *name, *end; |
875 | |
876 | _enter("{%d},{%x}" , conn->debug_id, key_serial(server_key)); |
877 | |
878 | *_expiry = 0; |
879 | |
880 | ASSERT(server_key->payload.data[0] != NULL); |
881 | ASSERTCMP((unsigned long) ticket & 7UL, ==, 0); |
882 | |
883 | memcpy(&iv, &server_key->payload.data[2], sizeof(iv)); |
884 | |
885 | req = skcipher_request_alloc(tfm: server_key->payload.data[0], GFP_NOFS); |
886 | if (!req) |
887 | return -ENOMEM; |
888 | |
889 | sg_init_one(&sg[0], ticket, ticket_len); |
890 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
891 | skcipher_request_set_crypt(req, src: sg, dst: sg, cryptlen: ticket_len, iv: iv.x); |
892 | crypto_skcipher_decrypt(req); |
893 | skcipher_request_free(req); |
894 | |
895 | p = ticket; |
896 | end = p + ticket_len; |
897 | |
898 | #define Z(field, fieldl) \ |
899 | ({ \ |
900 | u8 *__str = p; \ |
901 | q = memchr(p, 0, end - p); \ |
902 | if (!q || q - p > field##_SZ) \ |
903 | return rxrpc_abort_conn( \ |
904 | conn, skb, RXKADBADTICKET, -EPROTO, \ |
905 | rxkad_abort_resp_tkt_##fieldl); \ |
906 | for (; p < q; p++) \ |
907 | if (!isprint(*p)) \ |
908 | return rxrpc_abort_conn( \ |
909 | conn, skb, RXKADBADTICKET, -EPROTO, \ |
910 | rxkad_abort_resp_tkt_##fieldl); \ |
911 | p++; \ |
912 | __str; \ |
913 | }) |
914 | |
915 | /* extract the ticket flags */ |
916 | _debug("KIV FLAGS: %x" , *p); |
917 | little_endian = *p & 1; |
918 | p++; |
919 | |
920 | /* extract the authentication name */ |
921 | name = Z(ANAME, aname); |
922 | _debug("KIV ANAME: %s" , name); |
923 | |
924 | /* extract the principal's instance */ |
925 | name = Z(INST, inst); |
926 | _debug("KIV INST : %s" , name); |
927 | |
928 | /* extract the principal's authentication domain */ |
929 | name = Z(REALM, realm); |
930 | _debug("KIV REALM: %s" , name); |
931 | |
932 | if (end - p < 4 + 8 + 4 + 2) |
933 | return rxrpc_abort_conn(conn, skb, RXKADBADTICKET, err: -EPROTO, |
934 | why: rxkad_abort_resp_tkt_short); |
935 | |
936 | /* get the IPv4 address of the entity that requested the ticket */ |
937 | memcpy(&addr, p, sizeof(addr)); |
938 | p += 4; |
939 | _debug("KIV ADDR : %pI4" , &addr); |
940 | |
941 | /* get the session key from the ticket */ |
942 | memcpy(&key, p, sizeof(key)); |
943 | p += 8; |
944 | _debug("KIV KEY : %08x %08x" , ntohl(key.n[0]), ntohl(key.n[1])); |
945 | memcpy(_session_key, &key, sizeof(key)); |
946 | |
947 | /* get the ticket's lifetime */ |
948 | life = *p++ * 5 * 60; |
949 | _debug("KIV LIFE : %u" , life); |
950 | |
951 | /* get the issue time of the ticket */ |
952 | if (little_endian) { |
953 | __le32 stamp; |
954 | memcpy(&stamp, p, 4); |
955 | issue = rxrpc_u32_to_time64(le32_to_cpu(stamp)); |
956 | } else { |
957 | __be32 stamp; |
958 | memcpy(&stamp, p, 4); |
959 | issue = rxrpc_u32_to_time64(be32_to_cpu(stamp)); |
960 | } |
961 | p += 4; |
962 | now = ktime_get_real_seconds(); |
963 | _debug("KIV ISSUE: %llx [%llx]" , issue, now); |
964 | |
965 | /* check the ticket is in date */ |
966 | if (issue > now) |
967 | return rxrpc_abort_conn(conn, skb, RXKADNOAUTH, err: -EKEYREJECTED, |
968 | why: rxkad_abort_resp_tkt_future); |
969 | if (issue < now - life) |
970 | return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, err: -EKEYEXPIRED, |
971 | why: rxkad_abort_resp_tkt_expired); |
972 | |
973 | *_expiry = issue + life; |
974 | |
975 | /* get the service name */ |
976 | name = Z(SNAME, sname); |
977 | _debug("KIV SNAME: %s" , name); |
978 | |
979 | /* get the service instance name */ |
980 | name = Z(INST, sinst); |
981 | _debug("KIV SINST: %s" , name); |
982 | return 0; |
983 | } |
984 | |
985 | /* |
986 | * decrypt the response packet |
987 | */ |
988 | static void rxkad_decrypt_response(struct rxrpc_connection *conn, |
989 | struct rxkad_response *resp, |
990 | const struct rxrpc_crypt *session_key) |
991 | { |
992 | struct skcipher_request *req = rxkad_ci_req; |
993 | struct scatterlist sg[1]; |
994 | struct rxrpc_crypt iv; |
995 | |
996 | _enter(",,%08x%08x" , |
997 | ntohl(session_key->n[0]), ntohl(session_key->n[1])); |
998 | |
999 | mutex_lock(&rxkad_ci_mutex); |
1000 | if (crypto_sync_skcipher_setkey(tfm: rxkad_ci, key: session_key->x, |
1001 | keylen: sizeof(*session_key)) < 0) |
1002 | BUG(); |
1003 | |
1004 | memcpy(&iv, session_key, sizeof(iv)); |
1005 | |
1006 | sg_init_table(sg, 1); |
1007 | sg_set_buf(sg, buf: &resp->encrypted, buflen: sizeof(resp->encrypted)); |
1008 | skcipher_request_set_sync_tfm(req, tfm: rxkad_ci); |
1009 | skcipher_request_set_callback(req, flags: 0, NULL, NULL); |
1010 | skcipher_request_set_crypt(req, src: sg, dst: sg, cryptlen: sizeof(resp->encrypted), iv: iv.x); |
1011 | crypto_skcipher_decrypt(req); |
1012 | skcipher_request_zero(req); |
1013 | |
1014 | mutex_unlock(lock: &rxkad_ci_mutex); |
1015 | |
1016 | _leave("" ); |
1017 | } |
1018 | |
1019 | /* |
1020 | * verify a response |
1021 | */ |
1022 | static int rxkad_verify_response(struct rxrpc_connection *conn, |
1023 | struct sk_buff *skb) |
1024 | { |
1025 | struct rxkad_response *response; |
1026 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
1027 | struct rxrpc_crypt session_key; |
1028 | struct key *server_key; |
1029 | time64_t expiry; |
1030 | void *ticket; |
1031 | u32 version, kvno, ticket_len, level; |
1032 | __be32 csum; |
1033 | int ret, i; |
1034 | |
1035 | _enter("{%d}" , conn->debug_id); |
1036 | |
1037 | server_key = rxrpc_look_up_server_security(conn, skb, 0, 0); |
1038 | if (IS_ERR(ptr: server_key)) { |
1039 | ret = PTR_ERR(ptr: server_key); |
1040 | switch (ret) { |
1041 | case -ENOKEY: |
1042 | return rxrpc_abort_conn(conn, skb, RXKADUNKNOWNKEY, err: ret, |
1043 | why: rxkad_abort_resp_nokey); |
1044 | case -EKEYEXPIRED: |
1045 | return rxrpc_abort_conn(conn, skb, RXKADEXPIRED, err: ret, |
1046 | why: rxkad_abort_resp_key_expired); |
1047 | default: |
1048 | return rxrpc_abort_conn(conn, skb, RXKADNOAUTH, err: ret, |
1049 | why: rxkad_abort_resp_key_rejected); |
1050 | } |
1051 | } |
1052 | |
1053 | ret = -ENOMEM; |
1054 | response = kzalloc(size: sizeof(struct rxkad_response), GFP_NOFS); |
1055 | if (!response) |
1056 | goto temporary_error; |
1057 | |
1058 | if (skb_copy_bits(skb, offset: sizeof(struct rxrpc_wire_header), |
1059 | to: response, len: sizeof(*response)) < 0) { |
1060 | rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, err: -EPROTO, |
1061 | why: rxkad_abort_resp_short); |
1062 | goto protocol_error; |
1063 | } |
1064 | |
1065 | version = ntohl(response->version); |
1066 | ticket_len = ntohl(response->ticket_len); |
1067 | kvno = ntohl(response->kvno); |
1068 | |
1069 | trace_rxrpc_rx_response(conn, serial: sp->hdr.serial, version, kvno, ticket_len); |
1070 | |
1071 | if (version != RXKAD_VERSION) { |
1072 | rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, err: -EPROTO, |
1073 | why: rxkad_abort_resp_version); |
1074 | goto protocol_error; |
1075 | } |
1076 | |
1077 | if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN) { |
1078 | rxrpc_abort_conn(conn, skb, RXKADTICKETLEN, err: -EPROTO, |
1079 | why: rxkad_abort_resp_tkt_len); |
1080 | goto protocol_error; |
1081 | } |
1082 | |
1083 | if (kvno >= RXKAD_TKT_TYPE_KERBEROS_V5) { |
1084 | rxrpc_abort_conn(conn, skb, RXKADUNKNOWNKEY, err: -EPROTO, |
1085 | why: rxkad_abort_resp_unknown_tkt); |
1086 | goto protocol_error; |
1087 | } |
1088 | |
1089 | /* extract the kerberos ticket and decrypt and decode it */ |
1090 | ret = -ENOMEM; |
1091 | ticket = kmalloc(size: ticket_len, GFP_NOFS); |
1092 | if (!ticket) |
1093 | goto temporary_error_free_resp; |
1094 | |
1095 | if (skb_copy_bits(skb, offset: sizeof(struct rxrpc_wire_header) + sizeof(*response), |
1096 | to: ticket, len: ticket_len) < 0) { |
1097 | rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, err: -EPROTO, |
1098 | why: rxkad_abort_resp_short_tkt); |
1099 | goto protocol_error; |
1100 | } |
1101 | |
1102 | ret = rxkad_decrypt_ticket(conn, server_key, skb, ticket, ticket_len, |
1103 | session_key: &session_key, expiry: &expiry); |
1104 | if (ret < 0) |
1105 | goto temporary_error_free_ticket; |
1106 | |
1107 | /* use the session key from inside the ticket to decrypt the |
1108 | * response */ |
1109 | rxkad_decrypt_response(conn, resp: response, session_key: &session_key); |
1110 | |
1111 | if (ntohl(response->encrypted.epoch) != conn->proto.epoch || |
1112 | ntohl(response->encrypted.cid) != conn->proto.cid || |
1113 | ntohl(response->encrypted.securityIndex) != conn->security_ix) { |
1114 | rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, err: -EPROTO, |
1115 | why: rxkad_abort_resp_bad_param); |
1116 | goto protocol_error_free; |
1117 | } |
1118 | |
1119 | csum = response->encrypted.checksum; |
1120 | response->encrypted.checksum = 0; |
1121 | rxkad_calc_response_checksum(response); |
1122 | if (response->encrypted.checksum != csum) { |
1123 | rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, err: -EPROTO, |
1124 | why: rxkad_abort_resp_bad_checksum); |
1125 | goto protocol_error_free; |
1126 | } |
1127 | |
1128 | for (i = 0; i < RXRPC_MAXCALLS; i++) { |
1129 | u32 call_id = ntohl(response->encrypted.call_id[i]); |
1130 | u32 counter = READ_ONCE(conn->channels[i].call_counter); |
1131 | |
1132 | if (call_id > INT_MAX) { |
1133 | rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, err: -EPROTO, |
1134 | why: rxkad_abort_resp_bad_callid); |
1135 | goto protocol_error_free; |
1136 | } |
1137 | |
1138 | if (call_id < counter) { |
1139 | rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, err: -EPROTO, |
1140 | why: rxkad_abort_resp_call_ctr); |
1141 | goto protocol_error_free; |
1142 | } |
1143 | |
1144 | if (call_id > counter) { |
1145 | if (conn->channels[i].call) { |
1146 | rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, err: -EPROTO, |
1147 | why: rxkad_abort_resp_call_state); |
1148 | goto protocol_error_free; |
1149 | } |
1150 | conn->channels[i].call_counter = call_id; |
1151 | } |
1152 | } |
1153 | |
1154 | if (ntohl(response->encrypted.inc_nonce) != conn->rxkad.nonce + 1) { |
1155 | rxrpc_abort_conn(conn, skb, RXKADOUTOFSEQUENCE, err: -EPROTO, |
1156 | why: rxkad_abort_resp_ooseq); |
1157 | goto protocol_error_free; |
1158 | } |
1159 | |
1160 | level = ntohl(response->encrypted.level); |
1161 | if (level > RXRPC_SECURITY_ENCRYPT) { |
1162 | rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, err: -EPROTO, |
1163 | why: rxkad_abort_resp_level); |
1164 | goto protocol_error_free; |
1165 | } |
1166 | conn->security_level = level; |
1167 | |
1168 | /* create a key to hold the security data and expiration time - after |
1169 | * this the connection security can be handled in exactly the same way |
1170 | * as for a client connection */ |
1171 | ret = rxrpc_get_server_data_key(conn, &session_key, expiry, kvno); |
1172 | if (ret < 0) |
1173 | goto temporary_error_free_ticket; |
1174 | |
1175 | kfree(objp: ticket); |
1176 | kfree(objp: response); |
1177 | _leave(" = 0" ); |
1178 | return 0; |
1179 | |
1180 | protocol_error_free: |
1181 | kfree(objp: ticket); |
1182 | protocol_error: |
1183 | kfree(objp: response); |
1184 | key_put(key: server_key); |
1185 | return -EPROTO; |
1186 | |
1187 | temporary_error_free_ticket: |
1188 | kfree(objp: ticket); |
1189 | temporary_error_free_resp: |
1190 | kfree(objp: response); |
1191 | temporary_error: |
1192 | /* Ignore the response packet if we got a temporary error such as |
1193 | * ENOMEM. We just want to send the challenge again. Note that we |
1194 | * also come out this way if the ticket decryption fails. |
1195 | */ |
1196 | key_put(key: server_key); |
1197 | return ret; |
1198 | } |
1199 | |
1200 | /* |
1201 | * clear the connection security |
1202 | */ |
1203 | static void rxkad_clear(struct rxrpc_connection *conn) |
1204 | { |
1205 | _enter("" ); |
1206 | |
1207 | if (conn->rxkad.cipher) |
1208 | crypto_free_sync_skcipher(tfm: conn->rxkad.cipher); |
1209 | } |
1210 | |
1211 | /* |
1212 | * Initialise the rxkad security service. |
1213 | */ |
1214 | static int rxkad_init(void) |
1215 | { |
1216 | struct crypto_sync_skcipher *tfm; |
1217 | struct skcipher_request *req; |
1218 | |
1219 | /* pin the cipher we need so that the crypto layer doesn't invoke |
1220 | * keventd to go get it */ |
1221 | tfm = crypto_alloc_sync_skcipher(alg_name: "pcbc(fcrypt)" , type: 0, mask: 0); |
1222 | if (IS_ERR(ptr: tfm)) |
1223 | return PTR_ERR(ptr: tfm); |
1224 | |
1225 | req = skcipher_request_alloc(tfm: &tfm->base, GFP_KERNEL); |
1226 | if (!req) |
1227 | goto nomem_tfm; |
1228 | |
1229 | rxkad_ci_req = req; |
1230 | rxkad_ci = tfm; |
1231 | return 0; |
1232 | |
1233 | nomem_tfm: |
1234 | crypto_free_sync_skcipher(tfm); |
1235 | return -ENOMEM; |
1236 | } |
1237 | |
1238 | /* |
1239 | * Clean up the rxkad security service. |
1240 | */ |
1241 | static void rxkad_exit(void) |
1242 | { |
1243 | crypto_free_sync_skcipher(tfm: rxkad_ci); |
1244 | skcipher_request_free(req: rxkad_ci_req); |
1245 | } |
1246 | |
1247 | /* |
1248 | * RxRPC Kerberos-based security |
1249 | */ |
1250 | const struct rxrpc_security rxkad = { |
1251 | .name = "rxkad" , |
1252 | .security_index = RXRPC_SECURITY_RXKAD, |
1253 | .no_key_abort = RXKADUNKNOWNKEY, |
1254 | .init = rxkad_init, |
1255 | .exit = rxkad_exit, |
1256 | .preparse_server_key = rxkad_preparse_server_key, |
1257 | .free_preparse_server_key = rxkad_free_preparse_server_key, |
1258 | .destroy_server_key = rxkad_destroy_server_key, |
1259 | .init_connection_security = rxkad_init_connection_security, |
1260 | .alloc_txbuf = rxkad_alloc_txbuf, |
1261 | .secure_packet = rxkad_secure_packet, |
1262 | .verify_packet = rxkad_verify_packet, |
1263 | .free_call_crypto = rxkad_free_call_crypto, |
1264 | .issue_challenge = rxkad_issue_challenge, |
1265 | .respond_to_challenge = rxkad_respond_to_challenge, |
1266 | .verify_response = rxkad_verify_response, |
1267 | .clear = rxkad_clear, |
1268 | }; |
1269 | |