Blame view

net/rxrpc/rxkad.c 31.3 KB
17926a793   David Howells   [AF_RXRPC]: Provi...
1
2
3
4
5
6
7
8
9
10
  /* Kerberos-based RxRPC security
   *
   * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   * Written by David Howells (dhowells@redhat.com)
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version
   * 2 of the License, or (at your option) any later version.
   */
9b6d53985   Joe Perches   rxrpc: Use pr_<le...
11
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1afe593b4   Herbert Xu   rxrpc: Use skcipher
12
  #include <crypto/skcipher.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
13
14
15
16
  #include <linux/module.h>
  #include <linux/net.h>
  #include <linux/skbuff.h>
  #include <linux/udp.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
17
18
  #include <linux/scatterlist.h>
  #include <linux/ctype.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
19
  #include <linux/slab.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
20
21
  #include <net/sock.h>
  #include <net/af_rxrpc.h>
339412841   David Howells   RxRPC: Allow key ...
22
  #include <keys/rxrpc-type.h>
17926a793   David Howells   [AF_RXRPC]: Provi...
23
24
25
26
27
28
29
30
31
  #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...
32
33
34
35
36
37
38
39
  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...
40
41
42
43
44
  /*
   * 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
   */
1afe593b4   Herbert Xu   rxrpc: Use skcipher
45
  static struct crypto_skcipher *rxkad_ci;
