ar-key.c 8.0 KB

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