Root/
1 | /* Kerberos-based RxRPC security |
2 | * |
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) |
5 | * |
6 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/net.h> |
14 | #include <linux/skbuff.h> |
15 | #include <linux/udp.h> |
16 | #include <linux/crypto.h> |
17 | #include <linux/scatterlist.h> |
18 | #include <linux/ctype.h> |
19 | #include <net/sock.h> |
20 | #include <net/af_rxrpc.h> |
21 | #include <keys/rxrpc-type.h> |
22 | #define rxrpc_debug rxkad_debug |
23 | #include "ar-internal.h" |
24 | |
25 | #define RXKAD_VERSION 2 |
26 | #define MAXKRB5TICKETLEN 1024 |
27 | #define RXKAD_TKT_TYPE_KERBEROS_V5 256 |
28 | #define ANAME_SZ 40 /* size of authentication name */ |
29 | #define INST_SZ 40 /* size of principal's instance */ |
30 | #define REALM_SZ 40 /* size of principal's auth domain */ |
31 | #define SNAME_SZ 40 /* size of service name */ |
32 | |
33 | unsigned rxrpc_debug; |
34 | module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO); |
35 | MODULE_PARM_DESC(debug, "rxkad debugging mask"); |
36 | |
37 | struct rxkad_level1_hdr { |
38 | __be32 data_size; /* true data size (excluding padding) */ |
39 | }; |
40 | |
41 | struct rxkad_level2_hdr { |
42 | __be32 data_size; /* true data size (excluding padding) */ |
43 | __be32 checksum; /* decrypted data checksum */ |
44 | }; |
45 | |
46 | MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)"); |
47 | MODULE_AUTHOR("Red Hat, Inc."); |
48 | MODULE_LICENSE("GPL"); |
49 | |
50 | /* |
51 | * this holds a pinned cipher so that keventd doesn't get called by the cipher |
52 | * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE |
53 | * packets |
54 | */ |
55 | static struct crypto_blkcipher *rxkad_ci; |
56 | static DEFINE_MUTEX(rxkad_ci_mutex); |
57 | |
58 | /* |
59 | * initialise connection security |
60 | */ |
61 | static int rxkad_init_connection_security(struct rxrpc_connection *conn) |
62 | { |
63 | struct crypto_blkcipher *ci; |
64 | struct rxrpc_key_token *token; |
65 | int ret; |
66 | |
67 | _enter("{%d},{%x}", conn->debug_id, key_serial(conn->key)); |
68 | |
69 | token = conn->key->payload.data; |
70 | conn->security_ix = token->security_index; |
71 | |
72 | ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); |
73 | if (IS_ERR(ci)) { |
74 | _debug("no cipher"); |
75 | ret = PTR_ERR(ci); |
76 | goto error; |
77 | } |
78 | |
79 | if (crypto_blkcipher_setkey(ci, token->kad->session_key, |
80 | sizeof(token->kad->session_key)) < 0) |
81 | BUG(); |
82 | |
83 | switch (conn->security_level) { |
84 | case RXRPC_SECURITY_PLAIN: |
85 | break; |
86 | case RXRPC_SECURITY_AUTH: |
87 | conn->size_align = 8; |
88 | conn->security_size = sizeof(struct rxkad_level1_hdr); |
89 | conn->header_size += sizeof(struct rxkad_level1_hdr); |
90 | break; |
91 | case RXRPC_SECURITY_ENCRYPT: |
92 | conn->size_align = 8; |
93 | conn->security_size = sizeof(struct rxkad_level2_hdr); |
94 | conn->header_size += sizeof(struct rxkad_level2_hdr); |
95 | break; |
96 | default: |
97 | ret = -EKEYREJECTED; |
98 | goto error; |
99 | } |
100 | |
101 | conn->cipher = ci; |
102 | ret = 0; |
103 | error: |
104 | _leave(" = %d", ret); |
105 | return ret; |
106 | } |
107 | |
108 | /* |
109 | * prime the encryption state with the invariant parts of a connection's |
110 | * description |
111 | */ |
112 | static void rxkad_prime_packet_security(struct rxrpc_connection *conn) |
113 | { |
114 | struct rxrpc_key_token *token; |
115 | struct blkcipher_desc desc; |
116 | struct scatterlist sg[2]; |
117 | struct rxrpc_crypt iv; |
118 | struct { |
119 | __be32 x[4]; |
120 | } tmpbuf __attribute__((aligned(16))); /* must all be in same page */ |
121 | |
122 | _enter(""); |
123 | |
124 | if (!conn->key) |
125 | return; |
126 | |
127 | token = conn->key->payload.data; |
128 | memcpy(&iv, token->kad->session_key, sizeof(iv)); |
129 | |
130 | desc.tfm = conn->cipher; |
131 | desc.info = iv.x; |
132 | desc.flags = 0; |
133 | |
134 | tmpbuf.x[0] = conn->epoch; |
135 | tmpbuf.x[1] = conn->cid; |
136 | tmpbuf.x[2] = 0; |
137 | tmpbuf.x[3] = htonl(conn->security_ix); |
138 | |
139 | sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); |
140 | sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); |
141 | crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); |
142 | |
143 | memcpy(&conn->csum_iv, &tmpbuf.x[2], sizeof(conn->csum_iv)); |
144 | ASSERTCMP(conn->csum_iv.n[0], ==, tmpbuf.x[2]); |
145 | |
146 | _leave(""); |
147 | } |
148 | |
149 | /* |
150 | * partially encrypt a packet (level 1 security) |
151 | */ |
152 | static int rxkad_secure_packet_auth(const struct rxrpc_call *call, |
153 | struct sk_buff *skb, |
154 | u32 data_size, |
155 | void *sechdr) |
156 | { |
157 | struct rxrpc_skb_priv *sp; |
158 | struct blkcipher_desc desc; |
159 | struct rxrpc_crypt iv; |
160 | struct scatterlist sg[2]; |
161 | struct { |
162 | struct rxkad_level1_hdr hdr; |
163 | __be32 first; /* first four bytes of data and padding */ |
164 | } tmpbuf __attribute__((aligned(8))); /* must all be in same page */ |
165 | u16 check; |
166 | |
167 | sp = rxrpc_skb(skb); |
168 | |
169 | _enter(""); |
170 | |
171 | check = ntohl(sp->hdr.seq ^ sp->hdr.callNumber); |
172 | data_size |= (u32) check << 16; |
173 | |
174 | tmpbuf.hdr.data_size = htonl(data_size); |
175 | memcpy(&tmpbuf.first, sechdr + 4, sizeof(tmpbuf.first)); |
176 | |
177 | /* start the encryption afresh */ |
178 | memset(&iv, 0, sizeof(iv)); |
179 | desc.tfm = call->conn->cipher; |
180 | desc.info = iv.x; |
181 | desc.flags = 0; |
182 | |
183 | sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); |
184 | sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); |
185 | crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); |
186 | |
187 | memcpy(sechdr, &tmpbuf, sizeof(tmpbuf)); |
188 | |
189 | _leave(" = 0"); |
190 | return 0; |
191 | } |
192 | |
193 | /* |
194 | * wholly encrypt a packet (level 2 security) |
195 | */ |
196 | static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, |
197 | struct sk_buff *skb, |
198 | u32 data_size, |
199 | void *sechdr) |
200 | { |
201 | const struct rxrpc_key_token *token; |
202 | struct rxkad_level2_hdr rxkhdr |
203 | __attribute__((aligned(8))); /* must be all on one page */ |
204 | struct rxrpc_skb_priv *sp; |
205 | struct blkcipher_desc desc; |
206 | struct rxrpc_crypt iv; |
207 | struct scatterlist sg[16]; |
208 | struct sk_buff *trailer; |
209 | unsigned len; |
210 | u16 check; |
211 | int nsg; |
212 | |
213 | sp = rxrpc_skb(skb); |
214 | |
215 | _enter(""); |
216 | |
217 | check = ntohl(sp->hdr.seq ^ sp->hdr.callNumber); |
218 | |
219 | rxkhdr.data_size = htonl(data_size | (u32) check << 16); |
220 | rxkhdr.checksum = 0; |
221 | |
222 | /* encrypt from the session key */ |
223 | token = call->conn->key->payload.data; |
224 | memcpy(&iv, token->kad->session_key, sizeof(iv)); |
225 | desc.tfm = call->conn->cipher; |
226 | desc.info = iv.x; |
227 | desc.flags = 0; |
228 | |
229 | sg_init_one(&sg[0], sechdr, sizeof(rxkhdr)); |
230 | sg_init_one(&sg[1], &rxkhdr, sizeof(rxkhdr)); |
231 | crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(rxkhdr)); |
232 | |
233 | /* we want to encrypt the skbuff in-place */ |
234 | nsg = skb_cow_data(skb, 0, &trailer); |
235 | if (nsg < 0 || nsg > 16) |
236 | return -ENOMEM; |
237 | |
238 | len = data_size + call->conn->size_align - 1; |
239 | len &= ~(call->conn->size_align - 1); |
240 | |
241 | sg_init_table(sg, nsg); |
242 | skb_to_sgvec(skb, sg, 0, len); |
243 | crypto_blkcipher_encrypt_iv(&desc, sg, sg, len); |
244 | |
245 | _leave(" = 0"); |
246 | return 0; |
247 | } |
248 | |
249 | /* |
250 | * checksum an RxRPC packet header |
251 | */ |
252 | static int rxkad_secure_packet(const struct rxrpc_call *call, |
253 | struct sk_buff *skb, |
254 | size_t data_size, |
255 | void *sechdr) |
256 | { |
257 | struct rxrpc_skb_priv *sp; |
258 | struct blkcipher_desc desc; |
259 | struct rxrpc_crypt iv; |
260 | struct scatterlist sg[2]; |
261 | struct { |
262 | __be32 x[2]; |
263 | } tmpbuf __attribute__((aligned(8))); /* must all be in same page */ |
264 | __be32 x; |
265 | u32 y; |
266 | int ret; |
267 | |
268 | sp = rxrpc_skb(skb); |
269 | |
270 | _enter("{%d{%x}},{#%u},%zu,", |
271 | call->debug_id, key_serial(call->conn->key), ntohl(sp->hdr.seq), |
272 | data_size); |
273 | |
274 | if (!call->conn->cipher) |
275 | return 0; |
276 | |
277 | ret = key_validate(call->conn->key); |
278 | if (ret < 0) |
279 | return ret; |
280 | |
281 | /* continue encrypting from where we left off */ |
282 | memcpy(&iv, call->conn->csum_iv.x, sizeof(iv)); |
283 | desc.tfm = call->conn->cipher; |
284 | desc.info = iv.x; |
285 | desc.flags = 0; |
286 | |
287 | /* calculate the security checksum */ |
288 | x = htonl(call->channel << (32 - RXRPC_CIDSHIFT)); |
289 | x |= sp->hdr.seq & cpu_to_be32(0x3fffffff); |
290 | tmpbuf.x[0] = sp->hdr.callNumber; |
291 | tmpbuf.x[1] = x; |
292 | |
293 | sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); |
294 | sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); |
295 | crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); |
296 | |
297 | y = ntohl(tmpbuf.x[1]); |
298 | y = (y >> 16) & 0xffff; |
299 | if (y == 0) |
300 | y = 1; /* zero checksums are not permitted */ |
301 | sp->hdr.cksum = htons(y); |
302 | |
303 | switch (call->conn->security_level) { |
304 | case RXRPC_SECURITY_PLAIN: |
305 | ret = 0; |
306 | break; |
307 | case RXRPC_SECURITY_AUTH: |
308 | ret = rxkad_secure_packet_auth(call, skb, data_size, sechdr); |
309 | break; |
310 | case RXRPC_SECURITY_ENCRYPT: |
311 | ret = rxkad_secure_packet_encrypt(call, skb, data_size, |
312 | sechdr); |
313 | break; |
314 | default: |
315 | ret = -EPERM; |
316 | break; |
317 | } |
318 | |
319 | _leave(" = %d [set %hx]", ret, y); |
320 | return ret; |
321 | } |
322 | |
323 | /* |
324 | * decrypt partial encryption on a packet (level 1 security) |
325 | */ |
326 | static int rxkad_verify_packet_auth(const struct rxrpc_call *call, |
327 | struct sk_buff *skb, |
328 | u32 *_abort_code) |
329 | { |
330 | struct rxkad_level1_hdr sechdr; |
331 | struct rxrpc_skb_priv *sp; |
332 | struct blkcipher_desc desc; |
333 | struct rxrpc_crypt iv; |
334 | struct scatterlist sg[16]; |
335 | struct sk_buff *trailer; |
336 | u32 data_size, buf; |
337 | u16 check; |
338 | int nsg; |
339 | |
340 | _enter(""); |
341 | |
342 | sp = rxrpc_skb(skb); |
343 | |
344 | /* we want to decrypt the skbuff in-place */ |
345 | nsg = skb_cow_data(skb, 0, &trailer); |
346 | if (nsg < 0 || nsg > 16) |
347 | goto nomem; |
348 | |
349 | sg_init_table(sg, nsg); |
350 | skb_to_sgvec(skb, sg, 0, 8); |
351 | |
352 | /* start the decryption afresh */ |
353 | memset(&iv, 0, sizeof(iv)); |
354 | desc.tfm = call->conn->cipher; |
355 | desc.info = iv.x; |
356 | desc.flags = 0; |
357 | |
358 | crypto_blkcipher_decrypt_iv(&desc, sg, sg, 8); |
359 | |
360 | /* remove the decrypted packet length */ |
361 | if (skb_copy_bits(skb, 0, &sechdr, sizeof(sechdr)) < 0) |
362 | goto datalen_error; |
363 | if (!skb_pull(skb, sizeof(sechdr))) |
364 | BUG(); |
365 | |
366 | buf = ntohl(sechdr.data_size); |
367 | data_size = buf & 0xffff; |
368 | |
369 | check = buf >> 16; |
370 | check ^= ntohl(sp->hdr.seq ^ sp->hdr.callNumber); |
371 | check &= 0xffff; |
372 | if (check != 0) { |
373 | *_abort_code = RXKADSEALEDINCON; |
374 | goto protocol_error; |
375 | } |
376 | |
377 | /* shorten the packet to remove the padding */ |
378 | if (data_size > skb->len) |
379 | goto datalen_error; |
380 | else if (data_size < skb->len) |
381 | skb->len = data_size; |
382 | |
383 | _leave(" = 0 [dlen=%x]", data_size); |
384 | return 0; |
385 | |
386 | datalen_error: |
387 | *_abort_code = RXKADDATALEN; |
388 | protocol_error: |
389 | _leave(" = -EPROTO"); |
390 | return -EPROTO; |
391 | |
392 | nomem: |
393 | _leave(" = -ENOMEM"); |
394 | return -ENOMEM; |
395 | } |
396 | |
397 | /* |
398 | * wholly decrypt a packet (level 2 security) |
399 | */ |
400 | static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call, |
401 | struct sk_buff *skb, |
402 | u32 *_abort_code) |
403 | { |
404 | const struct rxrpc_key_token *token; |
405 | struct rxkad_level2_hdr sechdr; |
406 | struct rxrpc_skb_priv *sp; |
407 | struct blkcipher_desc desc; |
408 | struct rxrpc_crypt iv; |
409 | struct scatterlist _sg[4], *sg; |
410 | struct sk_buff *trailer; |
411 | u32 data_size, buf; |
412 | u16 check; |
413 | int nsg; |
414 | |
415 | _enter(",{%d}", skb->len); |
416 | |
417 | sp = rxrpc_skb(skb); |
418 | |
419 | /* we want to decrypt the skbuff in-place */ |
420 | nsg = skb_cow_data(skb, 0, &trailer); |
421 | if (nsg < 0) |
422 | goto nomem; |
423 | |
424 | sg = _sg; |
425 | if (unlikely(nsg > 4)) { |
426 | sg = kmalloc(sizeof(*sg) * nsg, GFP_NOIO); |
427 | if (!sg) |
428 | goto nomem; |
429 | } |
430 | |
431 | sg_init_table(sg, nsg); |
432 | skb_to_sgvec(skb, sg, 0, skb->len); |
433 | |
434 | /* decrypt from the session key */ |
435 | token = call->conn->key->payload.data; |
436 | memcpy(&iv, token->kad->session_key, sizeof(iv)); |
437 | desc.tfm = call->conn->cipher; |
438 | desc.info = iv.x; |
439 | desc.flags = 0; |
440 | |
441 | crypto_blkcipher_decrypt_iv(&desc, sg, sg, skb->len); |
442 | if (sg != _sg) |
443 | kfree(sg); |
444 | |
445 | /* remove the decrypted packet length */ |
446 | if (skb_copy_bits(skb, 0, &sechdr, sizeof(sechdr)) < 0) |
447 | goto datalen_error; |
448 | if (!skb_pull(skb, sizeof(sechdr))) |
449 | BUG(); |
450 | |
451 | buf = ntohl(sechdr.data_size); |
452 | data_size = buf & 0xffff; |
453 | |
454 | check = buf >> 16; |
455 | check ^= ntohl(sp->hdr.seq ^ sp->hdr.callNumber); |
456 | check &= 0xffff; |
457 | if (check != 0) { |
458 | *_abort_code = RXKADSEALEDINCON; |
459 | goto protocol_error; |
460 | } |
461 | |
462 | /* shorten the packet to remove the padding */ |
463 | if (data_size > skb->len) |
464 | goto datalen_error; |
465 | else if (data_size < skb->len) |
466 | skb->len = data_size; |
467 | |
468 | _leave(" = 0 [dlen=%x]", data_size); |
469 | return 0; |
470 | |
471 | datalen_error: |
472 | *_abort_code = RXKADDATALEN; |
473 | protocol_error: |
474 | _leave(" = -EPROTO"); |
475 | return -EPROTO; |
476 | |
477 | nomem: |
478 | _leave(" = -ENOMEM"); |
479 | return -ENOMEM; |
480 | } |
481 | |
482 | /* |
483 | * verify the security on a received packet |
484 | */ |
485 | static int rxkad_verify_packet(const struct rxrpc_call *call, |
486 | struct sk_buff *skb, |
487 | u32 *_abort_code) |
488 | { |
489 | struct blkcipher_desc desc; |
490 | struct rxrpc_skb_priv *sp; |
491 | struct rxrpc_crypt iv; |
492 | struct scatterlist sg[2]; |
493 | struct { |
494 | __be32 x[2]; |
495 | } tmpbuf __attribute__((aligned(8))); /* must all be in same page */ |
496 | __be32 x; |
497 | __be16 cksum; |
498 | u32 y; |
499 | int ret; |
500 | |
501 | sp = rxrpc_skb(skb); |
502 | |
503 | _enter("{%d{%x}},{#%u}", |
504 | call->debug_id, key_serial(call->conn->key), |
505 | ntohl(sp->hdr.seq)); |
506 | |
507 | if (!call->conn->cipher) |
508 | return 0; |
509 | |
510 | if (sp->hdr.securityIndex != RXRPC_SECURITY_RXKAD) { |
511 | *_abort_code = RXKADINCONSISTENCY; |
512 | _leave(" = -EPROTO [not rxkad]"); |
513 | return -EPROTO; |
514 | } |
515 | |
516 | /* continue encrypting from where we left off */ |
517 | memcpy(&iv, call->conn->csum_iv.x, sizeof(iv)); |
518 | desc.tfm = call->conn->cipher; |
519 | desc.info = iv.x; |
520 | desc.flags = 0; |
521 | |
522 | /* validate the security checksum */ |
523 | x = htonl(call->channel << (32 - RXRPC_CIDSHIFT)); |
524 | x |= sp->hdr.seq & cpu_to_be32(0x3fffffff); |
525 | tmpbuf.x[0] = call->call_id; |
526 | tmpbuf.x[1] = x; |
527 | |
528 | sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); |
529 | sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); |
530 | crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); |
531 | |
532 | y = ntohl(tmpbuf.x[1]); |
533 | y = (y >> 16) & 0xffff; |
534 | if (y == 0) |
535 | y = 1; /* zero checksums are not permitted */ |
536 | |
537 | cksum = htons(y); |
538 | if (sp->hdr.cksum != cksum) { |
539 | *_abort_code = RXKADSEALEDINCON; |
540 | _leave(" = -EPROTO [csum failed]"); |
541 | return -EPROTO; |
542 | } |
543 | |
544 | switch (call->conn->security_level) { |
545 | case RXRPC_SECURITY_PLAIN: |
546 | ret = 0; |
547 | break; |
548 | case RXRPC_SECURITY_AUTH: |
549 | ret = rxkad_verify_packet_auth(call, skb, _abort_code); |
550 | break; |
551 | case RXRPC_SECURITY_ENCRYPT: |
552 | ret = rxkad_verify_packet_encrypt(call, skb, _abort_code); |
553 | break; |
554 | default: |
555 | ret = -ENOANO; |
556 | break; |
557 | } |
558 | |
559 | _leave(" = %d", ret); |
560 | return ret; |
561 | } |
562 | |
563 | /* |
564 | * issue a challenge |
565 | */ |
566 | static int rxkad_issue_challenge(struct rxrpc_connection *conn) |
567 | { |
568 | struct rxkad_challenge challenge; |
569 | struct rxrpc_header hdr; |
570 | struct msghdr msg; |
571 | struct kvec iov[2]; |
572 | size_t len; |
573 | int ret; |
574 | |
575 | _enter("{%d,%x}", conn->debug_id, key_serial(conn->key)); |
576 | |
577 | ret = key_validate(conn->key); |
578 | if (ret < 0) |
579 | return ret; |
580 | |
581 | get_random_bytes(&conn->security_nonce, sizeof(conn->security_nonce)); |
582 | |
583 | challenge.version = htonl(2); |
584 | challenge.nonce = htonl(conn->security_nonce); |
585 | challenge.min_level = htonl(0); |
586 | challenge.__padding = 0; |
587 | |
588 | msg.msg_name = &conn->trans->peer->srx.transport.sin; |
589 | msg.msg_namelen = sizeof(conn->trans->peer->srx.transport.sin); |
590 | msg.msg_control = NULL; |
591 | msg.msg_controllen = 0; |
592 | msg.msg_flags = 0; |
593 | |
594 | hdr.epoch = conn->epoch; |
595 | hdr.cid = conn->cid; |
596 | hdr.callNumber = 0; |
597 | hdr.seq = 0; |
598 | hdr.type = RXRPC_PACKET_TYPE_CHALLENGE; |
599 | hdr.flags = conn->out_clientflag; |
600 | hdr.userStatus = 0; |
601 | hdr.securityIndex = conn->security_ix; |
602 | hdr._rsvd = 0; |
603 | hdr.serviceId = conn->service_id; |
604 | |
605 | iov[0].iov_base = &hdr; |
606 | iov[0].iov_len = sizeof(hdr); |
607 | iov[1].iov_base = &challenge; |
608 | iov[1].iov_len = sizeof(challenge); |
609 | |
610 | len = iov[0].iov_len + iov[1].iov_len; |
611 | |
612 | hdr.serial = htonl(atomic_inc_return(&conn->serial)); |
613 | _proto("Tx CHALLENGE %%%u", ntohl(hdr.serial)); |
614 | |
615 | ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 2, len); |
616 | if (ret < 0) { |
617 | _debug("sendmsg failed: %d", ret); |
618 | return -EAGAIN; |
619 | } |
620 | |
621 | _leave(" = 0"); |
622 | return 0; |
623 | } |
624 | |
625 | /* |
626 | * send a Kerberos security response |
627 | */ |
628 | static int rxkad_send_response(struct rxrpc_connection *conn, |
629 | struct rxrpc_header *hdr, |
630 | struct rxkad_response *resp, |
631 | const struct rxkad_key *s2) |
632 | { |
633 | struct msghdr msg; |
634 | struct kvec iov[3]; |
635 | size_t len; |
636 | int ret; |
637 | |
638 | _enter(""); |
639 | |
640 | msg.msg_name = &conn->trans->peer->srx.transport.sin; |
641 | msg.msg_namelen = sizeof(conn->trans->peer->srx.transport.sin); |
642 | msg.msg_control = NULL; |
643 | msg.msg_controllen = 0; |
644 | msg.msg_flags = 0; |
645 | |
646 | hdr->epoch = conn->epoch; |
647 | hdr->seq = 0; |
648 | hdr->type = RXRPC_PACKET_TYPE_RESPONSE; |
649 | hdr->flags = conn->out_clientflag; |
650 | hdr->userStatus = 0; |
651 | hdr->_rsvd = 0; |
652 | |
653 | iov[0].iov_base = hdr; |
654 | iov[0].iov_len = sizeof(*hdr); |
655 | iov[1].iov_base = resp; |
656 | iov[1].iov_len = sizeof(*resp); |
657 | iov[2].iov_base = (void *) s2->ticket; |
658 | iov[2].iov_len = s2->ticket_len; |
659 | |
660 | len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len; |
661 | |
662 | hdr->serial = htonl(atomic_inc_return(&conn->serial)); |
663 | _proto("Tx RESPONSE %%%u", ntohl(hdr->serial)); |
664 | |
665 | ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len); |
666 | if (ret < 0) { |
667 | _debug("sendmsg failed: %d", ret); |
668 | return -EAGAIN; |
669 | } |
670 | |
671 | _leave(" = 0"); |
672 | return 0; |
673 | } |
674 | |
675 | /* |
676 | * calculate the response checksum |
677 | */ |
678 | static void rxkad_calc_response_checksum(struct rxkad_response *response) |
679 | { |
680 | u32 csum = 1000003; |
681 | int loop; |
682 | u8 *p = (u8 *) response; |
683 | |
684 | for (loop = sizeof(*response); loop > 0; loop--) |
685 | csum = csum * 0x10204081 + *p++; |
686 | |
687 | response->encrypted.checksum = htonl(csum); |
688 | } |
689 | |
690 | /* |
691 | * load a scatterlist with a potentially split-page buffer |
692 | */ |
693 | static void rxkad_sg_set_buf2(struct scatterlist sg[2], |
694 | void *buf, size_t buflen) |
695 | { |
696 | int nsg = 1; |
697 | |
698 | sg_init_table(sg, 2); |
699 | |
700 | sg_set_buf(&sg[0], buf, buflen); |
701 | if (sg[0].offset + buflen > PAGE_SIZE) { |
702 | /* the buffer was split over two pages */ |
703 | sg[0].length = PAGE_SIZE - sg[0].offset; |
704 | sg_set_buf(&sg[1], buf + sg[0].length, buflen - sg[0].length); |
705 | nsg++; |
706 | } |
707 | |
708 | sg_mark_end(&sg[nsg - 1]); |
709 | |
710 | ASSERTCMP(sg[0].length + sg[1].length, ==, buflen); |
711 | } |
712 | |
713 | /* |
714 | * encrypt the response packet |
715 | */ |
716 | static void rxkad_encrypt_response(struct rxrpc_connection *conn, |
717 | struct rxkad_response *resp, |
718 | const struct rxkad_key *s2) |
719 | { |
720 | struct blkcipher_desc desc; |
721 | struct rxrpc_crypt iv; |
722 | struct scatterlist sg[2]; |
723 | |
724 | /* continue encrypting from where we left off */ |
725 | memcpy(&iv, s2->session_key, sizeof(iv)); |
726 | desc.tfm = conn->cipher; |
727 | desc.info = iv.x; |
728 | desc.flags = 0; |
729 | |
730 | rxkad_sg_set_buf2(sg, &resp->encrypted, sizeof(resp->encrypted)); |
731 | crypto_blkcipher_encrypt_iv(&desc, sg, sg, sizeof(resp->encrypted)); |
732 | } |
733 | |
734 | /* |
735 | * respond to a challenge packet |
736 | */ |
737 | static int rxkad_respond_to_challenge(struct rxrpc_connection *conn, |
738 | struct sk_buff *skb, |
739 | u32 *_abort_code) |
740 | { |
741 | const struct rxrpc_key_token *token; |
742 | struct rxkad_challenge challenge; |
743 | struct rxkad_response resp |
744 | __attribute__((aligned(8))); /* must be aligned for crypto */ |
745 | struct rxrpc_skb_priv *sp; |
746 | u32 version, nonce, min_level, abort_code; |
747 | int ret; |
748 | |
749 | _enter("{%d,%x}", conn->debug_id, key_serial(conn->key)); |
750 | |
751 | if (!conn->key) { |
752 | _leave(" = -EPROTO [no key]"); |
753 | return -EPROTO; |
754 | } |
755 | |
756 | ret = key_validate(conn->key); |
757 | if (ret < 0) { |
758 | *_abort_code = RXKADEXPIRED; |
759 | return ret; |
760 | } |
761 | |
762 | abort_code = RXKADPACKETSHORT; |
763 | sp = rxrpc_skb(skb); |
764 | if (skb_copy_bits(skb, 0, &challenge, sizeof(challenge)) < 0) |
765 | goto protocol_error; |
766 | |
767 | version = ntohl(challenge.version); |
768 | nonce = ntohl(challenge.nonce); |
769 | min_level = ntohl(challenge.min_level); |
770 | |
771 | _proto("Rx CHALLENGE %%%u { v=%u n=%u ml=%u }", |
772 | ntohl(sp->hdr.serial), version, nonce, min_level); |
773 | |
774 | abort_code = RXKADINCONSISTENCY; |
775 | if (version != RXKAD_VERSION) |
776 | goto protocol_error; |
777 | |
778 | abort_code = RXKADLEVELFAIL; |
779 | if (conn->security_level < min_level) |
780 | goto protocol_error; |
781 | |
782 | token = conn->key->payload.data; |
783 | |
784 | /* build the response packet */ |
785 | memset(&resp, 0, sizeof(resp)); |
786 | |
787 | resp.version = RXKAD_VERSION; |
788 | resp.encrypted.epoch = conn->epoch; |
789 | resp.encrypted.cid = conn->cid; |
790 | resp.encrypted.securityIndex = htonl(conn->security_ix); |
791 | resp.encrypted.call_id[0] = |
792 | (conn->channels[0] ? conn->channels[0]->call_id : 0); |
793 | resp.encrypted.call_id[1] = |
794 | (conn->channels[1] ? conn->channels[1]->call_id : 0); |
795 | resp.encrypted.call_id[2] = |
796 | (conn->channels[2] ? conn->channels[2]->call_id : 0); |
797 | resp.encrypted.call_id[3] = |
798 | (conn->channels[3] ? conn->channels[3]->call_id : 0); |
799 | resp.encrypted.inc_nonce = htonl(nonce + 1); |
800 | resp.encrypted.level = htonl(conn->security_level); |
801 | resp.kvno = htonl(token->kad->kvno); |
802 | resp.ticket_len = htonl(token->kad->ticket_len); |
803 | |
804 | /* calculate the response checksum and then do the encryption */ |
805 | rxkad_calc_response_checksum(&resp); |
806 | rxkad_encrypt_response(conn, &resp, token->kad); |
807 | return rxkad_send_response(conn, &sp->hdr, &resp, token->kad); |
808 | |
809 | protocol_error: |
810 | *_abort_code = abort_code; |
811 | _leave(" = -EPROTO [%d]", abort_code); |
812 | return -EPROTO; |
813 | } |
814 | |
815 | /* |
816 | * decrypt the kerberos IV ticket in the response |
817 | */ |
818 | static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, |
819 | void *ticket, size_t ticket_len, |
820 | struct rxrpc_crypt *_session_key, |
821 | time_t *_expiry, |
822 | u32 *_abort_code) |
823 | { |
824 | struct blkcipher_desc desc; |
825 | struct rxrpc_crypt iv, key; |
826 | struct scatterlist sg[1]; |
827 | struct in_addr addr; |
828 | unsigned life; |
829 | time_t issue, now; |
830 | bool little_endian; |
831 | int ret; |
832 | u8 *p, *q, *name, *end; |
833 | |
834 | _enter("{%d},{%x}", conn->debug_id, key_serial(conn->server_key)); |
835 | |
836 | *_expiry = 0; |
837 | |
838 | ret = key_validate(conn->server_key); |
839 | if (ret < 0) { |
840 | switch (ret) { |
841 | case -EKEYEXPIRED: |
842 | *_abort_code = RXKADEXPIRED; |
843 | goto error; |
844 | default: |
845 | *_abort_code = RXKADNOAUTH; |
846 | goto error; |
847 | } |
848 | } |
849 | |
850 | ASSERT(conn->server_key->payload.data != NULL); |
851 | ASSERTCMP((unsigned long) ticket & 7UL, ==, 0); |
852 | |
853 | memcpy(&iv, &conn->server_key->type_data, sizeof(iv)); |
854 | |
855 | desc.tfm = conn->server_key->payload.data; |
856 | desc.info = iv.x; |
857 | desc.flags = 0; |
858 | |
859 | sg_init_one(&sg[0], ticket, ticket_len); |
860 | crypto_blkcipher_decrypt_iv(&desc, sg, sg, ticket_len); |
861 | |
862 | p = ticket; |
863 | end = p + ticket_len; |
864 | |
865 | #define Z(size) \ |
866 | ({ \ |
867 | u8 *__str = p; \ |
868 | q = memchr(p, 0, end - p); \ |
869 | if (!q || q - p > (size)) \ |
870 | goto bad_ticket; \ |
871 | for (; p < q; p++) \ |
872 | if (!isprint(*p)) \ |
873 | goto bad_ticket; \ |
874 | p++; \ |
875 | __str; \ |
876 | }) |
877 | |
878 | /* extract the ticket flags */ |
879 | _debug("KIV FLAGS: %x", *p); |
880 | little_endian = *p & 1; |
881 | p++; |
882 | |
883 | /* extract the authentication name */ |
884 | name = Z(ANAME_SZ); |
885 | _debug("KIV ANAME: %s", name); |
886 | |
887 | /* extract the principal's instance */ |
888 | name = Z(INST_SZ); |
889 | _debug("KIV INST : %s", name); |
890 | |
891 | /* extract the principal's authentication domain */ |
892 | name = Z(REALM_SZ); |
893 | _debug("KIV REALM: %s", name); |
894 | |
895 | if (end - p < 4 + 8 + 4 + 2) |
896 | goto bad_ticket; |
897 | |
898 | /* get the IPv4 address of the entity that requested the ticket */ |
899 | memcpy(&addr, p, sizeof(addr)); |
900 | p += 4; |
901 | _debug("KIV ADDR : %pI4", &addr); |
902 | |
903 | /* get the session key from the ticket */ |
904 | memcpy(&key, p, sizeof(key)); |
905 | p += 8; |
906 | _debug("KIV KEY : %08x %08x", ntohl(key.n[0]), ntohl(key.n[1])); |
907 | memcpy(_session_key, &key, sizeof(key)); |
908 | |
909 | /* get the ticket's lifetime */ |
910 | life = *p++ * 5 * 60; |
911 | _debug("KIV LIFE : %u", life); |
912 | |
913 | /* get the issue time of the ticket */ |
914 | if (little_endian) { |
915 | __le32 stamp; |
916 | memcpy(&stamp, p, 4); |
917 | issue = le32_to_cpu(stamp); |
918 | } else { |
919 | __be32 stamp; |
920 | memcpy(&stamp, p, 4); |
921 | issue = be32_to_cpu(stamp); |
922 | } |
923 | p += 4; |
924 | now = get_seconds(); |
925 | _debug("KIV ISSUE: %lx [%lx]", issue, now); |
926 | |
927 | /* check the ticket is in date */ |
928 | if (issue > now) { |
929 | *_abort_code = RXKADNOAUTH; |
930 | ret = -EKEYREJECTED; |
931 | goto error; |
932 | } |
933 | |
934 | if (issue < now - life) { |
935 | *_abort_code = RXKADEXPIRED; |
936 | ret = -EKEYEXPIRED; |
937 | goto error; |
938 | } |
939 | |
940 | *_expiry = issue + life; |
941 | |
942 | /* get the service name */ |
943 | name = Z(SNAME_SZ); |
944 | _debug("KIV SNAME: %s", name); |
945 | |
946 | /* get the service instance name */ |
947 | name = Z(INST_SZ); |
948 | _debug("KIV SINST: %s", name); |
949 | |
950 | ret = 0; |
951 | error: |
952 | _leave(" = %d", ret); |
953 | return ret; |
954 | |
955 | bad_ticket: |
956 | *_abort_code = RXKADBADTICKET; |
957 | ret = -EBADMSG; |
958 | goto error; |
959 | } |
960 | |
961 | /* |
962 | * decrypt the response packet |
963 | */ |
964 | static void rxkad_decrypt_response(struct rxrpc_connection *conn, |
965 | struct rxkad_response *resp, |
966 | const struct rxrpc_crypt *session_key) |
967 | { |
968 | struct blkcipher_desc desc; |
969 | struct scatterlist sg[2]; |
970 | struct rxrpc_crypt iv; |
971 | |
972 | _enter(",,%08x%08x", |
973 | ntohl(session_key->n[0]), ntohl(session_key->n[1])); |
974 | |
975 | ASSERT(rxkad_ci != NULL); |
976 | |
977 | mutex_lock(&rxkad_ci_mutex); |
978 | if (crypto_blkcipher_setkey(rxkad_ci, session_key->x, |
979 | sizeof(*session_key)) < 0) |
980 | BUG(); |
981 | |
982 | memcpy(&iv, session_key, sizeof(iv)); |
983 | desc.tfm = rxkad_ci; |
984 | desc.info = iv.x; |
985 | desc.flags = 0; |
986 | |
987 | rxkad_sg_set_buf2(sg, &resp->encrypted, sizeof(resp->encrypted)); |
988 | crypto_blkcipher_decrypt_iv(&desc, sg, sg, sizeof(resp->encrypted)); |
989 | mutex_unlock(&rxkad_ci_mutex); |
990 | |
991 | _leave(""); |
992 | } |
993 | |
994 | /* |
995 | * verify a response |
996 | */ |
997 | static int rxkad_verify_response(struct rxrpc_connection *conn, |
998 | struct sk_buff *skb, |
999 | u32 *_abort_code) |
1000 | { |
1001 | struct rxkad_response response |
1002 | __attribute__((aligned(8))); /* must be aligned for crypto */ |
1003 | struct rxrpc_skb_priv *sp; |
1004 | struct rxrpc_crypt session_key; |
1005 | time_t expiry; |
1006 | void *ticket; |
1007 | u32 abort_code, version, kvno, ticket_len, level; |
1008 | __be32 csum; |
1009 | int ret; |
1010 | |
1011 | _enter("{%d,%x}", conn->debug_id, key_serial(conn->server_key)); |
1012 | |
1013 | abort_code = RXKADPACKETSHORT; |
1014 | if (skb_copy_bits(skb, 0, &response, sizeof(response)) < 0) |
1015 | goto protocol_error; |
1016 | if (!pskb_pull(skb, sizeof(response))) |
1017 | BUG(); |
1018 | |
1019 | version = ntohl(response.version); |
1020 | ticket_len = ntohl(response.ticket_len); |
1021 | kvno = ntohl(response.kvno); |
1022 | sp = rxrpc_skb(skb); |
1023 | _proto("Rx RESPONSE %%%u { v=%u kv=%u tl=%u }", |
1024 | ntohl(sp->hdr.serial), version, kvno, ticket_len); |
1025 | |
1026 | abort_code = RXKADINCONSISTENCY; |
1027 | if (version != RXKAD_VERSION) |
1028 | goto protocol_error; |
1029 | |
1030 | abort_code = RXKADTICKETLEN; |
1031 | if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN) |
1032 | goto protocol_error; |
1033 | |
1034 | abort_code = RXKADUNKNOWNKEY; |
1035 | if (kvno >= RXKAD_TKT_TYPE_KERBEROS_V5) |
1036 | goto protocol_error; |
1037 | |
1038 | /* extract the kerberos ticket and decrypt and decode it */ |
1039 | ticket = kmalloc(ticket_len, GFP_NOFS); |
1040 | if (!ticket) |
1041 | return -ENOMEM; |
1042 | |
1043 | abort_code = RXKADPACKETSHORT; |
1044 | if (skb_copy_bits(skb, 0, ticket, ticket_len) < 0) |
1045 | goto protocol_error_free; |
1046 | |
1047 | ret = rxkad_decrypt_ticket(conn, ticket, ticket_len, &session_key, |
1048 | &expiry, &abort_code); |
1049 | if (ret < 0) { |
1050 | *_abort_code = abort_code; |
1051 | kfree(ticket); |
1052 | return ret; |
1053 | } |
1054 | |
1055 | /* use the session key from inside the ticket to decrypt the |
1056 | * response */ |
1057 | rxkad_decrypt_response(conn, &response, &session_key); |
1058 | |
1059 | abort_code = RXKADSEALEDINCON; |
1060 | if (response.encrypted.epoch != conn->epoch) |
1061 | goto protocol_error_free; |
1062 | if (response.encrypted.cid != conn->cid) |
1063 | goto protocol_error_free; |
1064 | if (ntohl(response.encrypted.securityIndex) != conn->security_ix) |
1065 | goto protocol_error_free; |
1066 | csum = response.encrypted.checksum; |
1067 | response.encrypted.checksum = 0; |
1068 | rxkad_calc_response_checksum(&response); |
1069 | if (response.encrypted.checksum != csum) |
1070 | goto protocol_error_free; |
1071 | |
1072 | if (ntohl(response.encrypted.call_id[0]) > INT_MAX || |
1073 | ntohl(response.encrypted.call_id[1]) > INT_MAX || |
1074 | ntohl(response.encrypted.call_id[2]) > INT_MAX || |
1075 | ntohl(response.encrypted.call_id[3]) > INT_MAX) |
1076 | goto protocol_error_free; |
1077 | |
1078 | abort_code = RXKADOUTOFSEQUENCE; |
1079 | if (response.encrypted.inc_nonce != htonl(conn->security_nonce + 1)) |
1080 | goto protocol_error_free; |
1081 | |
1082 | abort_code = RXKADLEVELFAIL; |
1083 | level = ntohl(response.encrypted.level); |
1084 | if (level > RXRPC_SECURITY_ENCRYPT) |
1085 | goto protocol_error_free; |
1086 | conn->security_level = level; |
1087 | |
1088 | /* create a key to hold the security data and expiration time - after |
1089 | * this the connection security can be handled in exactly the same way |
1090 | * as for a client connection */ |
1091 | ret = rxrpc_get_server_data_key(conn, &session_key, expiry, kvno); |
1092 | if (ret < 0) { |
1093 | kfree(ticket); |
1094 | return ret; |
1095 | } |
1096 | |
1097 | kfree(ticket); |
1098 | _leave(" = 0"); |
1099 | return 0; |
1100 | |
1101 | protocol_error_free: |
1102 | kfree(ticket); |
1103 | protocol_error: |
1104 | *_abort_code = abort_code; |
1105 | _leave(" = -EPROTO [%d]", abort_code); |
1106 | return -EPROTO; |
1107 | } |
1108 | |
1109 | /* |
1110 | * clear the connection security |
1111 | */ |
1112 | static void rxkad_clear(struct rxrpc_connection *conn) |
1113 | { |
1114 | _enter(""); |
1115 | |
1116 | if (conn->cipher) |
1117 | crypto_free_blkcipher(conn->cipher); |
1118 | } |
1119 | |
1120 | /* |
1121 | * RxRPC Kerberos-based security |
1122 | */ |
1123 | static struct rxrpc_security rxkad = { |
1124 | .owner = THIS_MODULE, |
1125 | .name = "rxkad", |
1126 | .security_index = RXRPC_SECURITY_RXKAD, |
1127 | .init_connection_security = rxkad_init_connection_security, |
1128 | .prime_packet_security = rxkad_prime_packet_security, |
1129 | .secure_packet = rxkad_secure_packet, |
1130 | .verify_packet = rxkad_verify_packet, |
1131 | .issue_challenge = rxkad_issue_challenge, |
1132 | .respond_to_challenge = rxkad_respond_to_challenge, |
1133 | .verify_response = rxkad_verify_response, |
1134 | .clear = rxkad_clear, |
1135 | }; |
1136 | |
1137 | static __init int rxkad_init(void) |
1138 | { |
1139 | _enter(""); |
1140 | |
1141 | /* pin the cipher we need so that the crypto layer doesn't invoke |
1142 | * keventd to go get it */ |
1143 | rxkad_ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); |
1144 | if (IS_ERR(rxkad_ci)) |
1145 | return PTR_ERR(rxkad_ci); |
1146 | |
1147 | return rxrpc_register_security(&rxkad); |
1148 | } |
1149 | |
1150 | module_init(rxkad_init); |
1151 | |
1152 | static __exit void rxkad_exit(void) |
1153 | { |
1154 | _enter(""); |
1155 | |
1156 | rxrpc_unregister_security(&rxkad); |
1157 | crypto_free_blkcipher(rxkad_ci); |
1158 | } |
1159 | |
1160 | module_exit(rxkad_exit); |
1161 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9