gss_krb5_keys.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * COPYRIGHT (c) 2008
  3. * The Regents of the University of Michigan
  4. * ALL RIGHTS RESERVED
  5. *
  6. * Permission is granted to use, copy, create derivative works
  7. * and redistribute this software and such derivative works
  8. * for any purpose, so long as the name of The University of
  9. * Michigan is not used in any advertising or publicity
  10. * pertaining to the use of distribution of this software
  11. * without specific, written prior authorization. If the
  12. * above copyright notice or any other identification of the
  13. * University of Michigan is included in any copy of any
  14. * portion of this software, then the disclaimer below must
  15. * also be included.
  16. *
  17. * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
  18. * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
  19. * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
  20. * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
  21. * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
  22. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
  23. * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
  24. * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
  25. * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
  26. * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
  27. * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGES.
  29. */
  30. /*
  31. * Copyright (C) 1998 by the FundsXpress, INC.
  32. *
  33. * All rights reserved.
  34. *
  35. * Export of this software from the United States of America may require
  36. * a specific license from the United States Government. It is the
  37. * responsibility of any person or organization contemplating export to
  38. * obtain such a license before exporting.
  39. *
  40. * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  41. * distribute this software and its documentation for any purpose and
  42. * without fee is hereby granted, provided that the above copyright
  43. * notice appear in all copies and that both that copyright notice and
  44. * this permission notice appear in supporting documentation, and that
  45. * the name of FundsXpress. not be used in advertising or publicity pertaining
  46. * to distribution of the software without specific, written prior
  47. * permission. FundsXpress makes no representations about the suitability of
  48. * this software for any purpose. It is provided "as is" without express
  49. * or implied warranty.
  50. *
  51. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  52. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  53. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  54. */
  55. #include <linux/err.h>
  56. #include <linux/types.h>
  57. #include <linux/crypto.h>
  58. #include <linux/sunrpc/gss_krb5.h>
  59. #include <linux/sunrpc/xdr.h>
  60. #ifdef RPC_DEBUG
  61. # define RPCDBG_FACILITY RPCDBG_AUTH
  62. #endif
  63. /*
  64. * This is the n-fold function as described in rfc3961, sec 5.1
  65. * Taken from MIT Kerberos and modified.
  66. */
  67. static void krb5_nfold(u32 inbits, const u8 *in,
  68. u32 outbits, u8 *out)
  69. {
  70. int a, b, c, lcm;
  71. int byte, i, msbit;
  72. /* the code below is more readable if I make these bytes
  73. instead of bits */
  74. inbits >>= 3;
  75. outbits >>= 3;
  76. /* first compute lcm(n,k) */
  77. a = outbits;
  78. b = inbits;
  79. while (b != 0) {
  80. c = b;
  81. b = a%b;
  82. a = c;
  83. }
  84. lcm = outbits*inbits/a;
  85. /* now do the real work */
  86. memset(out, 0, outbits);
  87. byte = 0;
  88. /* this will end up cycling through k lcm(k,n)/k times, which
  89. is correct */
  90. for (i = lcm-1; i >= 0; i--) {
  91. /* compute the msbit in k which gets added into this byte */
  92. msbit = (
  93. /* first, start with the msbit in the first,
  94. * unrotated byte */
  95. ((inbits << 3) - 1)
  96. /* then, for each byte, shift to the right
  97. * for each repetition */
  98. + (((inbits << 3) + 13) * (i/inbits))
  99. /* last, pick out the correct byte within
  100. * that shifted repetition */
  101. + ((inbits - (i % inbits)) << 3)
  102. ) % (inbits << 3);
  103. /* pull out the byte value itself */
  104. byte += (((in[((inbits - 1) - (msbit >> 3)) % inbits] << 8)|
  105. (in[((inbits) - (msbit >> 3)) % inbits]))
  106. >> ((msbit & 7) + 1)) & 0xff;
  107. /* do the addition */
  108. byte += out[i % outbits];
  109. out[i % outbits] = byte & 0xff;
  110. /* keep around the carry bit, if any */
  111. byte >>= 8;
  112. }
  113. /* if there's a carry bit left over, add it back in */
  114. if (byte) {
  115. for (i = outbits - 1; i >= 0; i--) {
  116. /* do the addition */
  117. byte += out[i];
  118. out[i] = byte & 0xff;
  119. /* keep around the carry bit, if any */
  120. byte >>= 8;
  121. }
  122. }
  123. }
  124. /*
  125. * This is the DK (derive_key) function as described in rfc3961, sec 5.1
  126. * Taken from MIT Kerberos and modified.
  127. */
  128. u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e,
  129. const struct xdr_netobj *inkey,
  130. struct xdr_netobj *outkey,
  131. const struct xdr_netobj *in_constant,
  132. gfp_t gfp_mask)
  133. {
  134. size_t blocksize, keybytes, keylength, n;
  135. unsigned char *inblockdata, *outblockdata, *rawkey;
  136. struct xdr_netobj inblock, outblock;
  137. struct crypto_blkcipher *cipher;
  138. u32 ret = EINVAL;
  139. blocksize = gk5e->blocksize;
  140. keybytes = gk5e->keybytes;
  141. keylength = gk5e->keylength;
  142. if ((inkey->len != keylength) || (outkey->len != keylength))
  143. goto err_return;
  144. cipher = crypto_alloc_blkcipher(gk5e->encrypt_name, 0,
  145. CRYPTO_ALG_ASYNC);
  146. if (IS_ERR(cipher))
  147. goto err_return;
  148. if (crypto_blkcipher_setkey(cipher, inkey->data, inkey->len))
  149. goto err_return;
  150. /* allocate and set up buffers */
  151. ret = ENOMEM;
  152. inblockdata = kmalloc(blocksize, gfp_mask);
  153. if (inblockdata == NULL)
  154. goto err_free_cipher;
  155. outblockdata = kmalloc(blocksize, gfp_mask);
  156. if (outblockdata == NULL)
  157. goto err_free_in;
  158. rawkey = kmalloc(keybytes, gfp_mask);
  159. if (rawkey == NULL)
  160. goto err_free_out;
  161. inblock.data = (char *) inblockdata;
  162. inblock.len = blocksize;
  163. outblock.data = (char *) outblockdata;
  164. outblock.len = blocksize;
  165. /* initialize the input block */
  166. if (in_constant->len == inblock.len) {
  167. memcpy(inblock.data, in_constant->data, inblock.len);
  168. } else {
  169. krb5_nfold(in_constant->len * 8, in_constant->data,
  170. inblock.len * 8, inblock.data);
  171. }
  172. /* loop encrypting the blocks until enough key bytes are generated */
  173. n = 0;
  174. while (n < keybytes) {
  175. (*(gk5e->encrypt))(cipher, NULL, inblock.data,
  176. outblock.data, inblock.len);
  177. if ((keybytes - n) <= outblock.len) {
  178. memcpy(rawkey + n, outblock.data, (keybytes - n));
  179. break;
  180. }
  181. memcpy(rawkey + n, outblock.data, outblock.len);
  182. memcpy(inblock.data, outblock.data, outblock.len);
  183. n += outblock.len;
  184. }
  185. /* postprocess the key */
  186. inblock.data = (char *) rawkey;
  187. inblock.len = keybytes;
  188. BUG_ON(gk5e->mk_key == NULL);
  189. ret = (*(gk5e->mk_key))(gk5e, &inblock, outkey);
  190. if (ret) {
  191. dprintk("%s: got %d from mk_key function for '%s'\n",
  192. __func__, ret, gk5e->encrypt_name);
  193. goto err_free_raw;
  194. }
  195. /* clean memory, free resources and exit */
  196. ret = 0;
  197. err_free_raw:
  198. memset(rawkey, 0, keybytes);
  199. kfree(rawkey);
  200. err_free_out:
  201. memset(outblockdata, 0, blocksize);
  202. kfree(outblockdata);
  203. err_free_in:
  204. memset(inblockdata, 0, blocksize);
  205. kfree(inblockdata);
  206. err_free_cipher:
  207. crypto_free_blkcipher(cipher);
  208. err_return:
  209. return ret;
  210. }
  211. #define smask(step) ((1<<step)-1)
  212. #define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step)))
  213. #define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1)
  214. static void mit_des_fixup_key_parity(u8 key[8])
  215. {
  216. int i;
  217. for (i = 0; i < 8; i++) {
  218. key[i] &= 0xfe;
  219. key[i] |= 1^parity_char(key[i]);
  220. }
  221. }
  222. /*
  223. * This is the des3 key derivation postprocess function
  224. */
  225. u32 gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e,
  226. struct xdr_netobj *randombits,
  227. struct xdr_netobj *key)
  228. {
  229. int i;
  230. u32 ret = EINVAL;
  231. if (key->len != 24) {
  232. dprintk("%s: key->len is %d\n", __func__, key->len);
  233. goto err_out;
  234. }
  235. if (randombits->len != 21) {
  236. dprintk("%s: randombits->len is %d\n",
  237. __func__, randombits->len);
  238. goto err_out;
  239. }
  240. /* take the seven bytes, move them around into the top 7 bits of the
  241. 8 key bytes, then compute the parity bits. Do this three times. */
  242. for (i = 0; i < 3; i++) {
  243. memcpy(key->data + i*8, randombits->data + i*7, 7);
  244. key->data[i*8+7] = (((key->data[i*8]&1)<<1) |
  245. ((key->data[i*8+1]&1)<<2) |
  246. ((key->data[i*8+2]&1)<<3) |
  247. ((key->data[i*8+3]&1)<<4) |
  248. ((key->data[i*8+4]&1)<<5) |
  249. ((key->data[i*8+5]&1)<<6) |
  250. ((key->data[i*8+6]&1)<<7));
  251. mit_des_fixup_key_parity(key->data + i*8);
  252. }
  253. ret = 0;
  254. err_out:
  255. return ret;
  256. }
  257. /*
  258. * This is the aes key derivation postprocess function
  259. */
  260. u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
  261. struct xdr_netobj *randombits,
  262. struct xdr_netobj *key)
  263. {
  264. u32 ret = EINVAL;
  265. if (key->len != 16 && key->len != 32) {
  266. dprintk("%s: key->len is %d\n", __func__, key->len);
  267. goto err_out;
  268. }
  269. if (randombits->len != 16 && randombits->len != 32) {
  270. dprintk("%s: randombits->len is %d\n",
  271. __func__, randombits->len);
  272. goto err_out;
  273. }
  274. if (randombits->len != key->len) {
  275. dprintk("%s: randombits->len is %d, key->len is %d\n",
  276. __func__, randombits->len, key->len);
  277. goto err_out;
  278. }
  279. memcpy(key->data, randombits->data, key->len);
  280. ret = 0;
  281. err_out:
  282. return ret;
  283. }