• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* RxRPC key management
2  *
3  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  * RxRPC keys should have a description of describing their purpose:
12  *	"afs@CAMBRIDGE.REDHAT.COM>
13  */
14 
15 #include <linux/module.h>
16 #include <linux/net.h>
17 #include <linux/skbuff.h>
18 #include <linux/key-type.h>
19 #include <linux/crypto.h>
20 #include <net/sock.h>
21 #include <net/af_rxrpc.h>
22 #include <keys/rxrpc-type.h>
23 #include <keys/user-type.h>
24 #include "ar-internal.h"
25 
26 static int rxrpc_instantiate(struct key *, const void *, size_t);
27 static int rxrpc_instantiate_s(struct key *, const void *, size_t);
28 static void rxrpc_destroy(struct key *);
29 static void rxrpc_destroy_s(struct key *);
30 static void rxrpc_describe(const struct key *, struct seq_file *);
31 
32 /*
33  * rxrpc defined keys take an arbitrary string as the description and an
34  * arbitrary blob of data as the payload
35  */
36 struct key_type key_type_rxrpc = {
37 	.name		= "rxrpc",
38 	.instantiate	= rxrpc_instantiate,
39 	.match		= user_match,
40 	.destroy	= rxrpc_destroy,
41 	.describe	= rxrpc_describe,
42 };
43 EXPORT_SYMBOL(key_type_rxrpc);
44 
45 /*
46  * rxrpc server defined keys take "<serviceId>:<securityIndex>" as the
47  * description and an 8-byte decryption key as the payload
48  */
49 struct key_type key_type_rxrpc_s = {
50 	.name		= "rxrpc_s",
51 	.instantiate	= rxrpc_instantiate_s,
52 	.match		= user_match,
53 	.destroy	= rxrpc_destroy_s,
54 	.describe	= rxrpc_describe,
55 };
56 
57 /*
58  * instantiate an rxrpc defined key
59  * data should be of the form:
60  *	OFFSET	LEN	CONTENT
61  *	0	4	key interface version number
62  *	4	2	security index (type)
63  *	6	2	ticket length
64  *	8	4	key expiry time (time_t)
65  *	12	4	kvno
66  *	16	8	session key
67  *	24	[len]	ticket
68  *
69  * if no data is provided, then a no-security key is made
70  */
rxrpc_instantiate(struct key * key,const void * data,size_t datalen)71 static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
72 {
73 	const struct rxkad_key *tsec;
74 	struct rxrpc_key_payload *upayload;
75 	size_t plen;
76 	u32 kver;
77 	int ret;
78 
79 	_enter("{%x},,%zu", key_serial(key), datalen);
80 
81 	/* handle a no-security key */
82 	if (!data && datalen == 0)
83 		return 0;
84 
85 	/* get the key interface version number */
86 	ret = -EINVAL;
87 	if (datalen <= 4 || !data)
88 		goto error;
89 	memcpy(&kver, data, sizeof(kver));
90 	data += sizeof(kver);
91 	datalen -= sizeof(kver);
92 
93 	_debug("KEY I/F VERSION: %u", kver);
94 
95 	ret = -EKEYREJECTED;
96 	if (kver != 1)
97 		goto error;
98 
99 	/* deal with a version 1 key */
100 	ret = -EINVAL;
101 	if (datalen < sizeof(*tsec))
102 		goto error;
103 
104 	tsec = data;
105 	if (datalen != sizeof(*tsec) + tsec->ticket_len)
106 		goto error;
107 
108 	_debug("SCIX: %u", tsec->security_index);
109 	_debug("TLEN: %u", tsec->ticket_len);
110 	_debug("EXPY: %x", tsec->expiry);
111 	_debug("KVNO: %u", tsec->kvno);
112 	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
113 	       tsec->session_key[0], tsec->session_key[1],
114 	       tsec->session_key[2], tsec->session_key[3],
115 	       tsec->session_key[4], tsec->session_key[5],
116 	       tsec->session_key[6], tsec->session_key[7]);
117 	if (tsec->ticket_len >= 8)
118 		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
119 		       tsec->ticket[0], tsec->ticket[1],
120 		       tsec->ticket[2], tsec->ticket[3],
121 		       tsec->ticket[4], tsec->ticket[5],
122 		       tsec->ticket[6], tsec->ticket[7]);
123 
124 	ret = -EPROTONOSUPPORT;
125 	if (tsec->security_index != 2)
126 		goto error;
127 
128 	key->type_data.x[0] = tsec->security_index;
129 
130 	plen = sizeof(*upayload) + tsec->ticket_len;
131 	ret = key_payload_reserve(key, plen);
132 	if (ret < 0)
133 		goto error;
134 
135 	ret = -ENOMEM;
136 	upayload = kmalloc(plen, GFP_KERNEL);
137 	if (!upayload)
138 		goto error;
139 
140 	/* attach the data */
141 	memcpy(&upayload->k, tsec, sizeof(*tsec));
142 	memcpy(&upayload->k.ticket, (void *)tsec + sizeof(*tsec),
143 	       tsec->ticket_len);
144 	key->payload.data = upayload;
145 	key->expiry = tsec->expiry;
146 	ret = 0;
147 
148 error:
149 	return ret;
150 }
151 
152 /*
153  * instantiate a server secret key
154  * data should be a pointer to the 8-byte secret key
155  */
rxrpc_instantiate_s(struct key * key,const void * data,size_t datalen)156 static int rxrpc_instantiate_s(struct key *key, const void *data,
157 			       size_t datalen)
158 {
159 	struct crypto_blkcipher *ci;
160 
161 	_enter("{%x},,%zu", key_serial(key), datalen);
162 
163 	if (datalen != 8)
164 		return -EINVAL;
165 
166 	memcpy(&key->type_data, data, 8);
167 
168 	ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
169 	if (IS_ERR(ci)) {
170 		_leave(" = %ld", PTR_ERR(ci));
171 		return PTR_ERR(ci);
172 	}
173 
174 	if (crypto_blkcipher_setkey(ci, data, 8) < 0)
175 		BUG();
176 
177 	key->payload.data = ci;
178 	_leave(" = 0");
179 	return 0;
180 }
181 
182 /*
183  * dispose of the data dangling from the corpse of a rxrpc key
184  */
rxrpc_destroy(struct key * key)185 static void rxrpc_destroy(struct key *key)
186 {
187 	kfree(key->payload.data);
188 }
189 
190 /*
191  * dispose of the data dangling from the corpse of a rxrpc key
192  */
rxrpc_destroy_s(struct key * key)193 static void rxrpc_destroy_s(struct key *key)
194 {
195 	if (key->payload.data) {
196 		crypto_free_blkcipher(key->payload.data);
197 		key->payload.data = NULL;
198 	}
199 }
200 
201 /*
202  * describe the rxrpc key
203  */
rxrpc_describe(const struct key * key,struct seq_file * m)204 static void rxrpc_describe(const struct key *key, struct seq_file *m)
205 {
206 	seq_puts(m, key->description);
207 }
208 
209 /*
210  * grab the security key for a socket
211  */
rxrpc_request_key(struct rxrpc_sock * rx,char __user * optval,int optlen)212 int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
213 {
214 	struct key *key;
215 	char *description;
216 
217 	_enter("");
218 
219 	if (optlen <= 0 || optlen > PAGE_SIZE - 1)
220 		return -EINVAL;
221 
222 	description = kmalloc(optlen + 1, GFP_KERNEL);
223 	if (!description)
224 		return -ENOMEM;
225 
226 	if (copy_from_user(description, optval, optlen)) {
227 		kfree(description);
228 		return -EFAULT;
229 	}
230 	description[optlen] = 0;
231 
232 	key = request_key(&key_type_rxrpc, description, NULL);
233 	if (IS_ERR(key)) {
234 		kfree(description);
235 		_leave(" = %ld", PTR_ERR(key));
236 		return PTR_ERR(key);
237 	}
238 
239 	rx->key = key;
240 	kfree(description);
241 	_leave(" = 0 [key %x]", key->serial);
242 	return 0;
243 }
244 
245 /*
246  * grab the security keyring for a server socket
247  */
rxrpc_server_keyring(struct rxrpc_sock * rx,char __user * optval,int optlen)248 int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
249 			 int optlen)
250 {
251 	struct key *key;
252 	char *description;
253 
254 	_enter("");
255 
256 	if (optlen <= 0 || optlen > PAGE_SIZE - 1)
257 		return -EINVAL;
258 
259 	description = kmalloc(optlen + 1, GFP_KERNEL);
260 	if (!description)
261 		return -ENOMEM;
262 
263 	if (copy_from_user(description, optval, optlen)) {
264 		kfree(description);
265 		return -EFAULT;
266 	}
267 	description[optlen] = 0;
268 
269 	key = request_key(&key_type_keyring, description, NULL);
270 	if (IS_ERR(key)) {
271 		kfree(description);
272 		_leave(" = %ld", PTR_ERR(key));
273 		return PTR_ERR(key);
274 	}
275 
276 	rx->securities = key;
277 	kfree(description);
278 	_leave(" = 0 [key %x]", key->serial);
279 	return 0;
280 }
281 
282 /*
283  * generate a server data key
284  */
rxrpc_get_server_data_key(struct rxrpc_connection * conn,const void * session_key,time_t expiry,u32 kvno)285 int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
286 			      const void *session_key,
287 			      time_t expiry,
288 			      u32 kvno)
289 {
290 	const struct cred *cred = current_cred();
291 	struct key *key;
292 	int ret;
293 
294 	struct {
295 		u32 kver;
296 		struct rxkad_key tsec;
297 	} data;
298 
299 	_enter("");
300 
301 	key = key_alloc(&key_type_rxrpc, "x", 0, 0, cred, 0,
302 			KEY_ALLOC_NOT_IN_QUOTA);
303 	if (IS_ERR(key)) {
304 		_leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
305 		return -ENOMEM;
306 	}
307 
308 	_debug("key %d", key_serial(key));
309 
310 	data.kver = 1;
311 	data.tsec.security_index = 2;
312 	data.tsec.ticket_len = 0;
313 	data.tsec.expiry = expiry;
314 	data.tsec.kvno = 0;
315 
316 	memcpy(&data.tsec.session_key, session_key,
317 	       sizeof(data.tsec.session_key));
318 
319 	ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
320 	if (ret < 0)
321 		goto error;
322 
323 	conn->key = key;
324 	_leave(" = 0 [%d]", key_serial(key));
325 	return 0;
326 
327 error:
328 	key_revoke(key);
329 	key_put(key);
330 	_leave(" = -ENOMEM [ins %d]", ret);
331 	return -ENOMEM;
332 }
333 EXPORT_SYMBOL(rxrpc_get_server_data_key);
334 
335 /**
336  * rxrpc_get_null_key - Generate a null RxRPC key
337  * @keyname: The name to give the key.
338  *
339  * Generate a null RxRPC key that can be used to indicate anonymous security is
340  * required for a particular domain.
341  */
rxrpc_get_null_key(const char * keyname)342 struct key *rxrpc_get_null_key(const char *keyname)
343 {
344 	const struct cred *cred = current_cred();
345 	struct key *key;
346 	int ret;
347 
348 	key = key_alloc(&key_type_rxrpc, keyname, 0, 0, cred,
349 			KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
350 	if (IS_ERR(key))
351 		return key;
352 
353 	ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
354 	if (ret < 0) {
355 		key_revoke(key);
356 		key_put(key);
357 		return ERR_PTR(ret);
358 	}
359 
360 	return key;
361 }
362 EXPORT_SYMBOL(rxrpc_get_null_key);
363