3
* The Regents of the University of Michigan
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
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
32
* Copyright (C) 1998 by the FundsXpress, INC.
34
* All rights reserved.
36
* Export of this software from the United States of America may require
37
* a specific license from the United States Government. It is the
38
* responsibility of any person or organization contemplating export to
39
* obtain such a license before exporting.
41
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
42
* distribute this software and its documentation for any purpose and
43
* without fee is hereby granted, provided that the above copyright
44
* notice appear in all copies and that both that copyright notice and
45
* this permission notice appear in supporting documentation, and that
46
* the name of FundsXpress. not be used in advertising or publicity pertaining
47
* to distribution of the software without specific, written prior
48
* permission. FundsXpress makes no representations about the suitability of
49
* this software for any purpose. It is provided "as is" without express
50
* or implied warranty.
52
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
53
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
54
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
57
#include <linux/err.h>
58
#include <linux/types.h>
59
#include <linux/crypto.h>
60
#include <linux/sunrpc/gss_krb5.h>
61
#include <linux/sunrpc/xdr.h>
64
# define RPCDBG_FACILITY RPCDBG_AUTH
68
* This is the n-fold function as described in rfc3961, sec 5.1
69
* Taken from MIT Kerberos and modified.
72
static void krb5_nfold(u32 inbits, const u8 *in,
78
/* the code below is more readable if I make these bytes
84
/* first compute lcm(n,k) */
95
lcm = outbits*inbits/a;
97
/* now do the real work */
99
memset(out, 0, outbits);
102
/* this will end up cycling through k lcm(k,n)/k times, which
104
for (i = lcm-1; i >= 0; i--) {
105
/* compute the msbit in k which gets added into this byte */
107
/* first, start with the msbit in the first,
110
/* then, for each byte, shift to the right
111
* for each repetition */
112
+ (((inbits << 3) + 13) * (i/inbits))
113
/* last, pick out the correct byte within
114
* that shifted repetition */
115
+ ((inbits - (i % inbits)) << 3)
118
/* pull out the byte value itself */
119
byte += (((in[((inbits - 1) - (msbit >> 3)) % inbits] << 8)|
120
(in[((inbits) - (msbit >> 3)) % inbits]))
121
>> ((msbit & 7) + 1)) & 0xff;
123
/* do the addition */
124
byte += out[i % outbits];
125
out[i % outbits] = byte & 0xff;
127
/* keep around the carry bit, if any */
132
/* if there's a carry bit left over, add it back in */
134
for (i = outbits - 1; i >= 0; i--) {
135
/* do the addition */
137
out[i] = byte & 0xff;
139
/* keep around the carry bit, if any */
146
* This is the DK (derive_key) function as described in rfc3961, sec 5.1
147
* Taken from MIT Kerberos and modified.
150
u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e,
151
const struct xdr_netobj *inkey,
152
struct xdr_netobj *outkey,
153
const struct xdr_netobj *in_constant,
156
size_t blocksize, keybytes, keylength, n;
157
unsigned char *inblockdata, *outblockdata, *rawkey;
158
struct xdr_netobj inblock, outblock;
159
struct crypto_blkcipher *cipher;
162
blocksize = gk5e->blocksize;
163
keybytes = gk5e->keybytes;
164
keylength = gk5e->keylength;
166
if ((inkey->len != keylength) || (outkey->len != keylength))
169
cipher = crypto_alloc_blkcipher(gk5e->encrypt_name, 0,
173
if (crypto_blkcipher_setkey(cipher, inkey->data, inkey->len))
176
/* allocate and set up buffers */
179
inblockdata = kmalloc(blocksize, gfp_mask);
180
if (inblockdata == NULL)
181
goto err_free_cipher;
183
outblockdata = kmalloc(blocksize, gfp_mask);
184
if (outblockdata == NULL)
187
rawkey = kmalloc(keybytes, gfp_mask);
191
inblock.data = (char *) inblockdata;
192
inblock.len = blocksize;
194
outblock.data = (char *) outblockdata;
195
outblock.len = blocksize;
197
/* initialize the input block */
199
if (in_constant->len == inblock.len) {
200
memcpy(inblock.data, in_constant->data, inblock.len);
202
krb5_nfold(in_constant->len * 8, in_constant->data,
203
inblock.len * 8, inblock.data);
206
/* loop encrypting the blocks until enough key bytes are generated */
209
while (n < keybytes) {
210
(*(gk5e->encrypt))(cipher, NULL, inblock.data,
211
outblock.data, inblock.len);
213
if ((keybytes - n) <= outblock.len) {
214
memcpy(rawkey + n, outblock.data, (keybytes - n));
218
memcpy(rawkey + n, outblock.data, outblock.len);
219
memcpy(inblock.data, outblock.data, outblock.len);
223
/* postprocess the key */
225
inblock.data = (char *) rawkey;
226
inblock.len = keybytes;
228
BUG_ON(gk5e->mk_key == NULL);
229
ret = (*(gk5e->mk_key))(gk5e, &inblock, outkey);
231
dprintk("%s: got %d from mk_key function for '%s'\n",
232
__func__, ret, gk5e->encrypt_name);
236
/* clean memory, free resources and exit */
241
memset(rawkey, 0, keybytes);
244
memset(outblockdata, 0, blocksize);
247
memset(inblockdata, 0, blocksize);
250
crypto_free_blkcipher(cipher);
255
#define smask(step) ((1<<step)-1)
256
#define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step)))
257
#define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1)
259
static void mit_des_fixup_key_parity(u8 key[8])
262
for (i = 0; i < 8; i++) {
264
key[i] |= 1^parity_char(key[i]);
269
* This is the des3 key derivation postprocess function
271
u32 gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e,
272
struct xdr_netobj *randombits,
273
struct xdr_netobj *key)
278
if (key->len != 24) {
279
dprintk("%s: key->len is %d\n", __func__, key->len);
282
if (randombits->len != 21) {
283
dprintk("%s: randombits->len is %d\n",
284
__func__, randombits->len);
288
/* take the seven bytes, move them around into the top 7 bits of the
289
8 key bytes, then compute the parity bits. Do this three times. */
291
for (i = 0; i < 3; i++) {
292
memcpy(key->data + i*8, randombits->data + i*7, 7);
293
key->data[i*8+7] = (((key->data[i*8]&1)<<1) |
294
((key->data[i*8+1]&1)<<2) |
295
((key->data[i*8+2]&1)<<3) |
296
((key->data[i*8+3]&1)<<4) |
297
((key->data[i*8+4]&1)<<5) |
298
((key->data[i*8+5]&1)<<6) |
299
((key->data[i*8+6]&1)<<7));
301
mit_des_fixup_key_parity(key->data + i*8);
309
* This is the aes key derivation postprocess function
311
u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
312
struct xdr_netobj *randombits,
313
struct xdr_netobj *key)
317
if (key->len != 16 && key->len != 32) {
318
dprintk("%s: key->len is %d\n", __func__, key->len);
321
if (randombits->len != 16 && randombits->len != 32) {
322
dprintk("%s: randombits->len is %d\n",
323
__func__, randombits->len);
326
if (randombits->len != key->len) {
327
dprintk("%s: randombits->len is %d, key->len is %d\n",
328
__func__, randombits->len, key->len);
331
memcpy(key->data, randombits->data, key->len);