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