Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/net/sunrpc/auth_gss/gss_krb5_mech.c

Diff markup

Differences between /net/sunrpc/auth_gss/gss_krb5_mech.c (Version 2.6.35) and /net/sunrpc/auth_gss/gss_krb5_mech.c (Version 2.6.34)


  1 /*                                                  1 /*
  2  *  linux/net/sunrpc/gss_krb5_mech.c                2  *  linux/net/sunrpc/gss_krb5_mech.c
  3  *                                                  3  *
  4  *  Copyright (c) 2001-2008 The Regents of the !!   4  *  Copyright (c) 2001 The Regents of the University of Michigan.
  5  *  All rights reserved.                            5  *  All rights reserved.
  6  *                                                  6  *
  7  *  Andy Adamson <andros@umich.edu>                 7  *  Andy Adamson <andros@umich.edu>
  8  *  J. Bruce Fields <bfields@umich.edu>             8  *  J. Bruce Fields <bfields@umich.edu>
  9  *                                                  9  *
 10  *  Redistribution and use in source and binar     10  *  Redistribution and use in source and binary forms, with or without
 11  *  modification, are permitted provided that      11  *  modification, are permitted provided that the following conditions
 12  *  are met:                                       12  *  are met:
 13  *                                                 13  *
 14  *  1. Redistributions of source code must ret     14  *  1. Redistributions of source code must retain the above copyright
 15  *     notice, this list of conditions and the     15  *     notice, this list of conditions and the following disclaimer.
 16  *  2. Redistributions in binary form must rep     16  *  2. Redistributions in binary form must reproduce the above copyright
 17  *     notice, this list of conditions and the     17  *     notice, this list of conditions and the following disclaimer in the
 18  *     documentation and/or other materials pr     18  *     documentation and/or other materials provided with the distribution.
 19  *  3. Neither the name of the University nor      19  *  3. Neither the name of the University nor the names of its
 20  *     contributors may be used to endorse or      20  *     contributors may be used to endorse or promote products derived
 21  *     from this software without specific pri     21  *     from this software without specific prior written permission.
 22  *                                                 22  *
 23  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND AN     23  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 24  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO,     24  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 25  *  MERCHANTABILITY AND FITNESS FOR A PARTICUL     25  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 26  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS      26  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 27  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPEC     27  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 28  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      28  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 29  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     29  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 30  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND      30  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 31  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIA     31  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 32  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WA     32  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILI     33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 34  *                                                 34  *
 35  */                                                35  */
 36                                                    36 
 37 #include <linux/err.h>                             37 #include <linux/err.h>
 38 #include <linux/module.h>                          38 #include <linux/module.h>
 39 #include <linux/init.h>                            39 #include <linux/init.h>
 40 #include <linux/types.h>                           40 #include <linux/types.h>
 41 #include <linux/slab.h>                            41 #include <linux/slab.h>
 42 #include <linux/sunrpc/auth.h>                     42 #include <linux/sunrpc/auth.h>
 43 #include <linux/sunrpc/gss_krb5.h>                 43 #include <linux/sunrpc/gss_krb5.h>
 44 #include <linux/sunrpc/xdr.h>                      44 #include <linux/sunrpc/xdr.h>
 45 #include <linux/crypto.h>                          45 #include <linux/crypto.h>
 46                                                    46 
 47 #ifdef RPC_DEBUG                                   47 #ifdef RPC_DEBUG
 48 # define RPCDBG_FACILITY        RPCDBG_AUTH        48 # define RPCDBG_FACILITY        RPCDBG_AUTH
 49 #endif                                             49 #endif
 50                                                    50 
 51 static struct gss_api_mech gss_kerberos_mech;  << 
 52                                                << 
 53 static const struct gss_krb5_enctype supported << 
 54         /*                                     << 
 55          * DES (All DES enctypes are mapped to << 
 56          */                                    << 
 57         {                                      << 
 58           .etype = ENCTYPE_DES_CBC_RAW,        << 
 59           .ctype = CKSUMTYPE_RSA_MD5,          << 
 60           .name = "des-cbc-crc",               << 
 61           .encrypt_name = "cbc(des)",          << 
 62           .cksum_name = "md5",                 << 
 63           .encrypt = krb5_encrypt,             << 
 64           .decrypt = krb5_decrypt,             << 
 65           .mk_key = NULL,                      << 
 66           .signalg = SGN_ALG_DES_MAC_MD5,      << 
 67           .sealalg = SEAL_ALG_DES,             << 
 68           .keybytes = 7,                       << 
 69           .keylength = 8,                      << 
 70           .blocksize = 8,                      << 
 71           .conflen = 8,                        << 
 72           .cksumlength = 8,                    << 
 73           .keyed_cksum = 0,                    << 
 74         },                                     << 
 75         /*                                     << 
 76          * RC4-HMAC                            << 
 77          */                                    << 
 78         {                                      << 
 79           .etype = ENCTYPE_ARCFOUR_HMAC,       << 
 80           .ctype = CKSUMTYPE_HMAC_MD5_ARCFOUR, << 
 81           .name = "rc4-hmac",                  << 
 82           .encrypt_name = "ecb(arc4)",         << 
 83           .cksum_name = "hmac(md5)",           << 
 84           .encrypt = krb5_encrypt,             << 
 85           .decrypt = krb5_decrypt,             << 
 86           .mk_key = NULL,                      << 
 87           .signalg = SGN_ALG_HMAC_MD5,         << 
 88           .sealalg = SEAL_ALG_MICROSOFT_RC4,   << 
 89           .keybytes = 16,                      << 
 90           .keylength = 16,                     << 
 91           .blocksize = 1,                      << 
 92           .conflen = 8,                        << 
 93           .cksumlength = 8,                    << 
 94           .keyed_cksum = 1,                    << 
 95         },                                     << 
 96         /*                                     << 
 97          * 3DES                                << 
 98          */                                    << 
 99         {                                      << 
100           .etype = ENCTYPE_DES3_CBC_RAW,       << 
101           .ctype = CKSUMTYPE_HMAC_SHA1_DES3,   << 
102           .name = "des3-hmac-sha1",            << 
103           .encrypt_name = "cbc(des3_ede)",     << 
104           .cksum_name = "hmac(sha1)",          << 
105           .encrypt = krb5_encrypt,             << 
106           .decrypt = krb5_decrypt,             << 
107           .mk_key = gss_krb5_des3_make_key,    << 
108           .signalg = SGN_ALG_HMAC_SHA1_DES3_KD << 
109           .sealalg = SEAL_ALG_DES3KD,          << 
110           .keybytes = 21,                      << 
111           .keylength = 24,                     << 
112           .blocksize = 8,                      << 
113           .conflen = 8,                        << 
114           .cksumlength = 20,                   << 
115           .keyed_cksum = 1,                    << 
116         },                                     << 
117         /*                                     << 
118          * AES128                              << 
119          */                                    << 
120         {                                      << 
121           .etype = ENCTYPE_AES128_CTS_HMAC_SHA << 
122           .ctype = CKSUMTYPE_HMAC_SHA1_96_AES1 << 
123           .name = "aes128-cts",                << 
124           .encrypt_name = "cts(cbc(aes))",     << 
125           .cksum_name = "hmac(sha1)",          << 
126           .encrypt = krb5_encrypt,             << 
127           .decrypt = krb5_decrypt,             << 
128           .mk_key = gss_krb5_aes_make_key,     << 
129           .encrypt_v2 = gss_krb5_aes_encrypt,  << 
130           .decrypt_v2 = gss_krb5_aes_decrypt,  << 
131           .signalg = -1,                       << 
132           .sealalg = -1,                       << 
133           .keybytes = 16,                      << 
134           .keylength = 16,                     << 
135           .blocksize = 16,                     << 
136           .conflen = 16,                       << 
137           .cksumlength = 12,                   << 
138           .keyed_cksum = 1,                    << 
139         },                                     << 
140         /*                                     << 
141          * AES256                              << 
142          */                                    << 
143         {                                      << 
144           .etype = ENCTYPE_AES256_CTS_HMAC_SHA << 
145           .ctype = CKSUMTYPE_HMAC_SHA1_96_AES2 << 
146           .name = "aes256-cts",                << 
147           .encrypt_name = "cts(cbc(aes))",     << 
148           .cksum_name = "hmac(sha1)",          << 
149           .encrypt = krb5_encrypt,             << 
150           .decrypt = krb5_decrypt,             << 
151           .mk_key = gss_krb5_aes_make_key,     << 
152           .encrypt_v2 = gss_krb5_aes_encrypt,  << 
153           .decrypt_v2 = gss_krb5_aes_decrypt,  << 
154           .signalg = -1,                       << 
155           .sealalg = -1,                       << 
156           .keybytes = 32,                      << 
157           .keylength = 32,                     << 
158           .blocksize = 16,                     << 
159           .conflen = 16,                       << 
160           .cksumlength = 12,                   << 
161           .keyed_cksum = 1,                    << 
162         },                                     << 
163 };                                             << 
164                                                << 
165 static const int num_supported_enctypes =      << 
166         ARRAY_SIZE(supported_gss_krb5_enctypes << 
167                                                << 
168 static int                                     << 
169 supported_gss_krb5_enctype(int etype)          << 
170 {                                              << 
171         int i;                                 << 
172         for (i = 0; i < num_supported_enctypes << 
173                 if (supported_gss_krb5_enctype << 
174                         return 1;              << 
175         return 0;                              << 
176 }                                              << 
177                                                << 
178 static const struct gss_krb5_enctype *         << 
179 get_gss_krb5_enctype(int etype)                << 
180 {                                              << 
181         int i;                                 << 
182         for (i = 0; i < num_supported_enctypes << 
183                 if (supported_gss_krb5_enctype << 
184                         return &supported_gss_ << 
185         return NULL;                           << 
186 }                                              << 
187                                                << 
188 static const void *                                51 static const void *
189 simple_get_bytes(const void *p, const void *en     52 simple_get_bytes(const void *p, const void *end, void *res, int len)
190 {                                                  53 {
191         const void *q = (const void *)((const      54         const void *q = (const void *)((const char *)p + len);
192         if (unlikely(q > end || q < p))            55         if (unlikely(q > end || q < p))
193                 return ERR_PTR(-EFAULT);           56                 return ERR_PTR(-EFAULT);
194         memcpy(res, p, len);                       57         memcpy(res, p, len);
195         return q;                                  58         return q;
196 }                                                  59 }
197                                                    60 
198 static const void *                                61 static const void *
199 simple_get_netobj(const void *p, const void *e     62 simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
200 {                                                  63 {
201         const void *q;                             64         const void *q;
202         unsigned int len;                          65         unsigned int len;
203                                                    66 
204         p = simple_get_bytes(p, end, &len, siz     67         p = simple_get_bytes(p, end, &len, sizeof(len));
205         if (IS_ERR(p))                             68         if (IS_ERR(p))
206                 return p;                          69                 return p;
207         q = (const void *)((const char *)p + l     70         q = (const void *)((const char *)p + len);
208         if (unlikely(q > end || q < p))            71         if (unlikely(q > end || q < p))
209                 return ERR_PTR(-EFAULT);           72                 return ERR_PTR(-EFAULT);
210         res->data = kmemdup(p, len, GFP_NOFS);     73         res->data = kmemdup(p, len, GFP_NOFS);
211         if (unlikely(res->data == NULL))           74         if (unlikely(res->data == NULL))
212                 return ERR_PTR(-ENOMEM);           75                 return ERR_PTR(-ENOMEM);
213         res->len = len;                            76         res->len = len;
214         return q;                                  77         return q;
215 }                                                  78 }
216                                                    79 
217 static inline const void *                         80 static inline const void *
218 get_key(const void *p, const void *end,        !!  81 get_key(const void *p, const void *end, struct crypto_blkcipher **res)
219         struct krb5_ctx *ctx, struct crypto_bl << 
220 {                                                  82 {
221         struct xdr_netobj       key;               83         struct xdr_netobj       key;
222         int                     alg;               84         int                     alg;
                                                   >>  85         char                    *alg_name;
223                                                    86 
224         p = simple_get_bytes(p, end, &alg, siz     87         p = simple_get_bytes(p, end, &alg, sizeof(alg));
225         if (IS_ERR(p))                             88         if (IS_ERR(p))
226                 goto out_err;                      89                 goto out_err;
227                                                << 
228         switch (alg) {                         << 
229         case ENCTYPE_DES_CBC_CRC:              << 
230         case ENCTYPE_DES_CBC_MD4:              << 
231         case ENCTYPE_DES_CBC_MD5:              << 
232                 /* Map all these key types to  << 
233                 alg = ENCTYPE_DES_CBC_RAW;     << 
234                 break;                         << 
235         }                                      << 
236                                                << 
237         if (!supported_gss_krb5_enctype(alg))  << 
238                 printk(KERN_WARNING "gss_kerbe << 
239                         "encryption key algori << 
240                 goto out_err;                  << 
241         }                                      << 
242         p = simple_get_netobj(p, end, &key);       90         p = simple_get_netobj(p, end, &key);
243         if (IS_ERR(p))                             91         if (IS_ERR(p))
244                 goto out_err;                      92                 goto out_err;
245                                                    93 
246         *res = crypto_alloc_blkcipher(ctx->gk5 !!  94         switch (alg) {
247                                                !!  95                 case ENCTYPE_DES_CBC_RAW:
                                                   >>  96                         alg_name = "cbc(des)";
                                                   >>  97                         break;
                                                   >>  98                 default:
                                                   >>  99                         printk("gss_kerberos_mech: unsupported algorithm %d\n", alg);
                                                   >> 100                         goto out_err_free_key;
                                                   >> 101         }
                                                   >> 102         *res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
248         if (IS_ERR(*res)) {                       103         if (IS_ERR(*res)) {
249                 printk(KERN_WARNING "gss_kerbe !! 104                 printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name);
250                         "crypto algorithm %s\n << 
251                 *res = NULL;                      105                 *res = NULL;
252                 goto out_err_free_key;            106                 goto out_err_free_key;
253         }                                         107         }
254         if (crypto_blkcipher_setkey(*res, key.    108         if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
255                 printk(KERN_WARNING "gss_kerbe !! 109                 printk("gss_kerberos_mech: error setting key for crypto algorithm %s\n", alg_name);
256                         "crypto algorithm %s\n << 
257                 goto out_err_free_tfm;            110                 goto out_err_free_tfm;
258         }                                         111         }
259                                                   112 
260         kfree(key.data);                          113         kfree(key.data);
261         return p;                                 114         return p;
262                                                   115 
263 out_err_free_tfm:                                 116 out_err_free_tfm:
264         crypto_free_blkcipher(*res);              117         crypto_free_blkcipher(*res);
265 out_err_free_key:                                 118 out_err_free_key:
266         kfree(key.data);                          119         kfree(key.data);
267         p = ERR_PTR(-EINVAL);                     120         p = ERR_PTR(-EINVAL);
268 out_err:                                          121 out_err:
269         return p;                                 122         return p;
270 }                                                 123 }
271                                                   124 
272 static int                                        125 static int
273 gss_import_v1_context(const void *p, const voi !! 126 gss_import_sec_context_kerberos(const void *p,
                                                   >> 127                                 size_t len,
                                                   >> 128                                 struct gss_ctx *ctx_id)
274 {                                                 129 {
                                                   >> 130         const void *end = (const void *)((const char *)p + len);
                                                   >> 131         struct  krb5_ctx *ctx;
275         int tmp;                                  132         int tmp;
276                                                   133 
277         p = simple_get_bytes(p, end, &ctx->ini !! 134         if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) {
278         if (IS_ERR(p))                         !! 135                 p = ERR_PTR(-ENOMEM);
279                 goto out_err;                  << 
280                                                << 
281         /* Old format supports only DES!  Any  << 
282         ctx->enctype = ENCTYPE_DES_CBC_RAW;    << 
283                                                << 
284         ctx->gk5e = get_gss_krb5_enctype(ctx-> << 
285         if (ctx->gk5e == NULL)                 << 
286                 goto out_err;                     136                 goto out_err;
                                                   >> 137         }
287                                                   138 
                                                   >> 139         p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
                                                   >> 140         if (IS_ERR(p))
                                                   >> 141                 goto out_err_free_ctx;
288         /* The downcall format was designed be    142         /* The downcall format was designed before we completely understood
289          * the uses of the context fields; so     143          * the uses of the context fields; so it includes some stuff we
290          * just give some minimal sanity-check    144          * just give some minimal sanity-checking, and some we ignore
291          * completely (like the next twenty by    145          * completely (like the next twenty bytes): */
292         if (unlikely(p + 20 > end || p + 20 <     146         if (unlikely(p + 20 > end || p + 20 < p))
293                 goto out_err;                  !! 147                 goto out_err_free_ctx;
294         p += 20;                                  148         p += 20;
295         p = simple_get_bytes(p, end, &tmp, siz    149         p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
296         if (IS_ERR(p))                            150         if (IS_ERR(p))
297                 goto out_err;                  !! 151                 goto out_err_free_ctx;
298         if (tmp != SGN_ALG_DES_MAC_MD5) {         152         if (tmp != SGN_ALG_DES_MAC_MD5) {
299                 p = ERR_PTR(-ENOSYS);             153                 p = ERR_PTR(-ENOSYS);
300                 goto out_err;                  !! 154                 goto out_err_free_ctx;
301         }                                         155         }
302         p = simple_get_bytes(p, end, &tmp, siz    156         p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
303         if (IS_ERR(p))                            157         if (IS_ERR(p))
304                 goto out_err;                  !! 158                 goto out_err_free_ctx;
305         if (tmp != SEAL_ALG_DES) {                159         if (tmp != SEAL_ALG_DES) {
306                 p = ERR_PTR(-ENOSYS);             160                 p = ERR_PTR(-ENOSYS);
307                 goto out_err;                  !! 161                 goto out_err_free_ctx;
308         }                                         162         }
309         p = simple_get_bytes(p, end, &ctx->end    163         p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
310         if (IS_ERR(p))                            164         if (IS_ERR(p))
311                 goto out_err;                  !! 165                 goto out_err_free_ctx;
312         p = simple_get_bytes(p, end, &ctx->seq    166         p = simple_get_bytes(p, end, &ctx->seq_send, sizeof(ctx->seq_send));
313         if (IS_ERR(p))                            167         if (IS_ERR(p))
314                 goto out_err;                  !! 168                 goto out_err_free_ctx;
315         p = simple_get_netobj(p, end, &ctx->me    169         p = simple_get_netobj(p, end, &ctx->mech_used);
316         if (IS_ERR(p))                            170         if (IS_ERR(p))
317                 goto out_err;                  !! 171                 goto out_err_free_ctx;
318         p = get_key(p, end, ctx, &ctx->enc);   !! 172         p = get_key(p, end, &ctx->enc);
319         if (IS_ERR(p))                            173         if (IS_ERR(p))
320                 goto out_err_free_mech;           174                 goto out_err_free_mech;
321         p = get_key(p, end, ctx, &ctx->seq);   !! 175         p = get_key(p, end, &ctx->seq);
322         if (IS_ERR(p))                            176         if (IS_ERR(p))
323                 goto out_err_free_key1;           177                 goto out_err_free_key1;
324         if (p != end) {                           178         if (p != end) {
325                 p = ERR_PTR(-EFAULT);             179                 p = ERR_PTR(-EFAULT);
326                 goto out_err_free_key2;           180                 goto out_err_free_key2;
327         }                                         181         }
328                                                   182 
                                                   >> 183         ctx_id->internal_ctx_id = ctx;
                                                   >> 184 
                                                   >> 185         dprintk("RPC:       Successfully imported new context.\n");
329         return 0;                                 186         return 0;
330                                                   187 
331 out_err_free_key2:                                188 out_err_free_key2:
332         crypto_free_blkcipher(ctx->seq);          189         crypto_free_blkcipher(ctx->seq);
333 out_err_free_key1:                                190 out_err_free_key1:
334         crypto_free_blkcipher(ctx->enc);          191         crypto_free_blkcipher(ctx->enc);
335 out_err_free_mech:                                192 out_err_free_mech:
336         kfree(ctx->mech_used.data);               193         kfree(ctx->mech_used.data);
                                                   >> 194 out_err_free_ctx:
                                                   >> 195         kfree(ctx);
337 out_err:                                          196 out_err:
338         return PTR_ERR(p);                        197         return PTR_ERR(p);
339 }                                                 198 }
340                                                   199 
341 struct crypto_blkcipher *                      << 
342 context_v2_alloc_cipher(struct krb5_ctx *ctx,  << 
343 {                                              << 
344         struct crypto_blkcipher *cp;           << 
345                                                << 
346         cp = crypto_alloc_blkcipher(cname, 0,  << 
347         if (IS_ERR(cp)) {                      << 
348                 dprintk("gss_kerberos_mech: un << 
349                         "crypto algorithm %s\n << 
350                 return NULL;                   << 
351         }                                      << 
352         if (crypto_blkcipher_setkey(cp, key, c << 
353                 dprintk("gss_kerberos_mech: er << 
354                         "crypto algorithm %s\n << 
355                 crypto_free_blkcipher(cp);     << 
356                 return NULL;                   << 
357         }                                      << 
358         return cp;                             << 
359 }                                              << 
360                                                << 
361 static inline void                             << 
362 set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 us << 
363 {                                              << 
364         cdata[0] = (usage>>24)&0xff;           << 
365         cdata[1] = (usage>>16)&0xff;           << 
366         cdata[2] = (usage>>8)&0xff;            << 
367         cdata[3] = usage&0xff;                 << 
368         cdata[4] = seed;                       << 
369 }                                              << 
370                                                << 
371 static int                                     << 
372 context_derive_keys_des3(struct krb5_ctx *ctx, << 
373 {                                              << 
374         struct xdr_netobj c, keyin, keyout;    << 
375         u8 cdata[GSS_KRB5_K5CLENGTH];          << 
376         u32 err;                               << 
377                                                << 
378         c.len = GSS_KRB5_K5CLENGTH;            << 
379         c.data = cdata;                        << 
380                                                << 
381         keyin.data = ctx->Ksess;               << 
382         keyin.len = ctx->gk5e->keylength;      << 
383         keyout.len = ctx->gk5e->keylength;     << 
384                                                << 
385         /* seq uses the raw key */             << 
386         ctx->seq = context_v2_alloc_cipher(ctx << 
387                                            ctx << 
388         if (ctx->seq == NULL)                  << 
389                 goto out_err;                  << 
390                                                << 
391         ctx->enc = context_v2_alloc_cipher(ctx << 
392                                            ctx << 
393         if (ctx->enc == NULL)                  << 
394                 goto out_free_seq;             << 
395                                                << 
396         /* derive cksum */                     << 
397         set_cdata(cdata, KG_USAGE_SIGN, KEY_US << 
398         keyout.data = ctx->cksum;              << 
399         err = krb5_derive_key(ctx->gk5e, &keyi << 
400         if (err) {                             << 
401                 dprintk("%s: Error %d deriving << 
402                         __func__, err);        << 
403                 goto out_free_enc;             << 
404         }                                      << 
405                                                << 
406         return 0;                              << 
407                                                << 
408 out_free_enc:                                  << 
409         crypto_free_blkcipher(ctx->enc);       << 
410 out_free_seq:                                  << 
411         crypto_free_blkcipher(ctx->seq);       << 
412 out_err:                                       << 
413         return -EINVAL;                        << 
414 }                                              << 
415                                                << 
416 /*                                             << 
417  * Note that RC4 depends on deriving keys usin << 
418  * number or the checksum of a token.  Therefo << 
419  * cannot be calculated until the token is bei << 
420  */                                            << 
421 static int                                     << 
422 context_derive_keys_rc4(struct krb5_ctx *ctx)  << 
423 {                                              << 
424         struct crypto_hash *hmac;              << 
425         char sigkeyconstant[] = "signaturekey" << 
426         int slen = strlen(sigkeyconstant) + 1; << 
427         struct hash_desc desc;                 << 
428         struct scatterlist sg[1];              << 
429         int err;                               << 
430                                                << 
431         dprintk("RPC:       %s: entered\n", __ << 
432         /*                                     << 
433          * derive cksum (aka Ksign) key        << 
434          */                                    << 
435         hmac = crypto_alloc_hash(ctx->gk5e->ck << 
436         if (IS_ERR(hmac)) {                    << 
437                 dprintk("%s: error %ld allocat << 
438                         __func__, PTR_ERR(hmac << 
439                 err = PTR_ERR(hmac);           << 
440                 goto out_err;                  << 
441         }                                      << 
442                                                << 
443         err = crypto_hash_setkey(hmac, ctx->Ks << 
444         if (err)                               << 
445                 goto out_err_free_hmac;        << 
446                                                << 
447         sg_init_table(sg, 1);                  << 
448         sg_set_buf(sg, sigkeyconstant, slen);  << 
449                                                << 
450         desc.tfm = hmac;                       << 
451         desc.flags = 0;                        << 
452                                                << 
453         err = crypto_hash_init(&desc);         << 
454         if (err)                               << 
455                 goto out_err_free_hmac;        << 
456                                                << 
457         err = crypto_hash_digest(&desc, sg, sl << 
458         if (err)                               << 
459                 goto out_err_free_hmac;        << 
460         /*                                     << 
461          * allocate hash, and blkciphers for d << 
462          */                                    << 
463         ctx->enc = crypto_alloc_blkcipher(ctx- << 
464                                           CRYP << 
465         if (IS_ERR(ctx->enc)) {                << 
466                 err = PTR_ERR(ctx->enc);       << 
467                 goto out_err_free_hmac;        << 
468         }                                      << 
469                                                << 
470         ctx->seq = crypto_alloc_blkcipher(ctx- << 
471                                           CRYP << 
472         if (IS_ERR(ctx->seq)) {                << 
473                 crypto_free_blkcipher(ctx->enc << 
474                 err = PTR_ERR(ctx->seq);       << 
475                 goto out_err_free_hmac;        << 
476         }                                      << 
477                                                << 
478         dprintk("RPC:       %s: returning succ << 
479                                                << 
480         err = 0;                               << 
481                                                << 
482 out_err_free_hmac:                             << 
483         crypto_free_hash(hmac);                << 
484 out_err:                                       << 
485         dprintk("RPC:       %s: returning %d\n << 
486         return err;                            << 
487 }                                              << 
488                                                << 
489 static int                                     << 
490 context_derive_keys_new(struct krb5_ctx *ctx,  << 
491 {                                              << 
492         struct xdr_netobj c, keyin, keyout;    << 
493         u8 cdata[GSS_KRB5_K5CLENGTH];          << 
494         u32 err;                               << 
495                                                << 
496         c.len = GSS_KRB5_K5CLENGTH;            << 
497         c.data = cdata;                        << 
498                                                << 
499         keyin.data = ctx->Ksess;               << 
500         keyin.len = ctx->gk5e->keylength;      << 
501         keyout.len = ctx->gk5e->keylength;     << 
502                                                << 
503         /* initiator seal encryption */        << 
504         set_cdata(cdata, KG_USAGE_INITIATOR_SE << 
505         keyout.data = ctx->initiator_seal;     << 
506         err = krb5_derive_key(ctx->gk5e, &keyi << 
507         if (err) {                             << 
508                 dprintk("%s: Error %d deriving << 
509                         __func__, err);        << 
510                 goto out_err;                  << 
511         }                                      << 
512         ctx->initiator_enc = context_v2_alloc_ << 
513                                                << 
514                                                << 
515         if (ctx->initiator_enc == NULL)        << 
516                 goto out_err;                  << 
517                                                << 
518         /* acceptor seal encryption */         << 
519         set_cdata(cdata, KG_USAGE_ACCEPTOR_SEA << 
520         keyout.data = ctx->acceptor_seal;      << 
521         err = krb5_derive_key(ctx->gk5e, &keyi << 
522         if (err) {                             << 
523                 dprintk("%s: Error %d deriving << 
524                         __func__, err);        << 
525                 goto out_free_initiator_enc;   << 
526         }                                      << 
527         ctx->acceptor_enc = context_v2_alloc_c << 
528                                                << 
529                                                << 
530         if (ctx->acceptor_enc == NULL)         << 
531                 goto out_free_initiator_enc;   << 
532                                                << 
533         /* initiator sign checksum */          << 
534         set_cdata(cdata, KG_USAGE_INITIATOR_SI << 
535         keyout.data = ctx->initiator_sign;     << 
536         err = krb5_derive_key(ctx->gk5e, &keyi << 
537         if (err) {                             << 
538                 dprintk("%s: Error %d deriving << 
539                         __func__, err);        << 
540                 goto out_free_acceptor_enc;    << 
541         }                                      << 
542                                                << 
543         /* acceptor sign checksum */           << 
544         set_cdata(cdata, KG_USAGE_ACCEPTOR_SIG << 
545         keyout.data = ctx->acceptor_sign;      << 
546         err = krb5_derive_key(ctx->gk5e, &keyi << 
547         if (err) {                             << 
548                 dprintk("%s: Error %d deriving << 
549                         __func__, err);        << 
550                 goto out_free_acceptor_enc;    << 
551         }                                      << 
552                                                << 
553         /* initiator seal integrity */         << 
554         set_cdata(cdata, KG_USAGE_INITIATOR_SE << 
555         keyout.data = ctx->initiator_integ;    << 
556         err = krb5_derive_key(ctx->gk5e, &keyi << 
557         if (err) {                             << 
558                 dprintk("%s: Error %d deriving << 
559                         __func__, err);        << 
560                 goto out_free_acceptor_enc;    << 
561         }                                      << 
562                                                << 
563         /* acceptor seal integrity */          << 
564         set_cdata(cdata, KG_USAGE_ACCEPTOR_SEA << 
565         keyout.data = ctx->acceptor_integ;     << 
566         err = krb5_derive_key(ctx->gk5e, &keyi << 
567         if (err) {                             << 
568                 dprintk("%s: Error %d deriving << 
569                         __func__, err);        << 
570                 goto out_free_acceptor_enc;    << 
571         }                                      << 
572                                                << 
573         switch (ctx->enctype) {                << 
574         case ENCTYPE_AES128_CTS_HMAC_SHA1_96:  << 
575         case ENCTYPE_AES256_CTS_HMAC_SHA1_96:  << 
576                 ctx->initiator_enc_aux =       << 
577                         context_v2_alloc_ciphe << 
578                                                << 
579                 if (ctx->initiator_enc_aux ==  << 
580                         goto out_free_acceptor << 
581                 ctx->acceptor_enc_aux =        << 
582                         context_v2_alloc_ciphe << 
583                                                << 
584                 if (ctx->acceptor_enc_aux == N << 
585                         crypto_free_blkcipher( << 
586                         goto out_free_acceptor << 
587                 }                              << 
588         }                                      << 
589                                                << 
590         return 0;                              << 
591                                                << 
592 out_free_acceptor_enc:                         << 
593         crypto_free_blkcipher(ctx->acceptor_en << 
594 out_free_initiator_enc:                        << 
595         crypto_free_blkcipher(ctx->initiator_e << 
596 out_err:                                       << 
597         return -EINVAL;                        << 
598 }                                              << 
599                                                << 
600 static int                                     << 
601 gss_import_v2_context(const void *p, const voi << 
602                 gfp_t gfp_mask)                << 
603 {                                              << 
604         int keylen;                            << 
605                                                << 
606         p = simple_get_bytes(p, end, &ctx->fla << 
607         if (IS_ERR(p))                         << 
608                 goto out_err;                  << 
609         ctx->initiate = ctx->flags & KRB5_CTX_ << 
610                                                << 
611         p = simple_get_bytes(p, end, &ctx->end << 
612         if (IS_ERR(p))                         << 
613                 goto out_err;                  << 
614         p = simple_get_bytes(p, end, &ctx->seq << 
615         if (IS_ERR(p))                         << 
616                 goto out_err;                  << 
617         /* set seq_send for use by "older" enc << 
618         ctx->seq_send = ctx->seq_send64;       << 
619         if (ctx->seq_send64 != ctx->seq_send)  << 
620                 dprintk("%s: seq_send64 %lx, s << 
621                         (long unsigned)ctx->se << 
622                 goto out_err;                  << 
623         }                                      << 
624         p = simple_get_bytes(p, end, &ctx->enc << 
625         if (IS_ERR(p))                         << 
626                 goto out_err;                  << 
627         /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYP << 
628         if (ctx->enctype == ENCTYPE_DES3_CBC_S << 
629                 ctx->enctype = ENCTYPE_DES3_CB << 
630         ctx->gk5e = get_gss_krb5_enctype(ctx-> << 
631         if (ctx->gk5e == NULL) {               << 
632                 dprintk("gss_kerberos_mech: un << 
633                         ctx->enctype);         << 
634                 p = ERR_PTR(-EINVAL);          << 
635                 goto out_err;                  << 
636         }                                      << 
637         keylen = ctx->gk5e->keylength;         << 
638                                                << 
639         p = simple_get_bytes(p, end, ctx->Kses << 
640         if (IS_ERR(p))                         << 
641                 goto out_err;                  << 
642                                                << 
643         if (p != end) {                        << 
644                 p = ERR_PTR(-EINVAL);          << 
645                 goto out_err;                  << 
646         }                                      << 
647                                                << 
648         ctx->mech_used.data = kmemdup(gss_kerb << 
649                                       gss_kerb << 
650         if (unlikely(ctx->mech_used.data == NU << 
651                 p = ERR_PTR(-ENOMEM);          << 
652                 goto out_err;                  << 
653         }                                      << 
654         ctx->mech_used.len = gss_kerberos_mech << 
655                                                << 
656         switch (ctx->enctype) {                << 
657         case ENCTYPE_DES3_CBC_RAW:             << 
658                 return context_derive_keys_des << 
659         case ENCTYPE_ARCFOUR_HMAC:             << 
660                 return context_derive_keys_rc4 << 
661         case ENCTYPE_AES128_CTS_HMAC_SHA1_96:  << 
662         case ENCTYPE_AES256_CTS_HMAC_SHA1_96:  << 
663                 return context_derive_keys_new << 
664         default:                               << 
665                 return -EINVAL;                << 
666         }                                      << 
667                                                << 
668 out_err:                                       << 
669         return PTR_ERR(p);                     << 
670 }                                              << 
671                                                << 
672 static int                                     << 
673 gss_import_sec_context_kerberos(const void *p, << 
674                                 struct gss_ctx << 
675                                 gfp_t gfp_mask << 
676 {                                              << 
677         const void *end = (const void *)((cons << 
678         struct  krb5_ctx *ctx;                 << 
679         int ret;                               << 
680                                                << 
681         ctx = kzalloc(sizeof(*ctx), gfp_mask); << 
682         if (ctx == NULL)                       << 
683                 return -ENOMEM;                << 
684                                                << 
685         if (len == 85)                         << 
686                 ret = gss_import_v1_context(p, << 
687         else                                   << 
688                 ret = gss_import_v2_context(p, << 
689                                                << 
690         if (ret == 0)                          << 
691                 ctx_id->internal_ctx_id = ctx; << 
692         else                                   << 
693                 kfree(ctx);                    << 
694                                                << 
695         dprintk("RPC:       %s: returning %d\n << 
696         return ret;                            << 
697 }                                              << 
698                                                << 
699 static void                                       200 static void
700 gss_delete_sec_context_kerberos(void *internal    201 gss_delete_sec_context_kerberos(void *internal_ctx) {
701         struct krb5_ctx *kctx = internal_ctx;     202         struct krb5_ctx *kctx = internal_ctx;
702                                                   203 
703         crypto_free_blkcipher(kctx->seq);         204         crypto_free_blkcipher(kctx->seq);
704         crypto_free_blkcipher(kctx->enc);         205         crypto_free_blkcipher(kctx->enc);
705         crypto_free_blkcipher(kctx->acceptor_e << 
706         crypto_free_blkcipher(kctx->initiator_ << 
707         crypto_free_blkcipher(kctx->acceptor_e << 
708         crypto_free_blkcipher(kctx->initiator_ << 
709         kfree(kctx->mech_used.data);              206         kfree(kctx->mech_used.data);
710         kfree(kctx);                              207         kfree(kctx);
711 }                                                 208 }
712                                                   209 
713 static const struct gss_api_ops gss_kerberos_o    210 static const struct gss_api_ops gss_kerberos_ops = {
714         .gss_import_sec_context = gss_import_s    211         .gss_import_sec_context = gss_import_sec_context_kerberos,
715         .gss_get_mic            = gss_get_mic_    212         .gss_get_mic            = gss_get_mic_kerberos,
716         .gss_verify_mic         = gss_verify_m    213         .gss_verify_mic         = gss_verify_mic_kerberos,
717         .gss_wrap               = gss_wrap_ker    214         .gss_wrap               = gss_wrap_kerberos,
718         .gss_unwrap             = gss_unwrap_k    215         .gss_unwrap             = gss_unwrap_kerberos,
719         .gss_delete_sec_context = gss_delete_s    216         .gss_delete_sec_context = gss_delete_sec_context_kerberos,
720 };                                                217 };
721                                                   218 
722 static struct pf_desc gss_kerberos_pfs[] = {      219 static struct pf_desc gss_kerberos_pfs[] = {
723         [0] = {                                   220         [0] = {
724                 .pseudoflavor = RPC_AUTH_GSS_K    221                 .pseudoflavor = RPC_AUTH_GSS_KRB5,
725                 .service = RPC_GSS_SVC_NONE,      222                 .service = RPC_GSS_SVC_NONE,
726                 .name = "krb5",                   223                 .name = "krb5",
727         },                                        224         },
728         [1] = {                                   225         [1] = {
729                 .pseudoflavor = RPC_AUTH_GSS_K    226                 .pseudoflavor = RPC_AUTH_GSS_KRB5I,
730                 .service = RPC_GSS_SVC_INTEGRI    227                 .service = RPC_GSS_SVC_INTEGRITY,
731                 .name = "krb5i",                  228                 .name = "krb5i",
732         },                                        229         },
733         [2] = {                                   230         [2] = {
734                 .pseudoflavor = RPC_AUTH_GSS_K    231                 .pseudoflavor = RPC_AUTH_GSS_KRB5P,
735                 .service = RPC_GSS_SVC_PRIVACY    232                 .service = RPC_GSS_SVC_PRIVACY,
736                 .name = "krb5p",                  233                 .name = "krb5p",
737         },                                        234         },
738 };                                                235 };
739                                                   236 
740 static struct gss_api_mech gss_kerberos_mech =    237 static struct gss_api_mech gss_kerberos_mech = {
741         .gm_name        = "krb5",                 238         .gm_name        = "krb5",
742         .gm_owner       = THIS_MODULE,            239         .gm_owner       = THIS_MODULE,
743         .gm_oid         = {9, (void *)"\x2a\x8    240         .gm_oid         = {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"},
744         .gm_ops         = &gss_kerberos_ops,      241         .gm_ops         = &gss_kerberos_ops,
745         .gm_pf_num      = ARRAY_SIZE(gss_kerbe    242         .gm_pf_num      = ARRAY_SIZE(gss_kerberos_pfs),
746         .gm_pfs         = gss_kerberos_pfs,       243         .gm_pfs         = gss_kerberos_pfs,
747         .gm_upcall_enctypes = "enctypes=18,17, << 
748 };                                                244 };
749                                                   245 
750 static int __init init_kerberos_module(void)      246 static int __init init_kerberos_module(void)
751 {                                                 247 {
752         int status;                               248         int status;
753                                                   249 
754         status = gss_mech_register(&gss_kerber    250         status = gss_mech_register(&gss_kerberos_mech);
755         if (status)                               251         if (status)
756                 printk("Failed to register ker    252                 printk("Failed to register kerberos gss mechanism!\n");
757         return status;                            253         return status;
758 }                                                 254 }
759                                                   255 
760 static void __exit cleanup_kerberos_module(voi    256 static void __exit cleanup_kerberos_module(void)
761 {                                                 257 {
762         gss_mech_unregister(&gss_kerberos_mech    258         gss_mech_unregister(&gss_kerberos_mech);
763 }                                                 259 }
764                                                   260 
765 MODULE_LICENSE("GPL");                            261 MODULE_LICENSE("GPL");
766 module_init(init_kerberos_module);                262 module_init(init_kerberos_module);
767 module_exit(cleanup_kerberos_module);             263 module_exit(cleanup_kerberos_module);
768                                                   264 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us