Lines Matching +full:key +full:- +full:2

1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* RxRPC key management
17 #include <linux/key-type.h>
22 #include <keys/rxrpc-type.h>
23 #include <keys/user-type.h>
24 #include "ar-internal.h"
28 static void rxrpc_destroy(struct key *);
29 static void rxrpc_describe(const struct key *, struct seq_file *);
30 static long rxrpc_read(const struct key *, char *, size_t);
50 * - the caller guarantees we have at least 4 words
62 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), in rxrpc_preparse_xdr_rxkad()
66 return -EKEYREJECTED; in rxrpc_preparse_xdr_rxkad()
70 return -EKEYREJECTED; in rxrpc_preparse_xdr_rxkad()
72 return -EKEYREJECTED; in rxrpc_preparse_xdr_rxkad()
74 plen = sizeof(*token) + sizeof(*token->kad) + tktlen; in rxrpc_preparse_xdr_rxkad()
75 prep->quotalen = datalen + plen; in rxrpc_preparse_xdr_rxkad()
77 plen -= sizeof(*token); in rxrpc_preparse_xdr_rxkad()
80 return -ENOMEM; in rxrpc_preparse_xdr_rxkad()
82 token->kad = kzalloc(plen, GFP_KERNEL); in rxrpc_preparse_xdr_rxkad()
83 if (!token->kad) { in rxrpc_preparse_xdr_rxkad()
85 return -ENOMEM; in rxrpc_preparse_xdr_rxkad()
88 token->security_index = RXRPC_SECURITY_RXKAD; in rxrpc_preparse_xdr_rxkad()
89 token->kad->ticket_len = tktlen; in rxrpc_preparse_xdr_rxkad()
90 token->kad->vice_id = ntohl(xdr[0]); in rxrpc_preparse_xdr_rxkad()
91 token->kad->kvno = ntohl(xdr[1]); in rxrpc_preparse_xdr_rxkad()
92 token->kad->start = ntohl(xdr[4]); in rxrpc_preparse_xdr_rxkad()
93 token->kad->expiry = ntohl(xdr[5]); in rxrpc_preparse_xdr_rxkad()
94 token->kad->primary_flag = ntohl(xdr[6]); in rxrpc_preparse_xdr_rxkad()
95 memcpy(&token->kad->session_key, &xdr[2], 8); in rxrpc_preparse_xdr_rxkad()
96 memcpy(&token->kad->ticket, &xdr[8], tktlen); in rxrpc_preparse_xdr_rxkad()
98 _debug("SCIX: %u", token->security_index); in rxrpc_preparse_xdr_rxkad()
99 _debug("TLEN: %u", token->kad->ticket_len); in rxrpc_preparse_xdr_rxkad()
100 _debug("EXPY: %x", token->kad->expiry); in rxrpc_preparse_xdr_rxkad()
101 _debug("KVNO: %u", token->kad->kvno); in rxrpc_preparse_xdr_rxkad()
102 _debug("PRIM: %u", token->kad->primary_flag); in rxrpc_preparse_xdr_rxkad()
104 token->kad->session_key[0], token->kad->session_key[1], in rxrpc_preparse_xdr_rxkad()
105 token->kad->session_key[2], token->kad->session_key[3], in rxrpc_preparse_xdr_rxkad()
106 token->kad->session_key[4], token->kad->session_key[5], in rxrpc_preparse_xdr_rxkad()
107 token->kad->session_key[6], token->kad->session_key[7]); in rxrpc_preparse_xdr_rxkad()
108 if (token->kad->ticket_len >= 8) in rxrpc_preparse_xdr_rxkad()
110 token->kad->ticket[0], token->kad->ticket[1], in rxrpc_preparse_xdr_rxkad()
111 token->kad->ticket[2], token->kad->ticket[3], in rxrpc_preparse_xdr_rxkad()
112 token->kad->ticket[4], token->kad->ticket[5], in rxrpc_preparse_xdr_rxkad()
113 token->kad->ticket[6], token->kad->ticket[7]); in rxrpc_preparse_xdr_rxkad()
116 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); in rxrpc_preparse_xdr_rxkad()
119 for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0]; in rxrpc_preparse_xdr_rxkad()
121 pptoken = &(*pptoken)->next) in rxrpc_preparse_xdr_rxkad()
124 expiry = rxrpc_u32_to_time64(token->kad->expiry); in rxrpc_preparse_xdr_rxkad()
125 if (expiry < prep->expiry) in rxrpc_preparse_xdr_rxkad()
126 prep->expiry = expiry; in rxrpc_preparse_xdr_rxkad()
134 * - the caller guarantees we have more than 7 words
138 const __be32 *xdr = prep->data, *token, *p; in rxrpc_preparse_xdr()
141 size_t datalen = prep->datalen; in rxrpc_preparse_xdr()
145 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), in rxrpc_preparse_xdr()
146 prep->datalen); in rxrpc_preparse_xdr()
159 datalen -= 4; in rxrpc_preparse_xdr()
165 datalen -= 4; in rxrpc_preparse_xdr()
179 datalen -= paddedlen; in rxrpc_preparse_xdr()
180 xdr += paddedlen >> 2; in rxrpc_preparse_xdr()
186 datalen -= 4; in rxrpc_preparse_xdr()
199 datalen -= 4; in rxrpc_preparse_xdr()
204 datalen -= paddedlen; in rxrpc_preparse_xdr()
205 p += paddedlen >> 2; in rxrpc_preparse_xdr()
207 } while (--loop > 0); in rxrpc_preparse_xdr()
214 * - we ignore the cellname, relying on the key to be correctly named in rxrpc_preparse_xdr()
216 ret = -EPROTONOSUPPORT; in rxrpc_preparse_xdr()
223 toklen -= 4; in rxrpc_preparse_xdr()
232 ret2 = -EPROTONOSUPPORT; in rxrpc_preparse_xdr()
240 case -EPROTONOSUPPORT: in rxrpc_preparse_xdr()
242 case -ENOPKG: in rxrpc_preparse_xdr()
244 ret = -ENOPKG; in rxrpc_preparse_xdr()
251 } while (--ntoken > 0); in rxrpc_preparse_xdr()
258 _leave(" = -EPROTO"); in rxrpc_preparse_xdr()
259 return -EPROTO; in rxrpc_preparse_xdr()
263 * Preparse an rxrpc defined key.
267 * 0 4 key interface version number
268 * 4 2 security index (type)
269 * 6 2 ticket length
270 * 8 4 key expiry time (time_t)
272 * 16 8 session key
275 * if no data is provided, then a no-security key is made
286 _enter("%zu", prep->datalen); in rxrpc_preparse()
288 /* handle a no-security key */ in rxrpc_preparse()
289 if (!prep->data && prep->datalen == 0) in rxrpc_preparse()
293 if (prep->datalen > 7 * 4) { in rxrpc_preparse()
295 if (ret != -EPROTO) in rxrpc_preparse()
299 /* get the key interface version number */ in rxrpc_preparse()
300 ret = -EINVAL; in rxrpc_preparse()
301 if (prep->datalen <= 4 || !prep->data) in rxrpc_preparse()
303 memcpy(&kver, prep->data, sizeof(kver)); in rxrpc_preparse()
304 prep->data += sizeof(kver); in rxrpc_preparse()
305 prep->datalen -= sizeof(kver); in rxrpc_preparse()
307 _debug("KEY I/F VERSION: %u", kver); in rxrpc_preparse()
309 ret = -EKEYREJECTED; in rxrpc_preparse()
313 /* deal with a version 1 key */ in rxrpc_preparse()
314 ret = -EINVAL; in rxrpc_preparse()
315 if (prep->datalen < sizeof(*v1)) in rxrpc_preparse()
318 v1 = prep->data; in rxrpc_preparse()
319 if (prep->datalen != sizeof(*v1) + v1->ticket_length) in rxrpc_preparse()
322 _debug("SCIX: %u", v1->security_index); in rxrpc_preparse()
323 _debug("TLEN: %u", v1->ticket_length); in rxrpc_preparse()
324 _debug("EXPY: %x", v1->expiry); in rxrpc_preparse()
325 _debug("KVNO: %u", v1->kvno); in rxrpc_preparse()
327 v1->session_key[0], v1->session_key[1], in rxrpc_preparse()
328 v1->session_key[2], v1->session_key[3], in rxrpc_preparse()
329 v1->session_key[4], v1->session_key[5], in rxrpc_preparse()
330 v1->session_key[6], v1->session_key[7]); in rxrpc_preparse()
331 if (v1->ticket_length >= 8) in rxrpc_preparse()
333 v1->ticket[0], v1->ticket[1], in rxrpc_preparse()
334 v1->ticket[2], v1->ticket[3], in rxrpc_preparse()
335 v1->ticket[4], v1->ticket[5], in rxrpc_preparse()
336 v1->ticket[6], v1->ticket[7]); in rxrpc_preparse()
338 ret = -EPROTONOSUPPORT; in rxrpc_preparse()
339 if (v1->security_index != RXRPC_SECURITY_RXKAD) in rxrpc_preparse()
342 plen = sizeof(*token->kad) + v1->ticket_length; in rxrpc_preparse()
343 prep->quotalen = plen + sizeof(*token); in rxrpc_preparse()
345 ret = -ENOMEM; in rxrpc_preparse()
349 token->kad = kzalloc(plen, GFP_KERNEL); in rxrpc_preparse()
350 if (!token->kad) in rxrpc_preparse()
353 token->security_index = RXRPC_SECURITY_RXKAD; in rxrpc_preparse()
354 token->kad->ticket_len = v1->ticket_length; in rxrpc_preparse()
355 token->kad->expiry = v1->expiry; in rxrpc_preparse()
356 token->kad->kvno = v1->kvno; in rxrpc_preparse()
357 memcpy(&token->kad->session_key, &v1->session_key, 8); in rxrpc_preparse()
358 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); in rxrpc_preparse()
361 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); in rxrpc_preparse()
364 pp = (struct rxrpc_key_token **)&prep->payload.data[0]; in rxrpc_preparse()
366 pp = &(*pp)->next; in rxrpc_preparse()
368 expiry = rxrpc_u32_to_time64(token->kad->expiry); in rxrpc_preparse()
369 if (expiry < prep->expiry) in rxrpc_preparse()
370 prep->expiry = expiry; in rxrpc_preparse()
388 next = token->next; in rxrpc_free_token_list()
389 switch (token->security_index) { in rxrpc_free_token_list()
391 kfree(token->kad); in rxrpc_free_token_list()
394 pr_err("Unknown token type %x on rxrpc key\n", in rxrpc_free_token_list()
395 token->security_index); in rxrpc_free_token_list()
408 rxrpc_free_token_list(prep->payload.data[0]); in rxrpc_free_preparse()
412 * dispose of the data dangling from the corpse of a rxrpc key
414 static void rxrpc_destroy(struct key *key) in rxrpc_destroy() argument
416 rxrpc_free_token_list(key->payload.data[0]); in rxrpc_destroy()
420 * describe the rxrpc key
422 static void rxrpc_describe(const struct key *key, struct seq_file *m) in rxrpc_describe() argument
427 seq_puts(m, key->description); in rxrpc_describe()
429 for (token = key->payload.data[0]; token; token = token->next) { in rxrpc_describe()
432 switch (token->security_index) { in rxrpc_describe()
437 seq_printf(m, "%u", token->security_index); in rxrpc_describe()
446 * grab the security key for a socket
450 struct key *key; in rxrpc_request_key() local
455 if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities) in rxrpc_request_key()
456 return -EINVAL; in rxrpc_request_key()
462 key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL); in rxrpc_request_key()
463 if (IS_ERR(key)) { in rxrpc_request_key()
465 _leave(" = %ld", PTR_ERR(key)); in rxrpc_request_key()
466 return PTR_ERR(key); in rxrpc_request_key()
469 rx->key = key; in rxrpc_request_key()
471 _leave(" = 0 [key %x]", key->serial); in rxrpc_request_key()
476 * generate a server data key
484 struct key *key; in rxrpc_get_server_data_key() local
494 key = key_alloc(&key_type_rxrpc, "x", in rxrpc_get_server_data_key()
497 if (IS_ERR(key)) { in rxrpc_get_server_data_key()
498 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); in rxrpc_get_server_data_key()
499 return -ENOMEM; in rxrpc_get_server_data_key()
502 _debug("key %d", key_serial(key)); in rxrpc_get_server_data_key()
512 ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); in rxrpc_get_server_data_key()
516 conn->key = key; in rxrpc_get_server_data_key()
517 _leave(" = 0 [%d]", key_serial(key)); in rxrpc_get_server_data_key()
521 key_revoke(key); in rxrpc_get_server_data_key()
522 key_put(key); in rxrpc_get_server_data_key()
523 _leave(" = -ENOMEM [ins %d]", ret); in rxrpc_get_server_data_key()
524 return -ENOMEM; in rxrpc_get_server_data_key()
529 * rxrpc_get_null_key - Generate a null RxRPC key
530 * @keyname: The name to give the key.
532 * Generate a null RxRPC key that can be used to indicate anonymous security is
535 struct key *rxrpc_get_null_key(const char *keyname) in rxrpc_get_null_key()
538 struct key *key; in rxrpc_get_null_key() local
541 key = key_alloc(&key_type_rxrpc, keyname, in rxrpc_get_null_key()
544 if (IS_ERR(key)) in rxrpc_get_null_key()
545 return key; in rxrpc_get_null_key()
547 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL); in rxrpc_get_null_key()
549 key_revoke(key); in rxrpc_get_null_key()
550 key_put(key); in rxrpc_get_null_key()
554 return key; in rxrpc_get_null_key()
559 * read the contents of an rxrpc key
560 * - this returns the result in XDR form
562 static long rxrpc_read(const struct key *key, in rxrpc_read() argument
573 /* we don't know what form we should return non-AFS keys in */ in rxrpc_read()
574 if (memcmp(key->description, "afs@", 4) != 0) in rxrpc_read()
575 return -EOPNOTSUPP; in rxrpc_read()
576 cnlen = strlen(key->description + 4); in rxrpc_read()
582 size = 2 * 4; /* flags, cellname len */ in rxrpc_read()
587 for (token = key->payload.data[0]; token; token = token->next) { in rxrpc_read()
590 switch (token->security_index) { in rxrpc_read()
592 toksize += 8 * 4; /* viceid, kvno, key*2, begin, in rxrpc_read()
594 if (!token->no_leak_key) in rxrpc_read()
595 toksize += RND(token->kad->ticket_len); in rxrpc_read()
599 pr_err("Unsupported key token type (%u)\n", in rxrpc_read()
600 token->security_index); in rxrpc_read()
601 return -ENOPKG; in rxrpc_read()
606 return -EIO; in rxrpc_read()
629 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ in rxrpc_read()
630 xdr += (_l + 3) >> 2; \ in rxrpc_read()
637 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ in rxrpc_read()
638 xdr += (_l + 3) >> 2; \ in rxrpc_read()
644 xdr += 8 >> 2; \ in rxrpc_read()
653 ENCODE_DATA(cnlen, key->description + 4); /* cellname */ in rxrpc_read()
657 for (token = key->payload.data[0]; token; token = token->next) { in rxrpc_read()
661 ENCODE(token->security_index); in rxrpc_read()
663 switch (token->security_index) { in rxrpc_read()
665 ENCODE(token->kad->vice_id); in rxrpc_read()
666 ENCODE(token->kad->kvno); in rxrpc_read()
667 ENCODE_BYTES(8, token->kad->session_key); in rxrpc_read()
668 ENCODE(token->kad->start); in rxrpc_read()
669 ENCODE(token->kad->expiry); in rxrpc_read()
670 ENCODE(token->kad->primary_flag); in rxrpc_read()
671 if (token->no_leak_key) in rxrpc_read()
674 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); in rxrpc_read()
678 pr_err("Unsupported key token type (%u)\n", in rxrpc_read()
679 token->security_index); in rxrpc_read()
680 return -ENOPKG; in rxrpc_read()
683 if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr != in rxrpc_read()
685 return -EIO; in rxrpc_read()
694 return -EIO; in rxrpc_read()
695 if (WARN_ON((unsigned long)xdr - (unsigned long)buffer != size)) in rxrpc_read()
696 return -EIO; in rxrpc_read()