Blame view

net/rxrpc/rxkad.c 32.6 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
17926a793   David Howells   [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   David Howells   [AF_RXRPC]: Provi...
6
   */
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
7
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1afe593b4   Herbert Xu   rxrpc: Use skcipher
8
  #include <crypto/skcipher.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
9
10
11
12
  #include <linux/module.h>
  #include <linux/net.h>
  #include <linux/skbuff.h>
  #include <linux/udp.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
13
14
  #include <linux/scatterlist.h>
  #include <linux/ctype.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
15
  #include <linux/slab.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
16
17
  #include <net/sock.h>
  #include <net/af_rxrpc.h>
339412841   David Howells   RxRPC: Allow key ...
18
  #include <keys/rxrpc-type.h>
17926a793   David Howells   [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   David Howells   [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   David Howells   [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   Kees Cook   rxrpc: Remove VLA...
41
  static struct crypto_sync_skcipher *rxkad_ci;
1db88c534   David Howells   rxrpc: Fix -Wfram...
42
  static struct skcipher_request *rxkad_ci_req;
17926a793   David Howells   [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   Kees Cook   rxrpc: Remove VLA...
50
  	struct crypto_sync_skcipher *ci;
339412841   David Howells   RxRPC: Allow key ...
51
  	struct rxrpc_key_token *token;
17926a793   David Howells   [AF_RXRPC]: Provi...
52
  	int ret;
19ffa01c9   David Howells   rxrpc: Use struct...
53
  	_enter("{%d},{%x}", conn->debug_id, key_serial(conn->params.key));
17926a793   David Howells   [AF_RXRPC]: Provi...
54

19ffa01c9   David Howells   rxrpc: Use struct...
55
  	token = conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
56
  	conn->security_ix = token->security_index;
17926a793   David Howells   [AF_RXRPC]: Provi...
57

69d826fa5   Kees Cook   rxrpc: Remove VLA...
58
  	ci = crypto_alloc_sync_skcipher("pcbc(fcrypt)", 0, 0);
17926a793   David Howells   [AF_RXRPC]: Provi...
59
60
61
62
63
  	if (IS_ERR(ci)) {
  		_debug("no cipher");
  		ret = PTR_ERR(ci);
  		goto error;
  	}
69d826fa5   Kees Cook   rxrpc: Remove VLA...
64
  	if (crypto_sync_skcipher_setkey(ci, token->kad->session_key,
1afe593b4   Herbert Xu   rxrpc: Use skcipher
65
  				   sizeof(token->kad->session_key)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
66
  		BUG();
19ffa01c9   David Howells   rxrpc: Use struct...
67
  	switch (conn->params.security_level) {
17926a793   David Howells   [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   David Howells   [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   David Howells   [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   Herbert Xu   rxrpc: Avoid usin...
94
  static int rxkad_prime_packet_security(struct rxrpc_connection *conn)
17926a793   David Howells   [AF_RXRPC]: Provi...
95
  {
1db88c534   David Howells   rxrpc: Fix -Wfram...
96
  	struct skcipher_request *req;
339412841   David Howells   RxRPC: Allow key ...
97
  	struct rxrpc_key_token *token;
a263629da   Herbert Xu   rxrpc: Avoid usin...
98
  	struct scatterlist sg;
17926a793   David Howells   [AF_RXRPC]: Provi...
99
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
100
101
  	__be32 *tmpbuf;
  	size_t tmpsize = 4 * sizeof(__be32);
17926a793   David Howells   [AF_RXRPC]: Provi...
102
103
  
  	_enter("");
19ffa01c9   David Howells   rxrpc: Use struct...
104
  	if (!conn->params.key)
a263629da   Herbert Xu   rxrpc: Avoid usin...
105
106
107
108
109
  		return 0;
  
  	tmpbuf = kmalloc(tmpsize, GFP_KERNEL);
  	if (!tmpbuf)
  		return -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
110

1db88c534   David Howells   rxrpc: Fix -Wfram...
111
112
113
114
115
  	req = skcipher_request_alloc(&conn->cipher->base, GFP_NOFS);
  	if (!req) {
  		kfree(tmpbuf);
  		return -ENOMEM;
  	}
19ffa01c9   David Howells   rxrpc: Use struct...
116
  	token = conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
117
  	memcpy(&iv, token->kad->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
118

a263629da   Herbert Xu   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   Herbert Xu   rxrpc: Use skcipher
123

a263629da   Herbert Xu   rxrpc: Avoid usin...
124
  	sg_init_one(&sg, tmpbuf, tmpsize);
69d826fa5   Kees Cook   rxrpc: Remove VLA...
125
  	skcipher_request_set_sync_tfm(req, conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
126
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
127
  	skcipher_request_set_crypt(req, &sg, &sg, tmpsize, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
128
  	crypto_skcipher_encrypt(req);
1db88c534   David Howells   rxrpc: Fix -Wfram...
129
  	skcipher_request_free(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
130

a263629da   Herbert Xu   rxrpc: Avoid usin...
131
132
133
134
  	memcpy(&conn->csum_iv, tmpbuf + 2, sizeof(conn->csum_iv));
  	kfree(tmpbuf);
  	_leave(" = 0");
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
135
136
137
  }
  
  /*
1db88c534   David Howells   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   David Howells   [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   Kees Cook   rxrpc: Reuse SKCI...
172
173
  				    void *sechdr,
  				    struct skcipher_request *req)
17926a793   David Howells   [AF_RXRPC]: Provi...
174
  {
fb46f6ee1   David Howells   rxrpc: Trace prot...
175
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
a263629da   Herbert Xu   rxrpc: Avoid usin...
176
  	struct rxkad_level1_hdr hdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
177
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
178
  	struct scatterlist sg;
17926a793   David Howells   [AF_RXRPC]: Provi...
179
  	u16 check;
17926a793   David Howells   [AF_RXRPC]: Provi...
180
  	_enter("");
5a924b895   David Howells   rxrpc: Don't stor...
181
  	check = sp->hdr.seq ^ call->call_id;
0d12f8a40   David Howells   rxrpc: Keep the s...
182
  	data_size |= (u32)check << 16;
17926a793   David Howells   [AF_RXRPC]: Provi...
183

a263629da   Herbert Xu   rxrpc: Avoid usin...
184
185
  	hdr.data_size = htonl(data_size);
  	memcpy(sechdr, &hdr, sizeof(hdr));
17926a793   David Howells   [AF_RXRPC]: Provi...
186
187
188
  
  	/* start the encryption afresh */
  	memset(&iv, 0, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
189

a263629da   Herbert Xu   rxrpc: Avoid usin...
190
  	sg_init_one(&sg, sechdr, 8);
69d826fa5   Kees Cook   rxrpc: Remove VLA...
191
  	skcipher_request_set_sync_tfm(req, call->conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
192
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
193
  	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
194
195
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
196

17926a793   David Howells   [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   David Howells   rxrpc: Adjust som...
205
206
  				       struct sk_buff *skb,
  				       u32 data_size,
54424d389   Kees Cook   rxrpc: Reuse SKCI...
207
208
  				       void *sechdr,
  				       struct skcipher_request *req)
17926a793   David Howells   [AF_RXRPC]: Provi...
209
  {
339412841   David Howells   RxRPC: Allow key ...
210
  	const struct rxrpc_key_token *token;
a263629da   Herbert Xu   rxrpc: Avoid usin...
211
  	struct rxkad_level2_hdr rxkhdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
212
  	struct rxrpc_skb_priv *sp;
17926a793   David Howells   [AF_RXRPC]: Provi...
213
214
  	struct rxrpc_crypt iv;
  	struct scatterlist sg[16];
95c961747   Eric Dumazet   net: cleanup unsi...
215
  	unsigned int len;
17926a793   David Howells   [AF_RXRPC]: Provi...
216
  	u16 check;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
217
  	int err;
17926a793   David Howells   [AF_RXRPC]: Provi...
218
219
220
221
  
  	sp = rxrpc_skb(skb);
  
  	_enter("");
5a924b895   David Howells   rxrpc: Don't stor...
222
  	check = sp->hdr.seq ^ call->call_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
223

0d12f8a40   David Howells   rxrpc: Keep the s...
224
  	rxkhdr.data_size = htonl(data_size | (u32)check << 16);
17926a793   David Howells   [AF_RXRPC]: Provi...
225
  	rxkhdr.checksum = 0;
a263629da   Herbert Xu   rxrpc: Avoid usin...
226
  	memcpy(sechdr, &rxkhdr, sizeof(rxkhdr));
17926a793   David Howells   [AF_RXRPC]: Provi...
227
228
  
  	/* encrypt from the session key */
19ffa01c9   David Howells   rxrpc: Use struct...
229
  	token = call->conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
230
  	memcpy(&iv, token->kad->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
231

68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
232
  	sg_init_one(&sg[0], sechdr, sizeof(rxkhdr));
69d826fa5   Kees Cook   rxrpc: Remove VLA...
233
  	skcipher_request_set_sync_tfm(req, call->conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
234
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
235
  	skcipher_request_set_crypt(req, &sg[0], &sg[0], sizeof(rxkhdr), iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
236
  	crypto_skcipher_encrypt(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
237
238
  
  	/* we want to encrypt the skbuff in-place */
d0d5c0cd1   David Howells   rxrpc: Use skb_un...
239
240
  	err = -EMSGSIZE;
  	if (skb_shinfo(skb)->nr_frags > 16)
1afe593b4   Herbert Xu   rxrpc: Use skcipher
241
  		goto out;
17926a793   David Howells   [AF_RXRPC]: Provi...
242
243
244
  
  	len = data_size + call->conn->size_align - 1;
  	len &= ~(call->conn->size_align - 1);
d0d5c0cd1   David Howells   rxrpc: Use skb_un...
245
  	sg_init_table(sg, ARRAY_SIZE(sg));
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
246
247
248
  	err = skb_to_sgvec(skb, sg, 0, len);
  	if (unlikely(err < 0))
  		goto out;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
249
  	skcipher_request_set_crypt(req, sg, sg, len, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
250
  	crypto_skcipher_encrypt(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
251
252
  
  	_leave(" = 0");
1afe593b4   Herbert Xu   rxrpc: Use skcipher
253
254
255
256
257
  	err = 0;
  
  out:
  	skcipher_request_zero(req);
  	return err;
17926a793   David Howells   [AF_RXRPC]: Provi...
258
259
260
261
262
  }
  
  /*
   * checksum an RxRPC packet header
   */
a263629da   Herbert Xu   rxrpc: Avoid usin...
263
  static int rxkad_secure_packet(struct rxrpc_call *call,
b4f1342f9   David Howells   rxrpc: Adjust som...
264
265
266
  			       struct sk_buff *skb,
  			       size_t data_size,
  			       void *sechdr)
17926a793   David Howells   [AF_RXRPC]: Provi...
267
268
  {
  	struct rxrpc_skb_priv *sp;
1db88c534   David Howells   rxrpc: Fix -Wfram...
269
  	struct skcipher_request	*req;
17926a793   David Howells   [AF_RXRPC]: Provi...
270
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
271
  	struct scatterlist sg;
0d12f8a40   David Howells   rxrpc: Keep the s...
272
  	u32 x, y;
17926a793   David Howells   [AF_RXRPC]: Provi...
273
274
275
276
277
  	int ret;
  
  	sp = rxrpc_skb(skb);
  
  	_enter("{%d{%x}},{#%u},%zu,",
19ffa01c9   David Howells   rxrpc: Use struct...
278
279
  	       call->debug_id, key_serial(call->conn->params.key),
  	       sp->hdr.seq, data_size);
17926a793   David Howells   [AF_RXRPC]: Provi...
280
281
282
  
  	if (!call->conn->cipher)
  		return 0;
19ffa01c9   David Howells   rxrpc: Use struct...
283
  	ret = key_validate(call->conn->params.key);
17926a793   David Howells   [AF_RXRPC]: Provi...
284
285
  	if (ret < 0)
  		return ret;
1db88c534   David Howells   rxrpc: Fix -Wfram...
286
287
288
  	req = rxkad_get_call_crypto(call);
  	if (!req)
  		return -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
289
290
  	/* continue encrypting from where we left off */
  	memcpy(&iv, call->conn->csum_iv.x, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
291
292
  
  	/* calculate the security checksum */
01a90a459   David Howells   rxrpc: Drop chann...
293
  	x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT);
0d12f8a40   David Howells   rxrpc: Keep the s...
294
  	x |= sp->hdr.seq & 0x3fffffff;
5a924b895   David Howells   rxrpc: Don't stor...
295
  	call->crypto_buf[0] = htonl(call->call_id);
a263629da   Herbert Xu   rxrpc: Avoid usin...
296
  	call->crypto_buf[1] = htonl(x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
297

a263629da   Herbert Xu   rxrpc: Avoid usin...
298
  	sg_init_one(&sg, call->crypto_buf, 8);
69d826fa5   Kees Cook   rxrpc: Remove VLA...
299
  	skcipher_request_set_sync_tfm(req, call->conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
300
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
301
  	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
302
303
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
304

a263629da   Herbert Xu   rxrpc: Avoid usin...
305
  	y = ntohl(call->crypto_buf[1]);
91e916cff   Al Viro   net/rxrpc trivial...
306
307
308
  	y = (y >> 16) & 0xffff;
  	if (y == 0)
  		y = 1; /* zero checksums are not permitted */
0d12f8a40   David Howells   rxrpc: Keep the s...
309
  	sp->hdr.cksum = y;
17926a793   David Howells   [AF_RXRPC]: Provi...
310

19ffa01c9   David Howells   rxrpc: Use struct...
311
  	switch (call->conn->params.security_level) {
17926a793   David Howells   [AF_RXRPC]: Provi...
312
313
314
315
  	case RXRPC_SECURITY_PLAIN:
  		ret = 0;
  		break;
  	case RXRPC_SECURITY_AUTH:
54424d389   Kees Cook   rxrpc: Reuse SKCI...
316
317
  		ret = rxkad_secure_packet_auth(call, skb, data_size, sechdr,
  					       req);
17926a793   David Howells   [AF_RXRPC]: Provi...
318
319
320
  		break;
  	case RXRPC_SECURITY_ENCRYPT:
  		ret = rxkad_secure_packet_encrypt(call, skb, data_size,
54424d389   Kees Cook   rxrpc: Reuse SKCI...
321
  						  sechdr, req);
17926a793   David Howells   [AF_RXRPC]: Provi...
322
323
324
325
326
  		break;
  	default:
  		ret = -EPERM;
  		break;
  	}
91e916cff   Al Viro   net/rxrpc trivial...
327
  	_leave(" = %d [set %hx]", ret, y);
17926a793   David Howells   [AF_RXRPC]: Provi...
328
329
330
331
332
333
  	return ret;
  }
  
  /*
   * decrypt partial encryption on a packet (level 1 security)
   */
5a42976d4   David Howells   rxrpc: Add tracep...
334
  static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
248f219cb   David Howells   rxrpc: Rewrite th...
335
  				 unsigned int offset, unsigned int len,
54424d389   Kees Cook   rxrpc: Reuse SKCI...
336
337
  				 rxrpc_seq_t seq,
  				 struct skcipher_request *req)
17926a793   David Howells   [AF_RXRPC]: Provi...
338
339
  {
  	struct rxkad_level1_hdr sechdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
340
  	struct rxrpc_crypt iv;
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
341
  	struct scatterlist sg[16];
fb46f6ee1   David Howells   rxrpc: Trace prot...
342
  	bool aborted;
17926a793   David Howells   [AF_RXRPC]: Provi...
343
344
  	u32 data_size, buf;
  	u16 check;
d0d5c0cd1   David Howells   rxrpc: Use skb_un...
345
  	int ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
346
347
  
  	_enter("");
248f219cb   David Howells   rxrpc: Rewrite th...
348
  	if (len < 8) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
349
350
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_hdr", "V1H",
  					   RXKADSEALEDINCON);
5a42976d4   David Howells   rxrpc: Add tracep...
351
352
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
353

248f219cb   David Howells   rxrpc: Rewrite th...
354
355
356
  	/* Decrypt the skbuff in-place.  TODO: We really want to decrypt
  	 * directly into the target buffer.
  	 */
d0d5c0cd1   David Howells   rxrpc: Use skb_un...
357
  	sg_init_table(sg, ARRAY_SIZE(sg));
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
358
359
360
  	ret = skb_to_sgvec(skb, sg, offset, 8);
  	if (unlikely(ret < 0))
  		return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
361
362
363
  
  	/* start the decryption afresh */
  	memset(&iv, 0, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
364

69d826fa5   Kees Cook   rxrpc: Remove VLA...
365
  	skcipher_request_set_sync_tfm(req, call->conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
366
367
  	skcipher_request_set_callback(req, 0, NULL, NULL);
  	skcipher_request_set_crypt(req, sg, sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
368
369
  	crypto_skcipher_decrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
370

5a42976d4   David Howells   rxrpc: Add tracep...
371
  	/* Extract the decrypted packet length */
248f219cb   David Howells   rxrpc: Rewrite th...
372
  	if (skb_copy_bits(skb, offset, &sechdr, sizeof(sechdr)) < 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
373
374
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_len", "XV1",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
375
376
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
377
378
  	offset += sizeof(sechdr);
  	len -= sizeof(sechdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
379
380
381
382
383
  
  	buf = ntohl(sechdr.data_size);
  	data_size = buf & 0xffff;
  
  	check = buf >> 16;
5a42976d4   David Howells   rxrpc: Add tracep...
384
  	check ^= seq ^ call->call_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
385
386
  	check &= 0xffff;
  	if (check != 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
387
388
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_check", "V1C",
  					     RXKADSEALEDINCON);
17926a793   David Howells   [AF_RXRPC]: Provi...
389
390
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
391
  	if (data_size > len) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
392
393
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_datalen", "V1L",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
394
395
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
396
397
398
  
  	_leave(" = 0 [dlen=%x]", data_size);
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
399
  protocol_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
400
401
  	if (aborted)
  		rxrpc_send_abort_packet(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
402
  	return -EPROTO;
17926a793   David Howells   [AF_RXRPC]: Provi...
403
404
405
406
407
  }
  
  /*
   * wholly decrypt a packet (level 2 security)
   */
5a42976d4   David Howells   rxrpc: Add tracep...
408
  static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
248f219cb   David Howells   rxrpc: Rewrite th...
409
  				 unsigned int offset, unsigned int len,
54424d389   Kees Cook   rxrpc: Reuse SKCI...
410
411
  				 rxrpc_seq_t seq,
  				 struct skcipher_request *req)
17926a793   David Howells   [AF_RXRPC]: Provi...
412
  {
339412841   David Howells   RxRPC: Allow key ...
413
  	const struct rxrpc_key_token *token;
17926a793   David Howells   [AF_RXRPC]: Provi...
414
  	struct rxkad_level2_hdr sechdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
415
416
  	struct rxrpc_crypt iv;
  	struct scatterlist _sg[4], *sg;
fb46f6ee1   David Howells   rxrpc: Trace prot...
417
  	bool aborted;
17926a793   David Howells   [AF_RXRPC]: Provi...
418
419
  	u32 data_size, buf;
  	u16 check;
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
420
  	int nsg, ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
421
422
  
  	_enter(",{%d}", skb->len);
248f219cb   David Howells   rxrpc: Rewrite th...
423
  	if (len < 8) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
424
425
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_hdr", "V2H",
  					     RXKADSEALEDINCON);
5a42976d4   David Howells   rxrpc: Add tracep...
426
427
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
428

248f219cb   David Howells   rxrpc: Rewrite th...
429
430
431
  	/* Decrypt the skbuff in-place.  TODO: We really want to decrypt
  	 * directly into the target buffer.
  	 */
17926a793   David Howells   [AF_RXRPC]: Provi...
432
  	sg = _sg;
d0d5c0cd1   David Howells   rxrpc: Use skb_un...
433
434
435
436
  	nsg = skb_shinfo(skb)->nr_frags;
  	if (nsg <= 4) {
  		nsg = 4;
  	} else {
6da2ec560   Kees Cook   treewide: kmalloc...
437
  		sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO);
17926a793   David Howells   [AF_RXRPC]: Provi...
438
439
440
  		if (!sg)
  			goto nomem;
  	}
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
441
  	sg_init_table(sg, nsg);
89a5ea996   Jason A. Donenfeld   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   David Howells   [AF_RXRPC]: Provi...
448
449
  
  	/* decrypt from the session key */
19ffa01c9   David Howells   rxrpc: Use struct...
450
  	token = call->conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
451
  	memcpy(&iv, token->kad->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
452

69d826fa5   Kees Cook   rxrpc: Remove VLA...
453
  	skcipher_request_set_sync_tfm(req, call->conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
454
  	skcipher_request_set_callback(req, 0, NULL, NULL);
248f219cb   David Howells   rxrpc: Rewrite th...
455
  	skcipher_request_set_crypt(req, sg, sg, len, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
456
457
  	crypto_skcipher_decrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
458
459
  	if (sg != _sg)
  		kfree(sg);
5a42976d4   David Howells   rxrpc: Add tracep...
460
  	/* Extract the decrypted packet length */
248f219cb   David Howells   rxrpc: Rewrite th...
461
  	if (skb_copy_bits(skb, offset, &sechdr, sizeof(sechdr)) < 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
462
463
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_len", "XV2",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
464
465
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
466
467
  	offset += sizeof(sechdr);
  	len -= sizeof(sechdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
468
469
470
471
472
  
  	buf = ntohl(sechdr.data_size);
  	data_size = buf & 0xffff;
  
  	check = buf >> 16;
5a42976d4   David Howells   rxrpc: Add tracep...
473
  	check ^= seq ^ call->call_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
474
475
  	check &= 0xffff;
  	if (check != 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
476
477
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_check", "V2C",
  					     RXKADSEALEDINCON);
17926a793   David Howells   [AF_RXRPC]: Provi...
478
479
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
480
  	if (data_size > len) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
481
482
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_datalen", "V2L",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
483
484
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
485
486
487
  
  	_leave(" = 0 [dlen=%x]", data_size);
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
488
  protocol_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
489
490
  	if (aborted)
  		rxrpc_send_abort_packet(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
491
492
493
494
495
496
497
498
  	return -EPROTO;
  
  nomem:
  	_leave(" = -ENOMEM");
  	return -ENOMEM;
  }
  
  /*
5a42976d4   David Howells   rxrpc: Add tracep...
499
500
   * Verify the security on a received packet or subpacket (if part of a
   * jumbo packet).
17926a793   David Howells   [AF_RXRPC]: Provi...
501
   */
5a42976d4   David Howells   rxrpc: Add tracep...
502
  static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
248f219cb   David Howells   rxrpc: Rewrite th...
503
  			       unsigned int offset, unsigned int len,
5a42976d4   David Howells   rxrpc: Add tracep...
504
  			       rxrpc_seq_t seq, u16 expected_cksum)
17926a793   David Howells   [AF_RXRPC]: Provi...
505
  {
1db88c534   David Howells   rxrpc: Fix -Wfram...
506
  	struct skcipher_request	*req;
17926a793   David Howells   [AF_RXRPC]: Provi...
507
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
508
  	struct scatterlist sg;
fb46f6ee1   David Howells   rxrpc: Trace prot...
509
  	bool aborted;
0d12f8a40   David Howells   rxrpc: Keep the s...
510
511
  	u16 cksum;
  	u32 x, y;
17926a793   David Howells   [AF_RXRPC]: Provi...
512
513
  
  	_enter("{%d{%x}},{#%u}",
5a42976d4   David Howells   rxrpc: Add tracep...
514
  	       call->debug_id, key_serial(call->conn->params.key), seq);
17926a793   David Howells   [AF_RXRPC]: Provi...
515
516
517
  
  	if (!call->conn->cipher)
  		return 0;
1db88c534   David Howells   rxrpc: Fix -Wfram...
518
519
520
  	req = rxkad_get_call_crypto(call);
  	if (!req)
  		return -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
521
522
  	/* continue encrypting from where we left off */
  	memcpy(&iv, call->conn->csum_iv.x, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
523
524
  
  	/* validate the security checksum */
01a90a459   David Howells   rxrpc: Drop chann...
525
  	x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT);
5a42976d4   David Howells   rxrpc: Add tracep...
526
  	x |= seq & 0x3fffffff;
a263629da   Herbert Xu   rxrpc: Avoid usin...
527
528
  	call->crypto_buf[0] = htonl(call->call_id);
  	call->crypto_buf[1] = htonl(x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
529

a263629da   Herbert Xu   rxrpc: Avoid usin...
530
  	sg_init_one(&sg, call->crypto_buf, 8);
69d826fa5   Kees Cook   rxrpc: Remove VLA...
531
  	skcipher_request_set_sync_tfm(req, call->conn->cipher);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
532
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
533
  	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
534
535
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
536

a263629da   Herbert Xu   rxrpc: Avoid usin...
537
  	y = ntohl(call->crypto_buf[1]);
0d12f8a40   David Howells   rxrpc: Keep the s...
538
539
540
  	cksum = (y >> 16) & 0xffff;
  	if (cksum == 0)
  		cksum = 1; /* zero checksums are not permitted */
17926a793   David Howells   [AF_RXRPC]: Provi...
541

5a42976d4   David Howells   rxrpc: Add tracep...
542
  	if (cksum != expected_cksum) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
543
544
545
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_csum", "VCK",
  					     RXKADSEALEDINCON);
  		goto protocol_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
546
  	}
19ffa01c9   David Howells   rxrpc: Use struct...
547
  	switch (call->conn->params.security_level) {
17926a793   David Howells   [AF_RXRPC]: Provi...
548
  	case RXRPC_SECURITY_PLAIN:
5a42976d4   David Howells   rxrpc: Add tracep...
549
  		return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
550
  	case RXRPC_SECURITY_AUTH:
54424d389   Kees Cook   rxrpc: Reuse SKCI...
551
  		return rxkad_verify_packet_1(call, skb, offset, len, seq, req);
17926a793   David Howells   [AF_RXRPC]: Provi...
552
  	case RXRPC_SECURITY_ENCRYPT:
54424d389   Kees Cook   rxrpc: Reuse SKCI...
553
  		return rxkad_verify_packet_2(call, skb, offset, len, seq, req);
17926a793   David Howells   [AF_RXRPC]: Provi...
554
  	default:
5a42976d4   David Howells   rxrpc: Add tracep...
555
  		return -ENOANO;
17926a793   David Howells   [AF_RXRPC]: Provi...
556
  	}
fb46f6ee1   David Howells   rxrpc: Trace prot...
557
558
559
560
561
  
  protocol_error:
  	if (aborted)
  		rxrpc_send_abort_packet(call);
  	return -EPROTO;
17926a793   David Howells   [AF_RXRPC]: Provi...
562
563
564
  }
  
  /*
248f219cb   David Howells   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   David Howells   [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   David Howells   rxrpc: Keep the s...
616
  	struct rxrpc_wire_header whdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
617
618
619
  	struct msghdr msg;
  	struct kvec iov[2];
  	size_t len;
0d12f8a40   David Howells   rxrpc: Keep the s...
620
  	u32 serial;
17926a793   David Howells   [AF_RXRPC]: Provi...
621
  	int ret;
063c60d39   David Howells   rxrpc: Fix missin...
622
  	_enter("{%d,%x}", conn->debug_id, key_serial(conn->server_key));
17926a793   David Howells   [AF_RXRPC]: Provi...
623

063c60d39   David Howells   rxrpc: Fix missin...
624
  	ret = key_validate(conn->server_key);
17926a793   David Howells   [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   David Howells   rxrpc: Fix IPv6 s...
634
635
  	msg.msg_name	= &conn->params.peer->srx.transport;
  	msg.msg_namelen	= conn->params.peer->srx.transport_len;
17926a793   David Howells   [AF_RXRPC]: Provi...
636
637
638
  	msg.msg_control	= NULL;
  	msg.msg_controllen = 0;
  	msg.msg_flags	= 0;
19ffa01c9   David Howells   rxrpc: Use struct...
639
640
  	whdr.epoch	= htonl(conn->proto.epoch);
  	whdr.cid	= htonl(conn->proto.cid);
0d12f8a40   David Howells   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   David Howells   rxrpc: Separate t...
648
  	whdr.serviceId	= htons(conn->service_id);
0d12f8a40   David Howells   rxrpc: Keep the s...
649
650
651
  
  	iov[0].iov_base	= &whdr;
  	iov[0].iov_len	= sizeof(whdr);
17926a793   David Howells   [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   David Howells   rxrpc: Keep the s...
656
657
658
  	serial = atomic_inc_return(&conn->serial);
  	whdr.serial = htonl(serial);
  	_proto("Tx CHALLENGE %%%u", serial);
17926a793   David Howells   [AF_RXRPC]: Provi...
659

85f32278b   David Howells   rxrpc: Replace co...
660
  	ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
17926a793   David Howells   [AF_RXRPC]: Provi...
661
  	if (ret < 0) {
6b47fe1d1   David Howells   rxrpc: Trace UDP ...
662
  		trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
4764c0da6   David Howells   rxrpc: Trace pack...
663
  				    rxrpc_tx_point_rxkad_challenge);
17926a793   David Howells   [AF_RXRPC]: Provi...
664
665
  		return -EAGAIN;
  	}
330bdcfad   David Howells   rxrpc: Fix the ke...
666
  	conn->params.peer->last_tx_at = ktime_get_seconds();
4764c0da6   David Howells   rxrpc: Trace pack...
667
668
  	trace_rxrpc_tx_packet(conn->debug_id, &whdr,
  			      rxrpc_tx_point_rxkad_challenge);
17926a793   David Howells   [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   David Howells   rxrpc: Keep the s...
677
  			       struct rxrpc_host_header *hdr,
17926a793   David Howells   [AF_RXRPC]: Provi...
678
679
680
  			       struct rxkad_response *resp,
  			       const struct rxkad_key *s2)
  {
0d12f8a40   David Howells   rxrpc: Keep the s...
681
  	struct rxrpc_wire_header whdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
682
683
684
  	struct msghdr msg;
  	struct kvec iov[3];
  	size_t len;
0d12f8a40   David Howells   rxrpc: Keep the s...
685
  	u32 serial;
17926a793   David Howells   [AF_RXRPC]: Provi...
686
687
688
  	int ret;
  
  	_enter("");
7b674e390   David Howells   rxrpc: Fix IPv6 s...
689
690
  	msg.msg_name	= &conn->params.peer->srx.transport;
  	msg.msg_namelen	= conn->params.peer->srx.transport_len;
17926a793   David Howells   [AF_RXRPC]: Provi...
691
692
693
  	msg.msg_control	= NULL;
  	msg.msg_controllen = 0;
  	msg.msg_flags	= 0;
0d12f8a40   David Howells   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   David Howells   [AF_RXRPC]: Provi...
701

0d12f8a40   David Howells   rxrpc: Keep the s...
702
703
  	iov[0].iov_base	= &whdr;
  	iov[0].iov_len	= sizeof(whdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
704
705
  	iov[1].iov_base	= resp;
  	iov[1].iov_len	= sizeof(*resp);
0d12f8a40   David Howells   rxrpc: Keep the s...
706
  	iov[2].iov_base	= (void *)s2->ticket;
17926a793   David Howells   [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   David Howells   rxrpc: Keep the s...
710
711
712
  	serial = atomic_inc_return(&conn->serial);
  	whdr.serial = htonl(serial);
  	_proto("Tx RESPONSE %%%u", serial);
17926a793   David Howells   [AF_RXRPC]: Provi...
713

85f32278b   David Howells   rxrpc: Replace co...
714
  	ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len);
17926a793   David Howells   [AF_RXRPC]: Provi...
715
  	if (ret < 0) {
6b47fe1d1   David Howells   rxrpc: Trace UDP ...
716
  		trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
4764c0da6   David Howells   rxrpc: Trace pack...
717
  				    rxrpc_tx_point_rxkad_response);
17926a793   David Howells   [AF_RXRPC]: Provi...
718
719
  		return -EAGAIN;
  	}
330bdcfad   David Howells   rxrpc: Fix the ke...
720
  	conn->params.peer->last_tx_at = ktime_get_seconds();
17926a793   David Howells   [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   David Howells   [AF_RXRPC]: Provi...
741
742
   * encrypt the response packet
   */
1db88c534   David Howells   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   David Howells   [AF_RXRPC]: Provi...
746
  {
1db88c534   David Howells   rxrpc: Fix -Wfram...
747
  	struct skcipher_request *req;
17926a793   David Howells   [AF_RXRPC]: Provi...
748
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
749
  	struct scatterlist sg[1];
17926a793   David Howells   [AF_RXRPC]: Provi...
750

1db88c534   David Howells   rxrpc: Fix -Wfram...
751
752
753
  	req = skcipher_request_alloc(&conn->cipher->base, GFP_NOFS);
  	if (!req)
  		return -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
754
755
  	/* continue encrypting from where we left off */
  	memcpy(&iv, s2->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
756

a263629da   Herbert Xu   rxrpc: Avoid usin...
757
758
  	sg_init_table(sg, 1);
  	sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted));
69d826fa5   Kees Cook   rxrpc: Remove VLA...
759
  	skcipher_request_set_sync_tfm(req, conn->cipher);
1afe593b4   Herbert Xu   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   Herbert Xu   rxrpc: Use skcipher
762
  	crypto_skcipher_encrypt(req);
1db88c534   David Howells   rxrpc: Fix -Wfram...
763
764
  	skcipher_request_free(req);
  	return 0;
17926a793   David Howells   [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   David Howells   RxRPC: Allow key ...
774
  	const struct rxrpc_key_token *token;
17926a793   David Howells   [AF_RXRPC]: Provi...
775
  	struct rxkad_challenge challenge;
8c2f826dc   David Howells   rxrpc: Don't put ...
776
  	struct rxkad_response *resp;
248f219cb   David Howells   rxrpc: Rewrite th...
777
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
fb46f6ee1   David Howells   rxrpc: Trace prot...
778
  	const char *eproto;
17926a793   David Howells   [AF_RXRPC]: Provi...
779
780
  	u32 version, nonce, min_level, abort_code;
  	int ret;
19ffa01c9   David Howells   rxrpc: Use struct...
781
  	_enter("{%d,%x}", conn->debug_id, key_serial(conn->params.key));
17926a793   David Howells   [AF_RXRPC]: Provi...
782

fb46f6ee1   David Howells   rxrpc: Trace prot...
783
  	eproto = tracepoint_string("chall_no_key");
ef68622da   David Howells   rxrpc: Handle tem...
784
785
786
  	abort_code = RX_PROTOCOL_ERROR;
  	if (!conn->params.key)
  		goto protocol_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
787

ef68622da   David Howells   rxrpc: Handle tem...
788
  	abort_code = RXKADEXPIRED;
19ffa01c9   David Howells   rxrpc: Use struct...
789
  	ret = key_validate(conn->params.key);
ef68622da   David Howells   rxrpc: Handle tem...
790
791
  	if (ret < 0)
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
792

fb46f6ee1   David Howells   rxrpc: Trace prot...
793
  	eproto = tracepoint_string("chall_short");
17926a793   David Howells   [AF_RXRPC]: Provi...
794
  	abort_code = RXKADPACKETSHORT;
775e5b71d   David Howells   rxrpc: The offset...
795
796
  	if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
  			  &challenge, sizeof(challenge)) < 0)
17926a793   David Howells   [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   David Howells   rxrpc: Keep the s...
804
  	       sp->hdr.serial, version, nonce, min_level);
17926a793   David Howells   [AF_RXRPC]: Provi...
805

fb46f6ee1   David Howells   rxrpc: Trace prot...
806
  	eproto = tracepoint_string("chall_ver");
17926a793   David Howells   [AF_RXRPC]: Provi...
807
808
809
810
811
  	abort_code = RXKADINCONSISTENCY;
  	if (version != RXKAD_VERSION)
  		goto protocol_error;
  
  	abort_code = RXKADLEVELFAIL;
ef68622da   David Howells   rxrpc: Handle tem...
812
  	ret = -EACCES;
19ffa01c9   David Howells   rxrpc: Use struct...
813
  	if (conn->params.security_level < min_level)
ef68622da   David Howells   rxrpc: Handle tem...
814
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
815

19ffa01c9   David Howells   rxrpc: Use struct...
816
  	token = conn->params.key->payload.data[0];
17926a793   David Howells   [AF_RXRPC]: Provi...
817
818
  
  	/* build the response packet */
8c2f826dc   David Howells   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   David Howells   [AF_RXRPC]: Provi...
835
836
  
  	/* calculate the response checksum and then do the encryption */
8c2f826dc   David Howells   rxrpc: Don't put ...
837
  	rxkad_calc_response_checksum(resp);
1db88c534   David Howells   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   David Howells   rxrpc: Don't put ...
841
842
  	kfree(resp);
  	return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
843
844
  
  protocol_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
845
  	trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
ef68622da   David Howells   rxrpc: Handle tem...
846
847
  	ret = -EPROTO;
  other_error:
17926a793   David Howells   [AF_RXRPC]: Provi...
848
  	*_abort_code = abort_code;
ef68622da   David Howells   rxrpc: Handle tem...
849
  	return ret;
17926a793   David Howells   [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   David Howells   rxrpc: Trace prot...
856
  				struct sk_buff *skb,
17926a793   David Howells   [AF_RXRPC]: Provi...
857
858
  				void *ticket, size_t ticket_len,
  				struct rxrpc_crypt *_session_key,
10674a03c   Baolin Wang   net: rxrpc: Repla...
859
  				time64_t *_expiry,
17926a793   David Howells   [AF_RXRPC]: Provi...
860
861
  				u32 *_abort_code)
  {
1afe593b4   Herbert Xu   rxrpc: Use skcipher
862
  	struct skcipher_request *req;
fb46f6ee1   David Howells   rxrpc: Trace prot...
863
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
17926a793   David Howells   [AF_RXRPC]: Provi...
864
  	struct rxrpc_crypt iv, key;
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
865
  	struct scatterlist sg[1];
17926a793   David Howells   [AF_RXRPC]: Provi...
866
  	struct in_addr addr;
95c961747   Eric Dumazet   net: cleanup unsi...
867
  	unsigned int life;
fb46f6ee1   David Howells   rxrpc: Trace prot...
868
  	const char *eproto;
10674a03c   Baolin Wang   net: rxrpc: Repla...
869
  	time64_t issue, now;
17926a793   David Howells   [AF_RXRPC]: Provi...
870
871
  	bool little_endian;
  	int ret;
fb46f6ee1   David Howells   rxrpc: Trace prot...
872
  	u32 abort_code;
17926a793   David Howells   [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   David Howells   rxrpc: Trace prot...
883
  			abort_code = RXKADEXPIRED;
ef68622da   David Howells   rxrpc: Handle tem...
884
  			goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
885
  		default:
fb46f6ee1   David Howells   rxrpc: Trace prot...
886
  			abort_code = RXKADNOAUTH;
ef68622da   David Howells   rxrpc: Handle tem...
887
  			goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
888
889
  		}
  	}
146aa8b14   David Howells   KEYS: Merge the t...
890
  	ASSERT(conn->server_key->payload.data[0] != NULL);
17926a793   David Howells   [AF_RXRPC]: Provi...
891
  	ASSERTCMP((unsigned long) ticket & 7UL, ==, 0);
146aa8b14   David Howells   KEYS: Merge the t...
892
  	memcpy(&iv, &conn->server_key->payload.data[2], sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
893

ef68622da   David Howells   rxrpc: Handle tem...
894
  	ret = -ENOMEM;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
895
896
  	req = skcipher_request_alloc(conn->server_key->payload.data[0],
  				     GFP_NOFS);
ef68622da   David Howells   rxrpc: Handle tem...
897
898
  	if (!req)
  		goto temporary_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
899

68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
900
  	sg_init_one(&sg[0], ticket, ticket_len);
1afe593b4   Herbert Xu   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   Herbert Xu   rxrpc: Use skcipher
903
904
  	crypto_skcipher_decrypt(req);
  	skcipher_request_free(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
905
906
907
  
  	p = ticket;
  	end = p + ticket_len;
fb46f6ee1   David Howells   rxrpc: Trace prot...
908
  #define Z(field)					\
17926a793   David Howells   [AF_RXRPC]: Provi...
909
910
  	({						\
  		u8 *__str = p;				\
fb46f6ee1   David Howells   rxrpc: Trace prot...
911
  		eproto = tracepoint_string("rxkad_bad_"#field); \
17926a793   David Howells   [AF_RXRPC]: Provi...
912
  		q = memchr(p, 0, end - p);		\
fb46f6ee1   David Howells   rxrpc: Trace prot...
913
  		if (!q || q - p > (field##_SZ))		\
17926a793   David Howells   [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   David Howells   rxrpc: Trace prot...
928
  	name = Z(ANAME);
17926a793   David Howells   [AF_RXRPC]: Provi...
929
930
931
  	_debug("KIV ANAME: %s", name);
  
  	/* extract the principal's instance */
fb46f6ee1   David Howells   rxrpc: Trace prot...
932
  	name = Z(INST);
17926a793   David Howells   [AF_RXRPC]: Provi...
933
934
935
  	_debug("KIV INST : %s", name);
  
  	/* extract the principal's authentication domain */
fb46f6ee1   David Howells   rxrpc: Trace prot...
936
  	name = Z(REALM);
17926a793   David Howells   [AF_RXRPC]: Provi...
937
  	_debug("KIV REALM: %s", name);
fb46f6ee1   David Howells   rxrpc: Trace prot...
938
  	eproto = tracepoint_string("rxkad_bad_len");
17926a793   David Howells   [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   Harvey Harrison   net: replace NIPQ...
945
  	_debug("KIV ADDR : %pI4", &addr);
17926a793   David Howells   [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   Baolin Wang   net: rxrpc: Repla...
961
  		issue = rxrpc_u32_to_time64(le32_to_cpu(stamp));
17926a793   David Howells   [AF_RXRPC]: Provi...
962
963
964
  	} else {
  		__be32 stamp;
  		memcpy(&stamp, p, 4);
10674a03c   Baolin Wang   net: rxrpc: Repla...
965
  		issue = rxrpc_u32_to_time64(be32_to_cpu(stamp));
17926a793   David Howells   [AF_RXRPC]: Provi...
966
967
  	}
  	p += 4;
10674a03c   Baolin Wang   net: rxrpc: Repla...
968
969
  	now = ktime_get_real_seconds();
  	_debug("KIV ISSUE: %llx [%llx]", issue, now);
17926a793   David Howells   [AF_RXRPC]: Provi...
970
971
972
  
  	/* check the ticket is in date */
  	if (issue > now) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
973
  		abort_code = RXKADNOAUTH;
17926a793   David Howells   [AF_RXRPC]: Provi...
974
  		ret = -EKEYREJECTED;
ef68622da   David Howells   rxrpc: Handle tem...
975
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
976
977
978
  	}
  
  	if (issue < now - life) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
979
  		abort_code = RXKADEXPIRED;
17926a793   David Howells   [AF_RXRPC]: Provi...
980
  		ret = -EKEYEXPIRED;
ef68622da   David Howells   rxrpc: Handle tem...
981
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
982
983
984
985
986
  	}
  
  	*_expiry = issue + life;
  
  	/* get the service name */
fb46f6ee1   David Howells   rxrpc: Trace prot...
987
  	name = Z(SNAME);
17926a793   David Howells   [AF_RXRPC]: Provi...
988
989
990
  	_debug("KIV SNAME: %s", name);
  
  	/* get the service instance name */
fb46f6ee1   David Howells   rxrpc: Trace prot...
991
  	name = Z(INST);
17926a793   David Howells   [AF_RXRPC]: Provi...
992
  	_debug("KIV SINST: %s", name);
ef68622da   David Howells   rxrpc: Handle tem...
993
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
994
995
  
  bad_ticket:
fb46f6ee1   David Howells   rxrpc: Trace prot...
996
997
  	trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
  	abort_code = RXKADBADTICKET;
ef68622da   David Howells   rxrpc: Handle tem...
998
999
  	ret = -EPROTO;
  other_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
1000
  	*_abort_code = abort_code;
ef68622da   David Howells   rxrpc: Handle tem...
1001
1002
1003
  	return ret;
  temporary_error:
  	return ret;
17926a793   David Howells   [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   David Howells   rxrpc: Fix -Wfram...
1013
  	struct skcipher_request *req = rxkad_ci_req;
a263629da   Herbert Xu   rxrpc: Avoid usin...
1014
  	struct scatterlist sg[1];
17926a793   David Howells   [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   David Howells   [AF_RXRPC]: Provi...
1019
  	mutex_lock(&rxkad_ci_mutex);
69d826fa5   Kees Cook   rxrpc: Remove VLA...
1020
  	if (crypto_sync_skcipher_setkey(rxkad_ci, session_key->x,
1db88c534   David Howells   rxrpc: Fix -Wfram...
1021
  					sizeof(*session_key)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
1022
1023
1024
  		BUG();
  
  	memcpy(&iv, session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
1025

a263629da   Herbert Xu   rxrpc: Avoid usin...
1026
1027
  	sg_init_table(sg, 1);
  	sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted));
69d826fa5   Kees Cook   rxrpc: Remove VLA...
1028
  	skcipher_request_set_sync_tfm(req, rxkad_ci);
1afe593b4   Herbert Xu   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   Herbert Xu   rxrpc: Use skcipher
1031
1032
  	crypto_skcipher_decrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [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   David Howells   rxrpc: Don't put ...
1045
  	struct rxkad_response *response;
248f219cb   David Howells   rxrpc: Rewrite th...
1046
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
17926a793   David Howells   [AF_RXRPC]: Provi...
1047
  	struct rxrpc_crypt session_key;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1048
  	const char *eproto;
10674a03c   Baolin Wang   net: rxrpc: Repla...
1049
  	time64_t expiry;
17926a793   David Howells   [AF_RXRPC]: Provi...
1050
  	void *ticket;
91e916cff   Al Viro   net/rxrpc trivial...
1051
1052
  	u32 abort_code, version, kvno, ticket_len, level;
  	__be32 csum;
a1399f8bb   David Howells   rxrpc: Call chann...
1053
  	int ret, i;
17926a793   David Howells   [AF_RXRPC]: Provi...
1054
1055
  
  	_enter("{%d,%x}", conn->debug_id, key_serial(conn->server_key));
8c2f826dc   David Howells   rxrpc: Don't put ...
1056
1057
1058
1059
  	ret = -ENOMEM;
  	response = kzalloc(sizeof(struct rxkad_response), GFP_NOFS);
  	if (!response)
  		goto temporary_error;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1060
  	eproto = tracepoint_string("rxkad_rsp_short");
17926a793   David Howells   [AF_RXRPC]: Provi...
1061
  	abort_code = RXKADPACKETSHORT;
775e5b71d   David Howells   rxrpc: The offset...
1062
  	if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
8c2f826dc   David Howells   rxrpc: Don't put ...
1063
  			  response, sizeof(*response)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
1064
  		goto protocol_error;
8c2f826dc   David Howells   rxrpc: Don't put ...
1065
  	if (!pskb_pull(skb, sizeof(*response)))
17926a793   David Howells   [AF_RXRPC]: Provi...
1066
  		BUG();
8c2f826dc   David Howells   rxrpc: Don't put ...
1067
1068
1069
  	version = ntohl(response->version);
  	ticket_len = ntohl(response->ticket_len);
  	kvno = ntohl(response->kvno);
17926a793   David Howells   [AF_RXRPC]: Provi...
1070
  	_proto("Rx RESPONSE %%%u { v=%u kv=%u tl=%u }",
0d12f8a40   David Howells   rxrpc: Keep the s...
1071
  	       sp->hdr.serial, version, kvno, ticket_len);
17926a793   David Howells   [AF_RXRPC]: Provi...
1072

fb46f6ee1   David Howells   rxrpc: Trace prot...
1073
  	eproto = tracepoint_string("rxkad_rsp_ver");
17926a793   David Howells   [AF_RXRPC]: Provi...
1074
1075
  	abort_code = RXKADINCONSISTENCY;
  	if (version != RXKAD_VERSION)
4aa9cb320   David Howells   [AF_RXRPC]: Add a...
1076
  		goto protocol_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
1077

fb46f6ee1   David Howells   rxrpc: Trace prot...
1078
  	eproto = tracepoint_string("rxkad_rsp_tktlen");
17926a793   David Howells   [AF_RXRPC]: Provi...
1079
1080
1081
  	abort_code = RXKADTICKETLEN;
  	if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN)
  		goto protocol_error;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1082
  	eproto = tracepoint_string("rxkad_rsp_unkkey");
17926a793   David Howells   [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   David Howells   rxrpc: Handle tem...
1088
  	ret = -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
1089
1090
  	ticket = kmalloc(ticket_len, GFP_NOFS);
  	if (!ticket)
b43c75abf   Dinghao Liu   rxrpc: Fix memory...
1091
  		goto temporary_error_free_resp;
17926a793   David Howells   [AF_RXRPC]: Provi...
1092

fb46f6ee1   David Howells   rxrpc: Trace prot...
1093
  	eproto = tracepoint_string("rxkad_tkt_short");
17926a793   David Howells   [AF_RXRPC]: Provi...
1094
  	abort_code = RXKADPACKETSHORT;
775e5b71d   David Howells   rxrpc: The offset...
1095
1096
  	if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
  			  ticket, ticket_len) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
1097
  		goto protocol_error_free;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1098
  	ret = rxkad_decrypt_ticket(conn, skb, ticket, ticket_len, &session_key,
ef68622da   David Howells   rxrpc: Handle tem...
1099
1100
  				   &expiry, _abort_code);
  	if (ret < 0)
f45d01f4f   Qiushi Wu   rxrpc: Fix a memo...
1101
  		goto temporary_error_free_ticket;
17926a793   David Howells   [AF_RXRPC]: Provi...
1102
1103
1104
  
  	/* use the session key from inside the ticket to decrypt the
  	 * response */
8c2f826dc   David Howells   rxrpc: Don't put ...
1105
  	rxkad_decrypt_response(conn, response, &session_key);
17926a793   David Howells   [AF_RXRPC]: Provi...
1106

fb46f6ee1   David Howells   rxrpc: Trace prot...
1107
  	eproto = tracepoint_string("rxkad_rsp_param");
17926a793   David Howells   [AF_RXRPC]: Provi...
1108
  	abort_code = RXKADSEALEDINCON;
8c2f826dc   David Howells   rxrpc: Don't put ...
1109
  	if (ntohl(response->encrypted.epoch) != conn->proto.epoch)
17926a793   David Howells   [AF_RXRPC]: Provi...
1110
  		goto protocol_error_free;
8c2f826dc   David Howells   rxrpc: Don't put ...
1111
  	if (ntohl(response->encrypted.cid) != conn->proto.cid)
17926a793   David Howells   [AF_RXRPC]: Provi...
1112
  		goto protocol_error_free;
8c2f826dc   David Howells   rxrpc: Don't put ...
1113
  	if (ntohl(response->encrypted.securityIndex) != conn->security_ix)
17926a793   David Howells   [AF_RXRPC]: Provi...
1114
  		goto protocol_error_free;
8c2f826dc   David Howells   rxrpc: Don't put ...
1115
1116
1117
  	csum = response->encrypted.checksum;
  	response->encrypted.checksum = 0;
  	rxkad_calc_response_checksum(response);
fb46f6ee1   David Howells   rxrpc: Trace prot...
1118
  	eproto = tracepoint_string("rxkad_rsp_csum");
8c2f826dc   David Howells   rxrpc: Don't put ...
1119
  	if (response->encrypted.checksum != csum)
17926a793   David Howells   [AF_RXRPC]: Provi...
1120
  		goto protocol_error_free;
245500d85   David Howells   rxrpc: Rewrite th...
1121
  	spin_lock(&conn->bundle->channel_lock);
a1399f8bb   David Howells   rxrpc: Call chann...
1122
1123
  	for (i = 0; i < RXRPC_MAXCALLS; i++) {
  		struct rxrpc_call *call;
8c2f826dc   David Howells   rxrpc: Don't put ...
1124
  		u32 call_id = ntohl(response->encrypted.call_id[i]);
a1399f8bb   David Howells   rxrpc: Call chann...
1125

fb46f6ee1   David Howells   rxrpc: Trace prot...
1126
  		eproto = tracepoint_string("rxkad_rsp_callid");
a1399f8bb   David Howells   rxrpc: Call chann...
1127
1128
  		if (call_id > INT_MAX)
  			goto protocol_error_unlock;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1129
  		eproto = tracepoint_string("rxkad_rsp_callctr");
a1399f8bb   David Howells   rxrpc: Call chann...
1130
1131
  		if (call_id < conn->channels[i].call_counter)
  			goto protocol_error_unlock;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1132
1133
  
  		eproto = tracepoint_string("rxkad_rsp_callst");
a1399f8bb   David Howells   rxrpc: Call chann...
1134
1135
1136
  		if (call_id > conn->channels[i].call_counter) {
  			call = rcu_dereference_protected(
  				conn->channels[i].call,
245500d85   David Howells   rxrpc: Rewrite th...
1137
  				lockdep_is_held(&conn->bundle->channel_lock));
a1399f8bb   David Howells   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   David Howells   rxrpc: Rewrite th...
1143
  	spin_unlock(&conn->bundle->channel_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
1144

fb46f6ee1   David Howells   rxrpc: Trace prot...
1145
  	eproto = tracepoint_string("rxkad_rsp_seq");
17926a793   David Howells   [AF_RXRPC]: Provi...
1146
  	abort_code = RXKADOUTOFSEQUENCE;
8c2f826dc   David Howells   rxrpc: Don't put ...
1147
  	if (ntohl(response->encrypted.inc_nonce) != conn->security_nonce + 1)
17926a793   David Howells   [AF_RXRPC]: Provi...
1148
  		goto protocol_error_free;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1149
  	eproto = tracepoint_string("rxkad_rsp_level");
17926a793   David Howells   [AF_RXRPC]: Provi...
1150
  	abort_code = RXKADLEVELFAIL;
8c2f826dc   David Howells   rxrpc: Don't put ...
1151
  	level = ntohl(response->encrypted.level);
17926a793   David Howells   [AF_RXRPC]: Provi...
1152
1153
  	if (level > RXRPC_SECURITY_ENCRYPT)
  		goto protocol_error_free;
19ffa01c9   David Howells   rxrpc: Use struct...
1154
  	conn->params.security_level = level;
17926a793   David Howells   [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   David Howells   rxrpc: Handle tem...
1160
  	if (ret < 0)
8c2f826dc   David Howells   rxrpc: Don't put ...
1161
  		goto temporary_error_free_ticket;
17926a793   David Howells   [AF_RXRPC]: Provi...
1162
1163
  
  	kfree(ticket);
8c2f826dc   David Howells   rxrpc: Don't put ...
1164
  	kfree(response);
17926a793   David Howells   [AF_RXRPC]: Provi...
1165
1166
  	_leave(" = 0");
  	return 0;
a1399f8bb   David Howells   rxrpc: Call chann...
1167
  protocol_error_unlock:
245500d85   David Howells   rxrpc: Rewrite th...
1168
  	spin_unlock(&conn->bundle->channel_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
1169
1170
1171
  protocol_error_free:
  	kfree(ticket);
  protocol_error:
8c2f826dc   David Howells   rxrpc: Don't put ...
1172
  	kfree(response);
fb46f6ee1   David Howells   rxrpc: Trace prot...
1173
  	trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
17926a793   David Howells   [AF_RXRPC]: Provi...
1174
  	*_abort_code = abort_code;
17926a793   David Howells   [AF_RXRPC]: Provi...
1175
  	return -EPROTO;
ef68622da   David Howells   rxrpc: Handle tem...
1176

8c2f826dc   David Howells   rxrpc: Don't put ...
1177
  temporary_error_free_ticket:
ef68622da   David Howells   rxrpc: Handle tem...
1178
  	kfree(ticket);
b43c75abf   Dinghao Liu   rxrpc: Fix memory...
1179
  temporary_error_free_resp:
8c2f826dc   David Howells   rxrpc: Don't put ...
1180
  	kfree(response);
ef68622da   David Howells   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   David Howells   [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   Kees Cook   rxrpc: Remove VLA...
1197
  		crypto_free_sync_skcipher(conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
1198
1199
1200
  }
  
  /*
648af7fca   David Howells   rxrpc: Absorb the...
1201
1202
1203
1204
   * Initialise the rxkad security service.
   */
  static int rxkad_init(void)
  {
1db88c534   David Howells   rxrpc: Fix -Wfram...
1205
1206
  	struct crypto_sync_skcipher *tfm;
  	struct skcipher_request *req;
648af7fca   David Howells   rxrpc: Absorb the...
1207
1208
  	/* pin the cipher we need so that the crypto layer doesn't invoke
  	 * keventd to go get it */
1db88c534   David Howells   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   David Howells   rxrpc: Absorb the...
1224
1225
1226
1227
1228
1229
1230
  }
  
  /*
   * Clean up the rxkad security service.
   */
  static void rxkad_exit(void)
  {
1db88c534   David Howells   rxrpc: Fix -Wfram...
1231
1232
  	crypto_free_sync_skcipher(rxkad_ci);
  	skcipher_request_free(rxkad_ci_req);
648af7fca   David Howells   rxrpc: Absorb the...
1233
1234
1235
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
1236
1237
   * RxRPC Kerberos-based security
   */
648af7fca   David Howells   rxrpc: Absorb the...
1238
  const struct rxrpc_security rxkad = {
17926a793   David Howells   [AF_RXRPC]: Provi...
1239
  	.name				= "rxkad",
8b815477f   David Howells   RxRPC: Declare th...
1240
  	.security_index			= RXRPC_SECURITY_RXKAD,
063c60d39   David Howells   rxrpc: Fix missin...
1241
  	.no_key_abort			= RXKADUNKNOWNKEY,
648af7fca   David Howells   rxrpc: Absorb the...
1242
1243
  	.init				= rxkad_init,
  	.exit				= rxkad_exit,
17926a793   David Howells   [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   David Howells   rxrpc: Fix -Wfram...
1248
  	.free_call_crypto		= rxkad_free_call_crypto,
248f219cb   David Howells   rxrpc: Rewrite th...
1249
  	.locate_data			= rxkad_locate_data,
17926a793   David Howells   [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,
  };