17926a793   David Howells   [AF_RXRPC]: Provi...
46
47
48
49
50
51
52
  static DEFINE_MUTEX(rxkad_ci_mutex);
  
  /*
   * initialise connection security
   */
  static int rxkad_init_connection_security(struct rxrpc_connection *conn)
  {
1afe593b4   Herbert Xu   rxrpc: Use skcipher
53
  	struct crypto_skcipher *ci;
339412841   David Howells   RxRPC: Allow key ...
54
  	struct rxrpc_key_token *token;
17926a793   David Howells   [AF_RXRPC]: Provi...
55
  	int ret;
19ffa01c9   David Howells   rxrpc: Use struct...
56
  	_enter("{%d},{%x}", conn->debug_id, key_serial(conn->params.key));
17926a793   David Howells   [AF_RXRPC]: Provi...
57

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

1afe593b4   Herbert Xu   rxrpc: Use skcipher
61
  	ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
17926a793   David Howells   [AF_RXRPC]: Provi...
62
63
64
65
66
  	if (IS_ERR(ci)) {
  		_debug("no cipher");
  		ret = PTR_ERR(ci);
  		goto error;
  	}
1afe593b4   Herbert Xu   rxrpc: Use skcipher
67
68
  	if (crypto_skcipher_setkey(ci, token->kad->session_key,
  				   sizeof(token->kad->session_key)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
69
  		BUG();
19ffa01c9   David Howells   rxrpc: Use struct...
70
  	switch (conn->params.security_level) {
17926a793   David Howells   [AF_RXRPC]: Provi...
71
72
73
74
75
  	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...
76
77
78
79
  		break;
  	case RXRPC_SECURITY_ENCRYPT:
  		conn->size_align = 8;
  		conn->security_size = sizeof(struct rxkad_level2_hdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  		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...
97
  static int rxkad_prime_packet_security(struct rxrpc_connection *conn)
17926a793   David Howells   [AF_RXRPC]: Provi...
98
  {
339412841   David Howells   RxRPC: Allow key ...
99
  	struct rxrpc_key_token *token;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
100
  	SKCIPHER_REQUEST_ON_STACK(req, conn->cipher);
a263629da   Herbert Xu   rxrpc: Avoid usin...
101
  	struct scatterlist sg;
17926a793   David Howells   [AF_RXRPC]: Provi...
102
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
103
104
  	__be32 *tmpbuf;
  	size_t tmpsize = 4 * sizeof(__be32);
17926a793   David Howells   [AF_RXRPC]: Provi...
105
106
  
  	_enter("");
19ffa01c9   David Howells   rxrpc: Use struct...
107
  	if (!conn->params.key)
a263629da   Herbert Xu   rxrpc: Avoid usin...
108
109
110
111
112
  		return 0;
  
  	tmpbuf = kmalloc(tmpsize, GFP_KERNEL);
  	if (!tmpbuf)
  		return -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
113

19ffa01c9   David Howells   rxrpc: Use struct...
114
  	token = conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
115
  	memcpy(&iv, token->kad->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
116

a263629da   Herbert Xu   rxrpc: Avoid usin...
117
118
119
120
  	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
121

a263629da   Herbert Xu   rxrpc: Avoid usin...
122
  	sg_init_one(&sg, tmpbuf, tmpsize);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
123
124
  	skcipher_request_set_tfm(req, conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
125
  	skcipher_request_set_crypt(req, &sg, &sg, tmpsize, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
126
127
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
128

a263629da   Herbert Xu   rxrpc: Avoid usin...
129
130
131
132
  	memcpy(&conn->csum_iv, tmpbuf + 2, sizeof(conn->csum_iv));
  	kfree(tmpbuf);
  	_leave(" = 0");
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
133
134
135
136
137
138
139
140
141
142
  }
  
  /*
   * 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,
  				    void *sechdr)
  {
fb46f6ee1   David Howells   rxrpc: Trace prot...
143
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
144
  	SKCIPHER_REQUEST_ON_STACK(req, call->conn->cipher);
a263629da   Herbert Xu   rxrpc: Avoid usin...
145
  	struct rxkad_level1_hdr hdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
146
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
147
  	struct scatterlist sg;
17926a793   David Howells   [AF_RXRPC]: Provi...
148
  	u16 check;
17926a793   David Howells   [AF_RXRPC]: Provi...
149
  	_enter("");
5a924b895   David Howells   rxrpc: Don't stor...
150
  	check = sp->hdr.seq ^ call->call_id;
0d12f8a40   David Howells   rxrpc: Keep the s...
151
  	data_size |= (u32)check << 16;
17926a793   David Howells   [AF_RXRPC]: Provi...
152

a263629da   Herbert Xu   rxrpc: Avoid usin...
153
154
  	hdr.data_size = htonl(data_size);
  	memcpy(sechdr, &hdr, sizeof(hdr));
17926a793   David Howells   [AF_RXRPC]: Provi...
155
156
157
  
  	/* start the encryption afresh */
  	memset(&iv, 0, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
158

a263629da   Herbert Xu   rxrpc: Avoid usin...
159
  	sg_init_one(&sg, sechdr, 8);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
160
161
  	skcipher_request_set_tfm(req, call->conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
162
  	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
163
164
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
165

17926a793   David Howells   [AF_RXRPC]: Provi...
166
167
168
169
170
171
172
173
  	_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...
174
175
176
  				       struct sk_buff *skb,
  				       u32 data_size,
  				       void *sechdr)
17926a793   David Howells   [AF_RXRPC]: Provi...
177
  {
339412841   David Howells   RxRPC: Allow key ...
178
  	const struct rxrpc_key_token *token;
a263629da   Herbert Xu   rxrpc: Avoid usin...
179
  	struct rxkad_level2_hdr rxkhdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
180
  	struct rxrpc_skb_priv *sp;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
181
  	SKCIPHER_REQUEST_ON_STACK(req, call->conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
182
183
184
  	struct rxrpc_crypt iv;
  	struct scatterlist sg[16];
  	struct sk_buff *trailer;
95c961747   Eric Dumazet   net: cleanup unsi...
185
  	unsigned int len;
17926a793   David Howells   [AF_RXRPC]: Provi...
186
187
  	u16 check;
  	int nsg;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
188
  	int err;
17926a793   David Howells   [AF_RXRPC]: Provi...
189
190
191
192
  
  	sp = rxrpc_skb(skb);
  
  	_enter("");
5a924b895   David Howells   rxrpc: Don't stor...
193
  	check = sp->hdr.seq ^ call->call_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
194

0d12f8a40   David Howells   rxrpc: Keep the s...
195
  	rxkhdr.data_size = htonl(data_size | (u32)check << 16);
17926a793   David Howells   [AF_RXRPC]: Provi...
196
  	rxkhdr.checksum = 0;
a263629da   Herbert Xu   rxrpc: Avoid usin...
197
  	memcpy(sechdr, &rxkhdr, sizeof(rxkhdr));
17926a793   David Howells   [AF_RXRPC]: Provi...
198
199
  
  	/* encrypt from the session key */
19ffa01c9   David Howells   rxrpc: Use struct...
200
  	token = call->conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
201
  	memcpy(&iv, token->kad->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
202

68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
203
  	sg_init_one(&sg[0], sechdr, sizeof(rxkhdr));
1afe593b4   Herbert Xu   rxrpc: Use skcipher
204
205
  	skcipher_request_set_tfm(req, call->conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
206
  	skcipher_request_set_crypt(req, &sg[0], &sg[0], sizeof(rxkhdr), iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
207
  	crypto_skcipher_encrypt(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
208
209
210
  
  	/* we want to encrypt the skbuff in-place */
  	nsg = skb_cow_data(skb, 0, &trailer);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
211
  	err = -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
212
  	if (nsg < 0 || nsg > 16)
1afe593b4   Herbert Xu   rxrpc: Use skcipher
213
  		goto out;
17926a793   David Howells   [AF_RXRPC]: Provi...
214
215
216
  
  	len = data_size + call->conn->size_align - 1;
  	len &= ~(call->conn->size_align - 1);
51c739d1f   David S. Miller   [NET]: Fix incorr...
217
  	sg_init_table(sg, nsg);
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
218
219
220
  	err = skb_to_sgvec(skb, sg, 0, len);
  	if (unlikely(err < 0))
  		goto out;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
221
  	skcipher_request_set_crypt(req, sg, sg, len, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
222
  	crypto_skcipher_encrypt(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
223
224
  
  	_leave(" = 0");
1afe593b4   Herbert Xu   rxrpc: Use skcipher
225
226
227
228
229
  	err = 0;
  
  out:
  	skcipher_request_zero(req);
  	return err;
17926a793   David Howells   [AF_RXRPC]: Provi...
230
231
232
233
234
  }
  
  /*
   * checksum an RxRPC packet header
   */
a263629da   Herbert Xu   rxrpc: Avoid usin...
235
  static int rxkad_secure_packet(struct rxrpc_call *call,
b4f1342f9   David Howells   rxrpc: Adjust som...
236
237
238
  			       struct sk_buff *skb,
  			       size_t data_size,
  			       void *sechdr)
17926a793   David Howells   [AF_RXRPC]: Provi...
239
240
  {
  	struct rxrpc_skb_priv *sp;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
241
  	SKCIPHER_REQUEST_ON_STACK(req, call->conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
242
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
243
  	struct scatterlist sg;
0d12f8a40   David Howells   rxrpc: Keep the s...
244
  	u32 x, y;
17926a793   David Howells   [AF_RXRPC]: Provi...
245
246
247
248
249
  	int ret;
  
  	sp = rxrpc_skb(skb);
  
  	_enter("{%d{%x}},{#%u},%zu,",
19ffa01c9   David Howells   rxrpc: Use struct...
250
251
  	       call->debug_id, key_serial(call->conn->params.key),
  	       sp->hdr.seq, data_size);
17926a793   David Howells   [AF_RXRPC]: Provi...
252
253
254
  
  	if (!call->conn->cipher)
  		return 0;
19ffa01c9   David Howells   rxrpc: Use struct...
255
  	ret = key_validate(call->conn->params.key);
17926a793   David Howells   [AF_RXRPC]: Provi...
256
257
258
259
260
  	if (ret < 0)
  		return ret;
  
  	/* continue encrypting from where we left off */
  	memcpy(&iv, call->conn->csum_iv.x, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
261
262
  
  	/* calculate the security checksum */
01a90a459   David Howells   rxrpc: Drop chann...
263
  	x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT);
0d12f8a40   David Howells   rxrpc: Keep the s...
264
  	x |= sp->hdr.seq & 0x3fffffff;
5a924b895   David Howells   rxrpc: Don't stor...
265
  	call->crypto_buf[0] = htonl(call->call_id);
a263629da   Herbert Xu   rxrpc: Avoid usin...
266
  	call->crypto_buf[1] = htonl(x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
267

a263629da   Herbert Xu   rxrpc: Avoid usin...
268
  	sg_init_one(&sg, call->crypto_buf, 8);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
269
270
  	skcipher_request_set_tfm(req, call->conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
271
  	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
272
273
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
274

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

19ffa01c9   David Howells   rxrpc: Use struct...
281
  	switch (call->conn->params.security_level) {
17926a793   David Howells   [AF_RXRPC]: Provi...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  	case RXRPC_SECURITY_PLAIN:
  		ret = 0;
  		break;
  	case RXRPC_SECURITY_AUTH:
  		ret = rxkad_secure_packet_auth(call, skb, data_size, sechdr);
  		break;
  	case RXRPC_SECURITY_ENCRYPT:
  		ret = rxkad_secure_packet_encrypt(call, skb, data_size,
  						  sechdr);
  		break;
  	default:
  		ret = -EPERM;
  		break;
  	}
91e916cff   Al Viro   net/rxrpc trivial...
296
  	_leave(" = %d [set %hx]", ret, y);
17926a793   David Howells   [AF_RXRPC]: Provi...
297
298
299
300
301
302
  	return ret;
  }
  
  /*
   * decrypt partial encryption on a packet (level 1 security)
   */
5a42976d4   David Howells   rxrpc: Add tracep...
303
  static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
248f219cb   David Howells   rxrpc: Rewrite th...
304
  				 unsigned int offset, unsigned int len,
5a42976d4   David Howells   rxrpc: Add tracep...
305
  				 rxrpc_seq_t seq)
17926a793   David Howells   [AF_RXRPC]: Provi...
306
307
  {
  	struct rxkad_level1_hdr sechdr;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
308
  	SKCIPHER_REQUEST_ON_STACK(req, call->conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
309
  	struct rxrpc_crypt iv;
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
310
  	struct scatterlist sg[16];
17926a793   David Howells   [AF_RXRPC]: Provi...
311
  	struct sk_buff *trailer;
fb46f6ee1   David Howells   rxrpc: Trace prot...
312
  	bool aborted;
17926a793   David Howells   [AF_RXRPC]: Provi...
313
314
  	u32 data_size, buf;
  	u16 check;
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
315
  	int nsg, ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
316
317
  
  	_enter("");
248f219cb   David Howells   rxrpc: Rewrite th...
318
  	if (len < 8) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
319
320
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_hdr", "V1H",
  					   RXKADSEALEDINCON);
5a42976d4   David Howells   rxrpc: Add tracep...
321
322
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
323

248f219cb   David Howells   rxrpc: Rewrite th...
324
325
326
  	/* Decrypt the skbuff in-place.  TODO: We really want to decrypt
  	 * directly into the target buffer.
  	 */
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
327
328
  	nsg = skb_cow_data(skb, 0, &trailer);
  	if (nsg < 0 || nsg > 16)
17926a793   David Howells   [AF_RXRPC]: Provi...
329
  		goto nomem;
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
330
  	sg_init_table(sg, nsg);
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
331
332
333
  	ret = skb_to_sgvec(skb, sg, offset, 8);
  	if (unlikely(ret < 0))
  		return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
334
335
336
  
  	/* start the decryption afresh */
  	memset(&iv, 0, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
337

1afe593b4   Herbert Xu   rxrpc: Use skcipher
338
339
340
  	skcipher_request_set_tfm(req, call->conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
  	skcipher_request_set_crypt(req, sg, sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
341
342
  	crypto_skcipher_decrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
343

5a42976d4   David Howells   rxrpc: Add tracep...
344
  	/* Extract the decrypted packet length */
248f219cb   David Howells   rxrpc: Rewrite th...
345
  	if (skb_copy_bits(skb, offset, &sechdr, sizeof(sechdr)) < 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
346
347
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_len", "XV1",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
348
349
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
350
351
  	offset += sizeof(sechdr);
  	len -= sizeof(sechdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
352
353
354
355
356
  
  	buf = ntohl(sechdr.data_size);
  	data_size = buf & 0xffff;
  
  	check = buf >> 16;
5a42976d4   David Howells   rxrpc: Add tracep...
357
  	check ^= seq ^ call->call_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
358
359
  	check &= 0xffff;
  	if (check != 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
360
361
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_check", "V1C",
  					     RXKADSEALEDINCON);
17926a793   David Howells   [AF_RXRPC]: Provi...
362
363
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
364
  	if (data_size > len) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
365
366
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_1_datalen", "V1L",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
367
368
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
369
370
371
  
  	_leave(" = 0 [dlen=%x]", data_size);
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
372
  protocol_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
373
374
  	if (aborted)
  		rxrpc_send_abort_packet(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
375
376
377
378
379
380
381
382
383
384
  	return -EPROTO;
  
  nomem:
  	_leave(" = -ENOMEM");
  	return -ENOMEM;
  }
  
  /*
   * wholly decrypt a packet (level 2 security)
   */
5a42976d4   David Howells   rxrpc: Add tracep...
385
  static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
248f219cb   David Howells   rxrpc: Rewrite th...
386
  				 unsigned int offset, unsigned int len,
5a42976d4   David Howells   rxrpc: Add tracep...
387
  				 rxrpc_seq_t seq)
17926a793   David Howells   [AF_RXRPC]: Provi...
388
  {
339412841   David Howells   RxRPC: Allow key ...
389
  	const struct rxrpc_key_token *token;
17926a793   David Howells   [AF_RXRPC]: Provi...
390
  	struct rxkad_level2_hdr sechdr;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
391
  	SKCIPHER_REQUEST_ON_STACK(req, call->conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
392
393
394
  	struct rxrpc_crypt iv;
  	struct scatterlist _sg[4], *sg;
  	struct sk_buff *trailer;
fb46f6ee1   David Howells   rxrpc: Trace prot...
395
  	bool aborted;
17926a793   David Howells   [AF_RXRPC]: Provi...
396
397
  	u32 data_size, buf;
  	u16 check;
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
398
  	int nsg, ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
399
400
  
  	_enter(",{%d}", skb->len);
248f219cb   David Howells   rxrpc: Rewrite th...
401
  	if (len < 8) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
402
403
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_hdr", "V2H",
  					     RXKADSEALEDINCON);
5a42976d4   David Howells   rxrpc: Add tracep...
404
405
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
406

248f219cb   David Howells   rxrpc: Rewrite th...
407
408
409
  	/* Decrypt the skbuff in-place.  TODO: We really want to decrypt
  	 * directly into the target buffer.
  	 */
17926a793   David Howells   [AF_RXRPC]: Provi...
410
411
412
413
414
415
416
417
418
419
  	nsg = skb_cow_data(skb, 0, &trailer);
  	if (nsg < 0)
  		goto nomem;
  
  	sg = _sg;
  	if (unlikely(nsg > 4)) {
  		sg = kmalloc(sizeof(*sg) * nsg, GFP_NOIO);
  		if (!sg)
  			goto nomem;
  	}
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
420
  	sg_init_table(sg, nsg);
89a5ea996   Jason A. Donenfeld   rxrpc: check retu...
421
422
423
424
425
426
  	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...
427
428
  
  	/* decrypt from the session key */
19ffa01c9   David Howells   rxrpc: Use struct...
429
  	token = call->conn->params.key->payload.data[0];
339412841   David Howells   RxRPC: Allow key ...
430
  	memcpy(&iv, token->kad->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
431

1afe593b4   Herbert Xu   rxrpc: Use skcipher
432
433
  	skcipher_request_set_tfm(req, call->conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
248f219cb   David Howells   rxrpc: Rewrite th...
434
  	skcipher_request_set_crypt(req, sg, sg, len, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
435
436
  	crypto_skcipher_decrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
437
438
  	if (sg != _sg)
  		kfree(sg);
5a42976d4   David Howells   rxrpc: Add tracep...
439
  	/* Extract the decrypted packet length */
248f219cb   David Howells   rxrpc: Rewrite th...
440
  	if (skb_copy_bits(skb, offset, &sechdr, sizeof(sechdr)) < 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
441
442
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_len", "XV2",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
443
444
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
445
446
  	offset += sizeof(sechdr);
  	len -= sizeof(sechdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
447
448
449
450
451
  
  	buf = ntohl(sechdr.data_size);
  	data_size = buf & 0xffff;
  
  	check = buf >> 16;
5a42976d4   David Howells   rxrpc: Add tracep...
452
  	check ^= seq ^ call->call_id;
17926a793   David Howells   [AF_RXRPC]: Provi...
453
454
  	check &= 0xffff;
  	if (check != 0) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
455
456
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_check", "V2C",
  					     RXKADSEALEDINCON);
17926a793   David Howells   [AF_RXRPC]: Provi...
457
458
  		goto protocol_error;
  	}
248f219cb   David Howells   rxrpc: Rewrite th...
459
  	if (data_size > len) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
460
461
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_2_datalen", "V2L",
  					     RXKADDATALEN);
5a42976d4   David Howells   rxrpc: Add tracep...
462
463
  		goto protocol_error;
  	}
17926a793   David Howells   [AF_RXRPC]: Provi...
464
465
466
  
  	_leave(" = 0 [dlen=%x]", data_size);
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
467
  protocol_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
468
469
  	if (aborted)
  		rxrpc_send_abort_packet(call);
17926a793   David Howells   [AF_RXRPC]: Provi...
470
471
472
473
474
475
476
477
  	return -EPROTO;
  
  nomem:
  	_leave(" = -ENOMEM");
  	return -ENOMEM;
  }
  
  /*
5a42976d4   David Howells   rxrpc: Add tracep...
478
479
   * Verify the security on a received packet or subpacket (if part of a
   * jumbo packet).
17926a793   David Howells   [AF_RXRPC]: Provi...
480
   */
5a42976d4   David Howells   rxrpc: Add tracep...
481
  static int rxkad_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
248f219cb   David Howells   rxrpc: Rewrite th...
482
  			       unsigned int offset, unsigned int len,
5a42976d4   David Howells   rxrpc: Add tracep...
483
  			       rxrpc_seq_t seq, u16 expected_cksum)
17926a793   David Howells   [AF_RXRPC]: Provi...
484
  {
1afe593b4   Herbert Xu   rxrpc: Use skcipher
485
  	SKCIPHER_REQUEST_ON_STACK(req, call->conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
486
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
487
  	struct scatterlist sg;
fb46f6ee1   David Howells   rxrpc: Trace prot...
488
  	bool aborted;
0d12f8a40   David Howells   rxrpc: Keep the s...
489
490
  	u16 cksum;
  	u32 x, y;
17926a793   David Howells   [AF_RXRPC]: Provi...
491
492
  
  	_enter("{%d{%x}},{#%u}",
5a42976d4   David Howells   rxrpc: Add tracep...
493
  	       call->debug_id, key_serial(call->conn->params.key), seq);
17926a793   David Howells   [AF_RXRPC]: Provi...
494
495
496
  
  	if (!call->conn->cipher)
  		return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
497
498
  	/* continue encrypting from where we left off */
  	memcpy(&iv, call->conn->csum_iv.x, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
499
500
  
  	/* validate the security checksum */
01a90a459   David Howells   rxrpc: Drop chann...
501
  	x = (call->cid & RXRPC_CHANNELMASK) << (32 - RXRPC_CIDSHIFT);
5a42976d4   David Howells   rxrpc: Add tracep...
502
  	x |= seq & 0x3fffffff;
a263629da   Herbert Xu   rxrpc: Avoid usin...
503
504
  	call->crypto_buf[0] = htonl(call->call_id);
  	call->crypto_buf[1] = htonl(x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
505

a263629da   Herbert Xu   rxrpc: Avoid usin...
506
  	sg_init_one(&sg, call->crypto_buf, 8);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
507
508
  	skcipher_request_set_tfm(req, call->conn->cipher);
  	skcipher_request_set_callback(req, 0, NULL, NULL);
a263629da   Herbert Xu   rxrpc: Avoid usin...
509
  	skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
510
511
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
512

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

5a42976d4   David Howells   rxrpc: Add tracep...
518
  	if (cksum != expected_cksum) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
519
520
521
  		aborted = rxrpc_abort_eproto(call, skb, "rxkad_csum", "VCK",
  					     RXKADSEALEDINCON);
  		goto protocol_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
522
  	}
19ffa01c9   David Howells   rxrpc: Use struct...
523
  	switch (call->conn->params.security_level) {
17926a793   David Howells   [AF_RXRPC]: Provi...
524
  	case RXRPC_SECURITY_PLAIN:
5a42976d4   David Howells   rxrpc: Add tracep...
525
  		return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
526
  	case RXRPC_SECURITY_AUTH:
248f219cb   David Howells   rxrpc: Rewrite th...
527
  		return rxkad_verify_packet_1(call, skb, offset, len, seq);
17926a793   David Howells   [AF_RXRPC]: Provi...
528
  	case RXRPC_SECURITY_ENCRYPT:
248f219cb   David Howells   rxrpc: Rewrite th...
529
  		return rxkad_verify_packet_2(call, skb, offset, len, seq);
17926a793   David Howells   [AF_RXRPC]: Provi...
530
  	default:
5a42976d4   David Howells   rxrpc: Add tracep...
531
  		return -ENOANO;
17926a793   David Howells   [AF_RXRPC]: Provi...
532
  	}
fb46f6ee1   David Howells   rxrpc: Trace prot...
533
534
535
536
537
  
  protocol_error:
  	if (aborted)
  		rxrpc_send_abort_packet(call);
  	return -EPROTO;
17926a793   David Howells   [AF_RXRPC]: Provi...
538
539
540
  }
  
  /*
248f219cb   David Howells   rxrpc: Rewrite th...
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
   * 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...
587
588
589
590
591
   * issue a challenge
   */
  static int rxkad_issue_challenge(struct rxrpc_connection *conn)
  {
  	struct rxkad_challenge challenge;
0d12f8a40   David Howells   rxrpc: Keep the s...
592
  	struct rxrpc_wire_header whdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
593
594
595
  	struct msghdr msg;
  	struct kvec iov[2];
  	size_t len;
0d12f8a40   David Howells   rxrpc: Keep the s...
596
  	u32 serial;
17926a793   David Howells   [AF_RXRPC]: Provi...
597
  	int ret;
19ffa01c9   David Howells   rxrpc: Use struct...
598
  	_enter("{%d,%x}", conn->debug_id, key_serial(conn->params.key));
17926a793   David Howells   [AF_RXRPC]: Provi...
599

19ffa01c9   David Howells   rxrpc: Use struct...
600
  	ret = key_validate(conn->params.key);
17926a793   David Howells   [AF_RXRPC]: Provi...
601
602
603
604
605
606
607
608
609
  	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...
610
611
  	msg.msg_name	= &conn->params.peer->srx.transport;
  	msg.msg_namelen	= conn->params.peer->srx.transport_len;
17926a793   David Howells   [AF_RXRPC]: Provi...
612
613
614
  	msg.msg_control	= NULL;
  	msg.msg_controllen = 0;
  	msg.msg_flags	= 0;
19ffa01c9   David Howells   rxrpc: Use struct...
615
616
  	whdr.epoch	= htonl(conn->proto.epoch);
  	whdr.cid	= htonl(conn->proto.cid);
0d12f8a40   David Howells   rxrpc: Keep the s...
617
618
619
620
621
622
623
  	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...
624
  	whdr.serviceId	= htons(conn->service_id);
0d12f8a40   David Howells   rxrpc: Keep the s...
625
626
627
  
  	iov[0].iov_base	= &whdr;
  	iov[0].iov_len	= sizeof(whdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
628
629
630
631
  	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...
632
633
634
  	serial = atomic_inc_return(&conn->serial);
  	whdr.serial = htonl(serial);
  	_proto("Tx CHALLENGE %%%u", serial);
17926a793   David Howells   [AF_RXRPC]: Provi...
635

85f32278b   David Howells   rxrpc: Replace co...
636
  	ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len);
17926a793   David Howells   [AF_RXRPC]: Provi...
637
638
639
640
641
642
643
644
645
646
647
648
649
  	if (ret < 0) {
  		_debug("sendmsg failed: %d", ret);
  		return -EAGAIN;
  	}
  
  	_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...
650
  			       struct rxrpc_host_header *hdr,
17926a793   David Howells   [AF_RXRPC]: Provi...
651
652
653
  			       struct rxkad_response *resp,
  			       const struct rxkad_key *s2)
  {
0d12f8a40   David Howells   rxrpc: Keep the s...
654
  	struct rxrpc_wire_header whdr;
17926a793   David Howells   [AF_RXRPC]: Provi...
655
656
657
  	struct msghdr msg;
  	struct kvec iov[3];
  	size_t len;
0d12f8a40   David Howells   rxrpc: Keep the s...
658
  	u32 serial;
17926a793   David Howells   [AF_RXRPC]: Provi...
659
660
661
  	int ret;
  
  	_enter("");
7b674e390   David Howells   rxrpc: Fix IPv6 s...
662
663
  	msg.msg_name	= &conn->params.peer->srx.transport;
  	msg.msg_namelen	= conn->params.peer->srx.transport_len;
17926a793   David Howells   [AF_RXRPC]: Provi...
664
665
666
  	msg.msg_control	= NULL;
  	msg.msg_controllen = 0;
  	msg.msg_flags	= 0;
0d12f8a40   David Howells   rxrpc: Keep the s...
667
668
669
670
671
672
673
  	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...
674

0d12f8a40   David Howells   rxrpc: Keep the s...
675
676
  	iov[0].iov_base	= &whdr;
  	iov[0].iov_len	= sizeof(whdr);
17926a793   David Howells   [AF_RXRPC]: Provi...
677
678
  	iov[1].iov_base	= resp;
  	iov[1].iov_len	= sizeof(*resp);
0d12f8a40   David Howells   rxrpc: Keep the s...
679
  	iov[2].iov_base	= (void *)s2->ticket;
17926a793   David Howells   [AF_RXRPC]: Provi...
680
681
682
  	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...
683
684
685
  	serial = atomic_inc_return(&conn->serial);
  	whdr.serial = htonl(serial);
  	_proto("Tx RESPONSE %%%u", serial);
17926a793   David Howells   [AF_RXRPC]: Provi...
686

85f32278b   David Howells   rxrpc: Replace co...
687
  	ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 3, len);
17926a793   David Howells   [AF_RXRPC]: Provi...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
  	if (ret < 0) {
  		_debug("sendmsg failed: %d", ret);
  		return -EAGAIN;
  	}
  
  	_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...
713
714
715
716
717
718
   * encrypt the response packet
   */
  static void rxkad_encrypt_response(struct rxrpc_connection *conn,
  				   struct rxkad_response *resp,
  				   const struct rxkad_key *s2)
  {
1afe593b4   Herbert Xu   rxrpc: Use skcipher
719
  	SKCIPHER_REQUEST_ON_STACK(req, conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
720
  	struct rxrpc_crypt iv;
a263629da   Herbert Xu   rxrpc: Avoid usin...
721
  	struct scatterlist sg[1];
17926a793   David Howells   [AF_RXRPC]: Provi...
722
723
724
  
  	/* continue encrypting from where we left off */
  	memcpy(&iv, s2->session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
725

a263629da   Herbert Xu   rxrpc: Avoid usin...
726
727
  	sg_init_table(sg, 1);
  	sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted));
1afe593b4   Herbert Xu   rxrpc: Use skcipher
728
729
730
  	skcipher_request_set_tfm(req, conn->cipher);
  	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
731
732
  	crypto_skcipher_encrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
733
734
735
736
737
738
739
740
741
  }
  
  /*
   * 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 ...
742
  	const struct rxrpc_key_token *token;
17926a793   David Howells   [AF_RXRPC]: Provi...
743
  	struct rxkad_challenge challenge;
e781fff7b   David Howells   rxrpc: Don't put ...
744
  	struct rxkad_response *resp;
248f219cb   David Howells   rxrpc: Rewrite th...
745
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
fb46f6ee1   David Howells   rxrpc: Trace prot...
746
  	const char *eproto;
17926a793   David Howells   [AF_RXRPC]: Provi...
747
748
  	u32 version, nonce, min_level, abort_code;
  	int ret;
19ffa01c9   David Howells   rxrpc: Use struct...
749
  	_enter("{%d,%x}", conn->debug_id, key_serial(conn->params.key));
17926a793   David Howells   [AF_RXRPC]: Provi...
750

fb46f6ee1   David Howells   rxrpc: Trace prot...
751
  	eproto = tracepoint_string("chall_no_key");
ef68622da   David Howells   rxrpc: Handle tem...
752
753
754
  	abort_code = RX_PROTOCOL_ERROR;
  	if (!conn->params.key)
  		goto protocol_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
755

ef68622da   David Howells   rxrpc: Handle tem...
756
  	abort_code = RXKADEXPIRED;
19ffa01c9   David Howells   rxrpc: Use struct...
757
  	ret = key_validate(conn->params.key);
ef68622da   David Howells   rxrpc: Handle tem...
758
759
  	if (ret < 0)
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
760

fb46f6ee1   David Howells   rxrpc: Trace prot...
761
  	eproto = tracepoint_string("chall_short");
17926a793   David Howells   [AF_RXRPC]: Provi...
762
  	abort_code = RXKADPACKETSHORT;
775e5b71d   David Howells   rxrpc: The offset...
763
764
  	if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
  			  &challenge, sizeof(challenge)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
765
766
767
768
769
770
771
  		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...
772
  	       sp->hdr.serial, version, nonce, min_level);
17926a793   David Howells   [AF_RXRPC]: Provi...
773

fb46f6ee1   David Howells   rxrpc: Trace prot...
774
  	eproto = tracepoint_string("chall_ver");
17926a793   David Howells   [AF_RXRPC]: Provi...
775
776
777
778
779
  	abort_code = RXKADINCONSISTENCY;
  	if (version != RXKAD_VERSION)
  		goto protocol_error;
  
  	abort_code = RXKADLEVELFAIL;
ef68622da   David Howells   rxrpc: Handle tem...
780
  	ret = -EACCES;
19ffa01c9   David Howells   rxrpc: Use struct...
781
  	if (conn->params.security_level < min_level)
ef68622da   David Howells   rxrpc: Handle tem...
782
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
783

19ffa01c9   David Howells   rxrpc: Use struct...
784
  	token = conn->params.key->payload.data[0];
17926a793   David Howells   [AF_RXRPC]: Provi...
785
786
  
  	/* build the response packet */
e781fff7b   David Howells   rxrpc: Don't put ...
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
  	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...
803
804
  
  	/* calculate the response checksum and then do the encryption */
e781fff7b   David Howells   rxrpc: Don't put ...
805
806
807
808
809
  	rxkad_calc_response_checksum(resp);
  	rxkad_encrypt_response(conn, resp, token->kad);
  	ret = rxkad_send_response(conn, &sp->hdr, resp, token->kad);
  	kfree(resp);
  	return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
810
811
  
  protocol_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
812
  	trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
ef68622da   David Howells   rxrpc: Handle tem...
813
814
  	ret = -EPROTO;
  other_error:
17926a793   David Howells   [AF_RXRPC]: Provi...
815
  	*_abort_code = abort_code;
ef68622da   David Howells   rxrpc: Handle tem...
816
  	return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
817
818
819
820
821
822
  }
  
  /*
   * decrypt the kerberos IV ticket in the response
   */
  static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
fb46f6ee1   David Howells   rxrpc: Trace prot...
823
  				struct sk_buff *skb,
17926a793   David Howells   [AF_RXRPC]: Provi...
824
825
  				void *ticket, size_t ticket_len,
  				struct rxrpc_crypt *_session_key,
10674a03c   Baolin Wang   net: rxrpc: Repla...
826
  				time64_t *_expiry,
17926a793   David Howells   [AF_RXRPC]: Provi...
827
828
  				u32 *_abort_code)
  {
1afe593b4   Herbert Xu   rxrpc: Use skcipher
829
  	struct skcipher_request *req;
fb46f6ee1   David Howells   rxrpc: Trace prot...
830
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
17926a793   David Howells   [AF_RXRPC]: Provi...
831
  	struct rxrpc_crypt iv, key;
68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
832
  	struct scatterlist sg[1];
17926a793   David Howells   [AF_RXRPC]: Provi...
833
  	struct in_addr addr;
95c961747   Eric Dumazet   net: cleanup unsi...
834
  	unsigned int life;
fb46f6ee1   David Howells   rxrpc: Trace prot...
835
  	const char *eproto;
10674a03c   Baolin Wang   net: rxrpc: Repla...
836
  	time64_t issue, now;
17926a793   David Howells   [AF_RXRPC]: Provi...
837
838
  	bool little_endian;
  	int ret;
fb46f6ee1   David Howells   rxrpc: Trace prot...
839
  	u32 abort_code;
17926a793   David Howells   [AF_RXRPC]: Provi...
840
841
842
843
844
845
846
847
848
849
  	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...
850
  			abort_code = RXKADEXPIRED;
ef68622da   David Howells   rxrpc: Handle tem...
851
  			goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
852
  		default:
fb46f6ee1   David Howells   rxrpc: Trace prot...
853
  			abort_code = RXKADNOAUTH;
ef68622da   David Howells   rxrpc: Handle tem...
854
  			goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
855
856
  		}
  	}
146aa8b14   David Howells   KEYS: Merge the t...
857
  	ASSERT(conn->server_key->payload.data[0] != NULL);
17926a793   David Howells   [AF_RXRPC]: Provi...
858
  	ASSERTCMP((unsigned long) ticket & 7UL, ==, 0);
146aa8b14   David Howells   KEYS: Merge the t...
859
  	memcpy(&iv, &conn->server_key->payload.data[2], sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
860

ef68622da   David Howells   rxrpc: Handle tem...
861
  	ret = -ENOMEM;
1afe593b4   Herbert Xu   rxrpc: Use skcipher
862
863
  	req = skcipher_request_alloc(conn->server_key->payload.data[0],
  				     GFP_NOFS);
ef68622da   David Howells   rxrpc: Handle tem...
864
865
  	if (!req)
  		goto temporary_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
866

68e3f5dd4   Herbert Xu   [CRYPTO] users: F...
867
  	sg_init_one(&sg[0], ticket, ticket_len);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
868
869
  	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
870
871
  	crypto_skcipher_decrypt(req);
  	skcipher_request_free(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
872
873
874
  
  	p = ticket;
  	end = p + ticket_len;
fb46f6ee1   David Howells   rxrpc: Trace prot...
875
  #define Z(field)					\
17926a793   David Howells   [AF_RXRPC]: Provi...
876
877
  	({						\
  		u8 *__str = p;				\
fb46f6ee1   David Howells   rxrpc: Trace prot...
878
  		eproto = tracepoint_string("rxkad_bad_"#field); \
17926a793   David Howells   [AF_RXRPC]: Provi...
879
  		q = memchr(p, 0, end - p);		\
fb46f6ee1   David Howells   rxrpc: Trace prot...
880
  		if (!q || q - p > (field##_SZ))		\
17926a793   David Howells   [AF_RXRPC]: Provi...
881
882
883
884
885
886
887
888
889
890
891
892
893
894
  			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...
895
  	name = Z(ANAME);
17926a793   David Howells   [AF_RXRPC]: Provi...
896
897
898
  	_debug("KIV ANAME: %s", name);
  
  	/* extract the principal's instance */
fb46f6ee1   David Howells   rxrpc: Trace prot...
899
  	name = Z(INST);
17926a793   David Howells   [AF_RXRPC]: Provi...
900
901
902
  	_debug("KIV INST : %s", name);
  
  	/* extract the principal's authentication domain */
fb46f6ee1   David Howells   rxrpc: Trace prot...
903
  	name = Z(REALM);
17926a793   David Howells   [AF_RXRPC]: Provi...
904
  	_debug("KIV REALM: %s", name);
fb46f6ee1   David Howells   rxrpc: Trace prot...
905
  	eproto = tracepoint_string("rxkad_bad_len");
17926a793   David Howells   [AF_RXRPC]: Provi...
906
907
908
909
910
911
  	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...
912
  	_debug("KIV ADDR : %pI4", &addr);
17926a793   David Howells   [AF_RXRPC]: Provi...
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
  
  	/* 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...
928
  		issue = rxrpc_u32_to_time64(le32_to_cpu(stamp));
17926a793   David Howells   [AF_RXRPC]: Provi...
929
930
931
  	} else {
  		__be32 stamp;
  		memcpy(&stamp, p, 4);
10674a03c   Baolin Wang   net: rxrpc: Repla...
932
  		issue = rxrpc_u32_to_time64(be32_to_cpu(stamp));
17926a793   David Howells   [AF_RXRPC]: Provi...
933
934
  	}
  	p += 4;
10674a03c   Baolin Wang   net: rxrpc: Repla...
935
936
  	now = ktime_get_real_seconds();
  	_debug("KIV ISSUE: %llx [%llx]", issue, now);
17926a793   David Howells   [AF_RXRPC]: Provi...
937
938
939
  
  	/* check the ticket is in date */
  	if (issue > now) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
940
  		abort_code = RXKADNOAUTH;
17926a793   David Howells   [AF_RXRPC]: Provi...
941
  		ret = -EKEYREJECTED;
ef68622da   David Howells   rxrpc: Handle tem...
942
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
943
944
945
  	}
  
  	if (issue < now - life) {
fb46f6ee1   David Howells   rxrpc: Trace prot...
946
  		abort_code = RXKADEXPIRED;
17926a793   David Howells   [AF_RXRPC]: Provi...
947
  		ret = -EKEYEXPIRED;
ef68622da   David Howells   rxrpc: Handle tem...
948
  		goto other_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
949
950
951
952
953
  	}
  
  	*_expiry = issue + life;
  
  	/* get the service name */
fb46f6ee1   David Howells   rxrpc: Trace prot...
954
  	name = Z(SNAME);
17926a793   David Howells   [AF_RXRPC]: Provi...
955
956
957
  	_debug("KIV SNAME: %s", name);
  
  	/* get the service instance name */
fb46f6ee1   David Howells   rxrpc: Trace prot...
958
  	name = Z(INST);
17926a793   David Howells   [AF_RXRPC]: Provi...
959
  	_debug("KIV SINST: %s", name);
ef68622da   David Howells   rxrpc: Handle tem...
960
  	return 0;
17926a793   David Howells   [AF_RXRPC]: Provi...
961
962
  
  bad_ticket:
fb46f6ee1   David Howells   rxrpc: Trace prot...
963
964
  	trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
  	abort_code = RXKADBADTICKET;
ef68622da   David Howells   rxrpc: Handle tem...
965
966
  	ret = -EPROTO;
  other_error:
fb46f6ee1   David Howells   rxrpc: Trace prot...
967
  	*_abort_code = abort_code;
ef68622da   David Howells   rxrpc: Handle tem...
968
969
970
  	return ret;
  temporary_error:
  	return ret;
17926a793   David Howells   [AF_RXRPC]: Provi...
971
972
973
974
975
976
977
978
979
  }
  
  /*
   * decrypt the response packet
   */
  static void rxkad_decrypt_response(struct rxrpc_connection *conn,
  				   struct rxkad_response *resp,
  				   const struct rxrpc_crypt *session_key)
  {
1afe593b4   Herbert Xu   rxrpc: Use skcipher
980
  	SKCIPHER_REQUEST_ON_STACK(req, rxkad_ci);
a263629da   Herbert Xu   rxrpc: Avoid usin...
981
  	struct scatterlist sg[1];
17926a793   David Howells   [AF_RXRPC]: Provi...
982
983
984
985
986
987
988
989
  	struct rxrpc_crypt iv;
  
  	_enter(",,%08x%08x",
  	       ntohl(session_key->n[0]), ntohl(session_key->n[1]));
  
  	ASSERT(rxkad_ci != NULL);
  
  	mutex_lock(&rxkad_ci_mutex);
1afe593b4   Herbert Xu   rxrpc: Use skcipher
990
991
  	if (crypto_skcipher_setkey(rxkad_ci, session_key->x,
  				   sizeof(*session_key)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
992
993
994
  		BUG();
  
  	memcpy(&iv, session_key, sizeof(iv));
17926a793   David Howells   [AF_RXRPC]: Provi...
995

a263629da   Herbert Xu   rxrpc: Avoid usin...
996
997
  	sg_init_table(sg, 1);
  	sg_set_buf(sg, &resp->encrypted, sizeof(resp->encrypted));
1afe593b4   Herbert Xu   rxrpc: Use skcipher
998
999
1000
  	skcipher_request_set_tfm(req, rxkad_ci);
  	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
1001
1002
  	crypto_skcipher_decrypt(req);
  	skcipher_request_zero(req);
17926a793   David Howells   [AF_RXRPC]: Provi...
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
  	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)
  {
e781fff7b   David Howells   rxrpc: Don't put ...
1015
  	struct rxkad_response *response;
248f219cb   David Howells   rxrpc: Rewrite th...
1016
  	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
17926a793   David Howells   [AF_RXRPC]: Provi...
1017
  	struct rxrpc_crypt session_key;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1018
  	const char *eproto;
10674a03c   Baolin Wang   net: rxrpc: Repla...
1019
  	time64_t expiry;
17926a793   David Howells   [AF_RXRPC]: Provi...
1020
  	void *ticket;
91e916cff   Al Viro   net/rxrpc trivial...
1021
1022
  	u32 abort_code, version, kvno, ticket_len, level;
  	__be32 csum;
a1399f8bb   David Howells   rxrpc: Call chann...
1023
  	int ret, i;
17926a793   David Howells   [AF_RXRPC]: Provi...
1024
1025
  
  	_enter("{%d,%x}", conn->debug_id, key_serial(conn->server_key));
e781fff7b   David Howells   rxrpc: Don't put ...
1026
1027
1028
1029
  	ret = -ENOMEM;
  	response = kzalloc(sizeof(struct rxkad_response), GFP_NOFS);
  	if (!response)
  		goto temporary_error;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1030
  	eproto = tracepoint_string("rxkad_rsp_short");
17926a793   David Howells   [AF_RXRPC]: Provi...
1031
  	abort_code = RXKADPACKETSHORT;
775e5b71d   David Howells   rxrpc: The offset...
1032
  	if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
e781fff7b   David Howells   rxrpc: Don't put ...
1033
  			  response, sizeof(*response)) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
1034
  		goto protocol_error;
e781fff7b   David Howells   rxrpc: Don't put ...
1035
  	if (!pskb_pull(skb, sizeof(*response)))
17926a793   David Howells   [AF_RXRPC]: Provi...
1036
  		BUG();
e781fff7b   David Howells   rxrpc: Don't put ...
1037
1038
1039
  	version = ntohl(response->version);
  	ticket_len = ntohl(response->ticket_len);
  	kvno = ntohl(response->kvno);
17926a793   David Howells   [AF_RXRPC]: Provi...
1040
  	_proto("Rx RESPONSE %%%u { v=%u kv=%u tl=%u }",
0d12f8a40   David Howells   rxrpc: Keep the s...
1041
  	       sp->hdr.serial, version, kvno, ticket_len);
17926a793   David Howells   [AF_RXRPC]: Provi...
1042

fb46f6ee1   David Howells   rxrpc: Trace prot...
1043
  	eproto = tracepoint_string("rxkad_rsp_ver");
17926a793   David Howells   [AF_RXRPC]: Provi...
1044
1045
  	abort_code = RXKADINCONSISTENCY;
  	if (version != RXKAD_VERSION)
4aa9cb320   David Howells   [AF_RXRPC]: Add a...
1046
  		goto protocol_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
1047

fb46f6ee1   David Howells   rxrpc: Trace prot...
1048
  	eproto = tracepoint_string("rxkad_rsp_tktlen");
17926a793   David Howells   [AF_RXRPC]: Provi...
1049
1050
1051
  	abort_code = RXKADTICKETLEN;
  	if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN)
  		goto protocol_error;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1052
  	eproto = tracepoint_string("rxkad_rsp_unkkey");
17926a793   David Howells   [AF_RXRPC]: Provi...
1053
1054
1055
1056
1057
  	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...
1058
  	ret = -ENOMEM;
17926a793   David Howells   [AF_RXRPC]: Provi...
1059
1060
  	ticket = kmalloc(ticket_len, GFP_NOFS);
  	if (!ticket)
ef68622da   David Howells   rxrpc: Handle tem...
1061
  		goto temporary_error;
17926a793   David Howells   [AF_RXRPC]: Provi...
1062

fb46f6ee1   David Howells   rxrpc: Trace prot...
1063
  	eproto = tracepoint_string("rxkad_tkt_short");
17926a793   David Howells   [AF_RXRPC]: Provi...
1064
  	abort_code = RXKADPACKETSHORT;
775e5b71d   David Howells   rxrpc: The offset...
1065
1066
  	if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
  			  ticket, ticket_len) < 0)
17926a793   David Howells   [AF_RXRPC]: Provi...
1067
  		goto protocol_error_free;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1068
  	ret = rxkad_decrypt_ticket(conn, skb, ticket, ticket_len, &session_key,
ef68622da   David Howells   rxrpc: Handle tem...
1069
1070
  				   &expiry, _abort_code);
  	if (ret < 0)
e781fff7b   David Howells   rxrpc: Don't put ...
1071
  		goto temporary_error_free_resp;
17926a793   David Howells   [AF_RXRPC]: Provi...
1072
1073
1074
  
  	/* use the session key from inside the ticket to decrypt the
  	 * response */
e781fff7b   David Howells   rxrpc: Don't put ...
1075
  	rxkad_decrypt_response(conn, response, &session_key);
17926a793   David Howells   [AF_RXRPC]: Provi...
1076

fb46f6ee1   David Howells   rxrpc: Trace prot...
1077
  	eproto = tracepoint_string("rxkad_rsp_param");
17926a793   David Howells   [AF_RXRPC]: Provi...
1078
  	abort_code = RXKADSEALEDINCON;
e781fff7b   David Howells   rxrpc: Don't put ...
1079
  	if (ntohl(response->encrypted.epoch) != conn->proto.epoch)
17926a793   David Howells   [AF_RXRPC]: Provi...
1080
  		goto protocol_error_free;
e781fff7b   David Howells   rxrpc: Don't put ...
1081
  	if (ntohl(response->encrypted.cid) != conn->proto.cid)
17926a793   David Howells   [AF_RXRPC]: Provi...
1082
  		goto protocol_error_free;
e781fff7b   David Howells   rxrpc: Don't put ...
1083
  	if (ntohl(response->encrypted.securityIndex) != conn->security_ix)
17926a793   David Howells   [AF_RXRPC]: Provi...
1084
  		goto protocol_error_free;
e781fff7b   David Howells   rxrpc: Don't put ...
1085
1086
1087
  	csum = response->encrypted.checksum;
  	response->encrypted.checksum = 0;
  	rxkad_calc_response_checksum(response);
fb46f6ee1   David Howells   rxrpc: Trace prot...
1088
  	eproto = tracepoint_string("rxkad_rsp_csum");
e781fff7b   David Howells   rxrpc: Don't put ...
1089
  	if (response->encrypted.checksum != csum)
17926a793   David Howells   [AF_RXRPC]: Provi...
1090
  		goto protocol_error_free;
a1399f8bb   David Howells   rxrpc: Call chann...
1091
1092
1093
  	spin_lock(&conn->channel_lock);
  	for (i = 0; i < RXRPC_MAXCALLS; i++) {
  		struct rxrpc_call *call;
e781fff7b   David Howells   rxrpc: Don't put ...
1094
  		u32 call_id = ntohl(response->encrypted.call_id[i]);
a1399f8bb   David Howells   rxrpc: Call chann...
1095

fb46f6ee1   David Howells   rxrpc: Trace prot...
1096
  		eproto = tracepoint_string("rxkad_rsp_callid");
a1399f8bb   David Howells   rxrpc: Call chann...
1097
1098
  		if (call_id > INT_MAX)
  			goto protocol_error_unlock;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1099
  		eproto = tracepoint_string("rxkad_rsp_callctr");
a1399f8bb   David Howells   rxrpc: Call chann...
1100
1101
  		if (call_id < conn->channels[i].call_counter)
  			goto protocol_error_unlock;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1102
1103
  
  		eproto = tracepoint_string("rxkad_rsp_callst");
a1399f8bb   David Howells   rxrpc: Call chann...
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
  		if (call_id > conn->channels[i].call_counter) {
  			call = rcu_dereference_protected(
  				conn->channels[i].call,
  				lockdep_is_held(&conn->channel_lock));
  			if (call && call->state < RXRPC_CALL_COMPLETE)
  				goto protocol_error_unlock;
  			conn->channels[i].call_counter = call_id;
  		}
  	}
  	spin_unlock(&conn->channel_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
1114

fb46f6ee1   David Howells   rxrpc: Trace prot...
1115
  	eproto = tracepoint_string("rxkad_rsp_seq");
17926a793   David Howells   [AF_RXRPC]: Provi...
1116
  	abort_code = RXKADOUTOFSEQUENCE;
e781fff7b   David Howells   rxrpc: Don't put ...
1117
  	if (ntohl(response->encrypted.inc_nonce) != conn->security_nonce + 1)
17926a793   David Howells   [AF_RXRPC]: Provi...
1118
  		goto protocol_error_free;
fb46f6ee1   David Howells   rxrpc: Trace prot...
1119
  	eproto = tracepoint_string("rxkad_rsp_level");
17926a793   David Howells   [AF_RXRPC]: Provi...
1120
  	abort_code = RXKADLEVELFAIL;
e781fff7b   David Howells   rxrpc: Don't put ...
1121
  	level = ntohl(response->encrypted.level);
17926a793   David Howells   [AF_RXRPC]: Provi...
1122
1123
  	if (level > RXRPC_SECURITY_ENCRYPT)
  		goto protocol_error_free;
19ffa01c9   David Howells   rxrpc: Use struct...
1124
  	conn->params.security_level = level;
17926a793   David Howells   [AF_RXRPC]: Provi...
1125
1126
1127
1128
1129
  
  	/* 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...
1130
  	if (ret < 0)
e781fff7b   David Howells   rxrpc: Don't put ...
1131
  		goto temporary_error_free_ticket;
17926a793   David Howells   [AF_RXRPC]: Provi...
1132
1133
  
  	kfree(ticket);
e781fff7b   David Howells   rxrpc: Don't put ...
1134
  	kfree(response);
17926a793   David Howells   [AF_RXRPC]: Provi...
1135
1136
  	_leave(" = 0");
  	return 0;
a1399f8bb   David Howells   rxrpc: Call chann...
1137
1138
  protocol_error_unlock:
  	spin_unlock(&conn->channel_lock);
17926a793   David Howells   [AF_RXRPC]: Provi...
1139
1140
1141
  protocol_error_free:
  	kfree(ticket);
  protocol_error:
e781fff7b   David Howells   rxrpc: Don't put ...
1142
  	kfree(response);
fb46f6ee1   David Howells   rxrpc: Trace prot...
1143
  	trace_rxrpc_rx_eproto(NULL, sp->hdr.serial, eproto);
17926a793   David Howells   [AF_RXRPC]: Provi...
1144
  	*_abort_code = abort_code;
17926a793   David Howells   [AF_RXRPC]: Provi...
1145
  	return -EPROTO;
ef68622da   David Howells   rxrpc: Handle tem...
1146

e781fff7b   David Howells   rxrpc: Don't put ...
1147
  temporary_error_free_ticket:
ef68622da   David Howells   rxrpc: Handle tem...
1148
  	kfree(ticket);
e781fff7b   David Howells   rxrpc: Don't put ...
1149
1150
  temporary_error_free_resp:
  	kfree(response);
ef68622da   David Howells   rxrpc: Handle tem...
1151
1152
1153
1154
1155
1156
  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...
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  }
  
  /*
   * clear the connection security
   */
  static void rxkad_clear(struct rxrpc_connection *conn)
  {
  	_enter("");
  
  	if (conn->cipher)
1afe593b4   Herbert Xu   rxrpc: Use skcipher
1167
  		crypto_free_skcipher(conn->cipher);
17926a793   David Howells   [AF_RXRPC]: Provi...
1168
1169
1170
  }
  
  /*
648af7fca   David Howells   rxrpc: Absorb the...
1171
1172
1173
1174
1175
1176
1177
   * Initialise the rxkad security service.
   */
  static int rxkad_init(void)
  {
  	/* pin the cipher we need so that the crypto layer doesn't invoke
  	 * keventd to go get it */
  	rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
fa54cc70e   Wu Fengguang   rxrpc: fix ptr_re...
1178
  	return PTR_ERR_OR_ZERO(rxkad_ci);
648af7fca   David Howells   rxrpc: Absorb the...
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
  }
  
  /*
   * Clean up the rxkad security service.
   */
  static void rxkad_exit(void)
  {
  	if (rxkad_ci)
  		crypto_free_skcipher(rxkad_ci);
  }
  
  /*
17926a793   David Howells   [AF_RXRPC]: Provi...
1191
1192
   * RxRPC Kerberos-based security
   */
648af7fca   David Howells   rxrpc: Absorb the...
1193
  const struct rxrpc_security rxkad = {
17926a793   David Howells   [AF_RXRPC]: Provi...
1194
  	.name				= "rxkad",
8b815477f   David Howells   RxRPC: Declare th...
1195
  	.security_index			= RXRPC_SECURITY_RXKAD,
648af7fca   David Howells   rxrpc: Absorb the...
1196
1197
  	.init				= rxkad_init,
  	.exit				= rxkad_exit,
17926a793   David Howells   [AF_RXRPC]: Provi...
1198
1199
1200
1201
  	.init_connection_security	= rxkad_init_connection_security,
  	.prime_packet_security		= rxkad_prime_packet_security,
  	.secure_packet			= rxkad_secure_packet,
  	.verify_packet			= rxkad_verify_packet,
248f219cb   David Howells   rxrpc: Rewrite th...
1202
  	.locate_data			= rxkad_locate_data,
17926a793   David Howells   [AF_RXRPC]: Provi...
1203
1204
1205
1206
1207
  	.issue_challenge		= rxkad_issue_challenge,
  	.respond_to_challenge		= rxkad_respond_to_challenge,
  	.verify_response		= rxkad_verify_response,
  	.clear				= rxkad_clear,
  };