SUNRPC: Remove CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM
[sfrench/cifs-2.6.git] / net / sunrpc / auth_gss / gss_krb5_mech.c
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  *  linux/net/sunrpc/gss_krb5_mech.c
4  *
5  *  Copyright (c) 2001-2008 The Regents of the University of Michigan.
6  *  All rights reserved.
7  *
8  *  Andy Adamson <andros@umich.edu>
9  *  J. Bruce Fields <bfields@umich.edu>
10  */
11
12 #include <crypto/hash.h>
13 #include <crypto/skcipher.h>
14 #include <linux/err.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/types.h>
18 #include <linux/slab.h>
19 #include <linux/sunrpc/auth.h>
20 #include <linux/sunrpc/gss_krb5.h>
21 #include <linux/sunrpc/xdr.h>
22 #include <kunit/visibility.h>
23
24 #include "auth_gss_internal.h"
25 #include "gss_krb5_internal.h"
26
27 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
28 # define RPCDBG_FACILITY        RPCDBG_AUTH
29 #endif
30
31 static struct gss_api_mech gss_kerberos_mech;
32 static int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask);
33
34 static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = {
35 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1)
36         /*
37          * AES-128 with SHA-1 (RFC 3962)
38          */
39         {
40           .etype = ENCTYPE_AES128_CTS_HMAC_SHA1_96,
41           .ctype = CKSUMTYPE_HMAC_SHA1_96_AES128,
42           .name = "aes128-cts",
43           .encrypt_name = "cts(cbc(aes))",
44           .aux_cipher = "cbc(aes)",
45           .cksum_name = "hmac(sha1)",
46           .import_ctx = gss_krb5_import_ctx_v2,
47           .derive_key = krb5_derive_key_v2,
48           .encrypt = gss_krb5_aes_encrypt,
49           .decrypt = gss_krb5_aes_decrypt,
50
51           .get_mic = gss_krb5_get_mic_v2,
52           .verify_mic = gss_krb5_verify_mic_v2,
53           .wrap = gss_krb5_wrap_v2,
54           .unwrap = gss_krb5_unwrap_v2,
55
56           .signalg = -1,
57           .sealalg = -1,
58           .keybytes = 16,
59           .keylength = BITS2OCTETS(128),
60           .Kc_length = BITS2OCTETS(128),
61           .Ke_length = BITS2OCTETS(128),
62           .Ki_length = BITS2OCTETS(128),
63           .cksumlength = BITS2OCTETS(96),
64           .keyed_cksum = 1,
65         },
66         /*
67          * AES-256 with SHA-1 (RFC 3962)
68          */
69         {
70           .etype = ENCTYPE_AES256_CTS_HMAC_SHA1_96,
71           .ctype = CKSUMTYPE_HMAC_SHA1_96_AES256,
72           .name = "aes256-cts",
73           .encrypt_name = "cts(cbc(aes))",
74           .aux_cipher = "cbc(aes)",
75           .cksum_name = "hmac(sha1)",
76           .import_ctx = gss_krb5_import_ctx_v2,
77           .derive_key = krb5_derive_key_v2,
78           .encrypt = gss_krb5_aes_encrypt,
79           .decrypt = gss_krb5_aes_decrypt,
80
81           .get_mic = gss_krb5_get_mic_v2,
82           .verify_mic = gss_krb5_verify_mic_v2,
83           .wrap = gss_krb5_wrap_v2,
84           .unwrap = gss_krb5_unwrap_v2,
85
86           .signalg = -1,
87           .sealalg = -1,
88           .keybytes = 32,
89           .keylength = BITS2OCTETS(256),
90           .Kc_length = BITS2OCTETS(256),
91           .Ke_length = BITS2OCTETS(256),
92           .Ki_length = BITS2OCTETS(256),
93           .cksumlength = BITS2OCTETS(96),
94           .keyed_cksum = 1,
95         },
96 #endif
97
98 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA)
99         /*
100          * Camellia-128 with CMAC (RFC 6803)
101          */
102         {
103                 .etype          = ENCTYPE_CAMELLIA128_CTS_CMAC,
104                 .ctype          = CKSUMTYPE_CMAC_CAMELLIA128,
105                 .name           = "camellia128-cts-cmac",
106                 .encrypt_name   = "cts(cbc(camellia))",
107                 .aux_cipher     = "cbc(camellia)",
108                 .cksum_name     = "cmac(camellia)",
109                 .cksumlength    = BITS2OCTETS(128),
110                 .keyed_cksum    = 1,
111                 .keylength      = BITS2OCTETS(128),
112                 .Kc_length      = BITS2OCTETS(128),
113                 .Ke_length      = BITS2OCTETS(128),
114                 .Ki_length      = BITS2OCTETS(128),
115
116                 .import_ctx     = gss_krb5_import_ctx_v2,
117                 .derive_key     = krb5_kdf_feedback_cmac,
118                 .encrypt        = gss_krb5_aes_encrypt,
119                 .decrypt        = gss_krb5_aes_decrypt,
120
121                 .get_mic        = gss_krb5_get_mic_v2,
122                 .verify_mic     = gss_krb5_verify_mic_v2,
123                 .wrap           = gss_krb5_wrap_v2,
124                 .unwrap         = gss_krb5_unwrap_v2,
125         },
126         /*
127          * Camellia-256 with CMAC (RFC 6803)
128          */
129         {
130                 .etype          = ENCTYPE_CAMELLIA256_CTS_CMAC,
131                 .ctype          = CKSUMTYPE_CMAC_CAMELLIA256,
132                 .name           = "camellia256-cts-cmac",
133                 .encrypt_name   = "cts(cbc(camellia))",
134                 .aux_cipher     = "cbc(camellia)",
135                 .cksum_name     = "cmac(camellia)",
136                 .cksumlength    = BITS2OCTETS(128),
137                 .keyed_cksum    = 1,
138                 .keylength      = BITS2OCTETS(256),
139                 .Kc_length      = BITS2OCTETS(256),
140                 .Ke_length      = BITS2OCTETS(256),
141                 .Ki_length      = BITS2OCTETS(256),
142
143                 .import_ctx     = gss_krb5_import_ctx_v2,
144                 .derive_key     = krb5_kdf_feedback_cmac,
145                 .encrypt        = gss_krb5_aes_encrypt,
146                 .decrypt        = gss_krb5_aes_decrypt,
147
148                 .get_mic        = gss_krb5_get_mic_v2,
149                 .verify_mic     = gss_krb5_verify_mic_v2,
150                 .wrap           = gss_krb5_wrap_v2,
151                 .unwrap         = gss_krb5_unwrap_v2,
152         },
153 #endif
154
155 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2)
156         /*
157          * AES-128 with SHA-256 (RFC 8009)
158          */
159         {
160                 .etype          = ENCTYPE_AES128_CTS_HMAC_SHA256_128,
161                 .ctype          = CKSUMTYPE_HMAC_SHA256_128_AES128,
162                 .name           = "aes128-cts-hmac-sha256-128",
163                 .encrypt_name   = "cts(cbc(aes))",
164                 .aux_cipher     = "cbc(aes)",
165                 .cksum_name     = "hmac(sha256)",
166                 .cksumlength    = BITS2OCTETS(128),
167                 .keyed_cksum    = 1,
168                 .keylength      = BITS2OCTETS(128),
169                 .Kc_length      = BITS2OCTETS(128),
170                 .Ke_length      = BITS2OCTETS(128),
171                 .Ki_length      = BITS2OCTETS(128),
172
173                 .import_ctx     = gss_krb5_import_ctx_v2,
174                 .derive_key     = krb5_kdf_hmac_sha2,
175                 .encrypt        = krb5_etm_encrypt,
176                 .decrypt        = krb5_etm_decrypt,
177
178                 .get_mic        = gss_krb5_get_mic_v2,
179                 .verify_mic     = gss_krb5_verify_mic_v2,
180                 .wrap           = gss_krb5_wrap_v2,
181                 .unwrap         = gss_krb5_unwrap_v2,
182         },
183         /*
184          * AES-256 with SHA-384 (RFC 8009)
185          */
186         {
187                 .etype          = ENCTYPE_AES256_CTS_HMAC_SHA384_192,
188                 .ctype          = CKSUMTYPE_HMAC_SHA384_192_AES256,
189                 .name           = "aes256-cts-hmac-sha384-192",
190                 .encrypt_name   = "cts(cbc(aes))",
191                 .aux_cipher     = "cbc(aes)",
192                 .cksum_name     = "hmac(sha384)",
193                 .cksumlength    = BITS2OCTETS(192),
194                 .keyed_cksum    = 1,
195                 .keylength      = BITS2OCTETS(256),
196                 .Kc_length      = BITS2OCTETS(192),
197                 .Ke_length      = BITS2OCTETS(256),
198                 .Ki_length      = BITS2OCTETS(192),
199
200                 .import_ctx     = gss_krb5_import_ctx_v2,
201                 .derive_key     = krb5_kdf_hmac_sha2,
202                 .encrypt        = krb5_etm_encrypt,
203                 .decrypt        = krb5_etm_decrypt,
204
205                 .get_mic        = gss_krb5_get_mic_v2,
206                 .verify_mic     = gss_krb5_verify_mic_v2,
207                 .wrap           = gss_krb5_wrap_v2,
208                 .unwrap         = gss_krb5_unwrap_v2,
209         },
210 #endif
211 };
212
213 /*
214  * The list of advertised enctypes is specified in order of most
215  * preferred to least.
216  */
217 static char gss_krb5_enctype_priority_list[64];
218
219 static void gss_krb5_prepare_enctype_priority_list(void)
220 {
221         static const u32 gss_krb5_enctypes[] = {
222 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2)
223                 ENCTYPE_AES256_CTS_HMAC_SHA384_192,
224                 ENCTYPE_AES128_CTS_HMAC_SHA256_128,
225 #endif
226 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA)
227                 ENCTYPE_CAMELLIA256_CTS_CMAC,
228                 ENCTYPE_CAMELLIA128_CTS_CMAC,
229 #endif
230 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1)
231                 ENCTYPE_AES256_CTS_HMAC_SHA1_96,
232                 ENCTYPE_AES128_CTS_HMAC_SHA1_96,
233 #endif
234         };
235         size_t total, i;
236         char buf[16];
237         char *sep;
238         int n;
239
240         sep = "";
241         gss_krb5_enctype_priority_list[0] = '\0';
242         for (total = 0, i = 0; i < ARRAY_SIZE(gss_krb5_enctypes); i++) {
243                 n = sprintf(buf, "%s%u", sep, gss_krb5_enctypes[i]);
244                 if (n < 0)
245                         break;
246                 if (total + n >= sizeof(gss_krb5_enctype_priority_list))
247                         break;
248                 strcat(gss_krb5_enctype_priority_list, buf);
249                 sep = ",";
250                 total += n;
251         }
252 }
253
254 /**
255  * gss_krb5_lookup_enctype - Retrieve profile information for a given enctype
256  * @etype: ENCTYPE value
257  *
258  * Returns a pointer to a gss_krb5_enctype structure, or NULL if no
259  * matching etype is found.
260  */
261 VISIBLE_IF_KUNIT
262 const struct gss_krb5_enctype *gss_krb5_lookup_enctype(u32 etype)
263 {
264         size_t i;
265
266         for (i = 0; i < ARRAY_SIZE(supported_gss_krb5_enctypes); i++)
267                 if (supported_gss_krb5_enctypes[i].etype == etype)
268                         return &supported_gss_krb5_enctypes[i];
269         return NULL;
270 }
271 EXPORT_SYMBOL_IF_KUNIT(gss_krb5_lookup_enctype);
272
273 static struct crypto_sync_skcipher *
274 gss_krb5_alloc_cipher_v2(const char *cname, const struct xdr_netobj *key)
275 {
276         struct crypto_sync_skcipher *tfm;
277
278         tfm = crypto_alloc_sync_skcipher(cname, 0, 0);
279         if (IS_ERR(tfm))
280                 return NULL;
281         if (crypto_sync_skcipher_setkey(tfm, key->data, key->len)) {
282                 crypto_free_sync_skcipher(tfm);
283                 return NULL;
284         }
285         return tfm;
286 }
287
288 static struct crypto_ahash *
289 gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key)
290 {
291         struct crypto_ahash *tfm;
292
293         tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
294         if (IS_ERR(tfm))
295                 return NULL;
296         if (crypto_ahash_setkey(tfm, key->data, key->len)) {
297                 crypto_free_ahash(tfm);
298                 return NULL;
299         }
300         return tfm;
301 }
302
303 static int
304 gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
305 {
306         struct xdr_netobj keyin = {
307                 .len    = ctx->gk5e->keylength,
308                 .data   = ctx->Ksess,
309         };
310         struct xdr_netobj keyout;
311         int ret = -EINVAL;
312
313         keyout.data = kmalloc(GSS_KRB5_MAX_KEYLEN, gfp_mask);
314         if (!keyout.data)
315                 return -ENOMEM;
316
317         /* initiator seal encryption */
318         keyout.len = ctx->gk5e->Ke_length;
319         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL,
320                             KEY_USAGE_SEED_ENCRYPTION, gfp_mask))
321                 goto out;
322         ctx->initiator_enc = gss_krb5_alloc_cipher_v2(ctx->gk5e->encrypt_name,
323                                                       &keyout);
324         if (ctx->initiator_enc == NULL)
325                 goto out;
326         if (ctx->gk5e->aux_cipher) {
327                 ctx->initiator_enc_aux =
328                         gss_krb5_alloc_cipher_v2(ctx->gk5e->aux_cipher,
329                                                  &keyout);
330                 if (ctx->initiator_enc_aux == NULL)
331                         goto out_free;
332         }
333
334         /* acceptor seal encryption */
335         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL,
336                             KEY_USAGE_SEED_ENCRYPTION, gfp_mask))
337                 goto out_free;
338         ctx->acceptor_enc = gss_krb5_alloc_cipher_v2(ctx->gk5e->encrypt_name,
339                                                      &keyout);
340         if (ctx->acceptor_enc == NULL)
341                 goto out_free;
342         if (ctx->gk5e->aux_cipher) {
343                 ctx->acceptor_enc_aux =
344                         gss_krb5_alloc_cipher_v2(ctx->gk5e->aux_cipher,
345                                                  &keyout);
346                 if (ctx->acceptor_enc_aux == NULL)
347                         goto out_free;
348         }
349
350         /* initiator sign checksum */
351         keyout.len = ctx->gk5e->Kc_length;
352         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SIGN,
353                             KEY_USAGE_SEED_CHECKSUM, gfp_mask))
354                 goto out_free;
355         ctx->initiator_sign = gss_krb5_alloc_hash_v2(ctx, &keyout);
356         if (ctx->initiator_sign == NULL)
357                 goto out_free;
358
359         /* acceptor sign checksum */
360         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SIGN,
361                             KEY_USAGE_SEED_CHECKSUM, gfp_mask))
362                 goto out_free;
363         ctx->acceptor_sign = gss_krb5_alloc_hash_v2(ctx, &keyout);
364         if (ctx->acceptor_sign == NULL)
365                 goto out_free;
366
367         /* initiator seal integrity */
368         keyout.len = ctx->gk5e->Ki_length;
369         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL,
370                             KEY_USAGE_SEED_INTEGRITY, gfp_mask))
371                 goto out_free;
372         ctx->initiator_integ = gss_krb5_alloc_hash_v2(ctx, &keyout);
373         if (ctx->initiator_integ == NULL)
374                 goto out_free;
375
376         /* acceptor seal integrity */
377         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL,
378                             KEY_USAGE_SEED_INTEGRITY, gfp_mask))
379                 goto out_free;
380         ctx->acceptor_integ = gss_krb5_alloc_hash_v2(ctx, &keyout);
381         if (ctx->acceptor_integ == NULL)
382                 goto out_free;
383
384         ret = 0;
385 out:
386         kfree_sensitive(keyout.data);
387         return ret;
388
389 out_free:
390         crypto_free_ahash(ctx->acceptor_integ);
391         crypto_free_ahash(ctx->initiator_integ);
392         crypto_free_ahash(ctx->acceptor_sign);
393         crypto_free_ahash(ctx->initiator_sign);
394         crypto_free_sync_skcipher(ctx->acceptor_enc_aux);
395         crypto_free_sync_skcipher(ctx->acceptor_enc);
396         crypto_free_sync_skcipher(ctx->initiator_enc_aux);
397         crypto_free_sync_skcipher(ctx->initiator_enc);
398         goto out;
399 }
400
401 static int
402 gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
403                 gfp_t gfp_mask)
404 {
405         u64 seq_send64;
406         int keylen;
407         u32 time32;
408
409         p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
410         if (IS_ERR(p))
411                 goto out_err;
412         ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR;
413
414         p = simple_get_bytes(p, end, &time32, sizeof(time32));
415         if (IS_ERR(p))
416                 goto out_err;
417         /* unsigned 32-bit time overflows in year 2106 */
418         ctx->endtime = (time64_t)time32;
419         p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64));
420         if (IS_ERR(p))
421                 goto out_err;
422         atomic64_set(&ctx->seq_send64, seq_send64);
423         /* set seq_send for use by "older" enctypes */
424         atomic_set(&ctx->seq_send, seq_send64);
425         if (seq_send64 != atomic_read(&ctx->seq_send)) {
426                 dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__,
427                         seq_send64, atomic_read(&ctx->seq_send));
428                 p = ERR_PTR(-EINVAL);
429                 goto out_err;
430         }
431         p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype));
432         if (IS_ERR(p))
433                 goto out_err;
434         /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */
435         if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1)
436                 ctx->enctype = ENCTYPE_DES3_CBC_RAW;
437         ctx->gk5e = gss_krb5_lookup_enctype(ctx->enctype);
438         if (ctx->gk5e == NULL) {
439                 dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n",
440                         ctx->enctype);
441                 p = ERR_PTR(-EINVAL);
442                 goto out_err;
443         }
444         keylen = ctx->gk5e->keylength;
445
446         p = simple_get_bytes(p, end, ctx->Ksess, keylen);
447         if (IS_ERR(p))
448                 goto out_err;
449
450         if (p != end) {
451                 p = ERR_PTR(-EINVAL);
452                 goto out_err;
453         }
454
455         ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data,
456                                       gss_kerberos_mech.gm_oid.len, gfp_mask);
457         if (unlikely(ctx->mech_used.data == NULL)) {
458                 p = ERR_PTR(-ENOMEM);
459                 goto out_err;
460         }
461         ctx->mech_used.len = gss_kerberos_mech.gm_oid.len;
462
463         return ctx->gk5e->import_ctx(ctx, gfp_mask);
464
465 out_err:
466         return PTR_ERR(p);
467 }
468
469 static int
470 gss_krb5_import_sec_context(const void *p, size_t len, struct gss_ctx *ctx_id,
471                             time64_t *endtime, gfp_t gfp_mask)
472 {
473         const void *end = (const void *)((const char *)p + len);
474         struct  krb5_ctx *ctx;
475         int ret;
476
477         ctx = kzalloc(sizeof(*ctx), gfp_mask);
478         if (ctx == NULL)
479                 return -ENOMEM;
480
481         ret = gss_import_v2_context(p, end, ctx, gfp_mask);
482         memzero_explicit(&ctx->Ksess, sizeof(ctx->Ksess));
483         if (ret) {
484                 kfree(ctx);
485                 return ret;
486         }
487
488         ctx_id->internal_ctx_id = ctx;
489         if (endtime)
490                 *endtime = ctx->endtime;
491         return 0;
492 }
493
494 static void
495 gss_krb5_delete_sec_context(void *internal_ctx)
496 {
497         struct krb5_ctx *kctx = internal_ctx;
498
499         crypto_free_sync_skcipher(kctx->seq);
500         crypto_free_sync_skcipher(kctx->enc);
501         crypto_free_sync_skcipher(kctx->acceptor_enc);
502         crypto_free_sync_skcipher(kctx->initiator_enc);
503         crypto_free_sync_skcipher(kctx->acceptor_enc_aux);
504         crypto_free_sync_skcipher(kctx->initiator_enc_aux);
505         crypto_free_ahash(kctx->acceptor_sign);
506         crypto_free_ahash(kctx->initiator_sign);
507         crypto_free_ahash(kctx->acceptor_integ);
508         crypto_free_ahash(kctx->initiator_integ);
509         kfree(kctx->mech_used.data);
510         kfree(kctx);
511 }
512
513 /**
514  * gss_krb5_get_mic - get_mic for the Kerberos GSS mechanism
515  * @gctx: GSS context
516  * @text: plaintext to checksum
517  * @token: buffer into which to write the computed checksum
518  *
519  * Return values:
520  *    %GSS_S_COMPLETE - success, and @token is filled in
521  *    %GSS_S_FAILURE - checksum could not be generated
522  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
523  */
524 static u32 gss_krb5_get_mic(struct gss_ctx *gctx, struct xdr_buf *text,
525                             struct xdr_netobj *token)
526 {
527         struct krb5_ctx *kctx = gctx->internal_ctx_id;
528
529         return kctx->gk5e->get_mic(kctx, text, token);
530 }
531
532 /**
533  * gss_krb5_verify_mic - verify_mic for the Kerberos GSS mechanism
534  * @gctx: GSS context
535  * @message_buffer: plaintext to check
536  * @read_token: received checksum to check
537  *
538  * Return values:
539  *    %GSS_S_COMPLETE - computed and received checksums match
540  *    %GSS_S_DEFECTIVE_TOKEN - received checksum is not valid
541  *    %GSS_S_BAD_SIG - computed and received checksums do not match
542  *    %GSS_S_FAILURE - received checksum could not be checked
543  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
544  */
545 static u32 gss_krb5_verify_mic(struct gss_ctx *gctx,
546                                struct xdr_buf *message_buffer,
547                                struct xdr_netobj *read_token)
548 {
549         struct krb5_ctx *kctx = gctx->internal_ctx_id;
550
551         return kctx->gk5e->verify_mic(kctx, message_buffer, read_token);
552 }
553
554 /**
555  * gss_krb5_wrap - gss_wrap for the Kerberos GSS mechanism
556  * @gctx: initialized GSS context
557  * @offset: byte offset in @buf to start writing the cipher text
558  * @buf: OUT: send buffer
559  * @pages: plaintext to wrap
560  *
561  * Return values:
562  *    %GSS_S_COMPLETE - success, @buf has been updated
563  *    %GSS_S_FAILURE - @buf could not be wrapped
564  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
565  */
566 static u32 gss_krb5_wrap(struct gss_ctx *gctx, int offset,
567                          struct xdr_buf *buf, struct page **pages)
568 {
569         struct krb5_ctx *kctx = gctx->internal_ctx_id;
570
571         return kctx->gk5e->wrap(kctx, offset, buf, pages);
572 }
573
574 /**
575  * gss_krb5_unwrap - gss_unwrap for the Kerberos GSS mechanism
576  * @gctx: initialized GSS context
577  * @offset: starting byte offset into @buf
578  * @len: size of ciphertext to unwrap
579  * @buf: ciphertext to unwrap
580  *
581  * Return values:
582  *    %GSS_S_COMPLETE - success, @buf has been updated
583  *    %GSS_S_DEFECTIVE_TOKEN - received blob is not valid
584  *    %GSS_S_BAD_SIG - computed and received checksums do not match
585  *    %GSS_S_FAILURE - @buf could not be unwrapped
586  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
587  */
588 static u32 gss_krb5_unwrap(struct gss_ctx *gctx, int offset,
589                            int len, struct xdr_buf *buf)
590 {
591         struct krb5_ctx *kctx = gctx->internal_ctx_id;
592
593         return kctx->gk5e->unwrap(kctx, offset, len, buf,
594                                   &gctx->slack, &gctx->align);
595 }
596
597 static const struct gss_api_ops gss_kerberos_ops = {
598         .gss_import_sec_context = gss_krb5_import_sec_context,
599         .gss_get_mic            = gss_krb5_get_mic,
600         .gss_verify_mic         = gss_krb5_verify_mic,
601         .gss_wrap               = gss_krb5_wrap,
602         .gss_unwrap             = gss_krb5_unwrap,
603         .gss_delete_sec_context = gss_krb5_delete_sec_context,
604 };
605
606 static struct pf_desc gss_kerberos_pfs[] = {
607         [0] = {
608                 .pseudoflavor = RPC_AUTH_GSS_KRB5,
609                 .qop = GSS_C_QOP_DEFAULT,
610                 .service = RPC_GSS_SVC_NONE,
611                 .name = "krb5",
612         },
613         [1] = {
614                 .pseudoflavor = RPC_AUTH_GSS_KRB5I,
615                 .qop = GSS_C_QOP_DEFAULT,
616                 .service = RPC_GSS_SVC_INTEGRITY,
617                 .name = "krb5i",
618                 .datatouch = true,
619         },
620         [2] = {
621                 .pseudoflavor = RPC_AUTH_GSS_KRB5P,
622                 .qop = GSS_C_QOP_DEFAULT,
623                 .service = RPC_GSS_SVC_PRIVACY,
624                 .name = "krb5p",
625                 .datatouch = true,
626         },
627 };
628
629 MODULE_ALIAS("rpc-auth-gss-krb5");
630 MODULE_ALIAS("rpc-auth-gss-krb5i");
631 MODULE_ALIAS("rpc-auth-gss-krb5p");
632 MODULE_ALIAS("rpc-auth-gss-390003");
633 MODULE_ALIAS("rpc-auth-gss-390004");
634 MODULE_ALIAS("rpc-auth-gss-390005");
635 MODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2");
636
637 static struct gss_api_mech gss_kerberos_mech = {
638         .gm_name        = "krb5",
639         .gm_owner       = THIS_MODULE,
640         .gm_oid         = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
641         .gm_ops         = &gss_kerberos_ops,
642         .gm_pf_num      = ARRAY_SIZE(gss_kerberos_pfs),
643         .gm_pfs         = gss_kerberos_pfs,
644         .gm_upcall_enctypes = gss_krb5_enctype_priority_list,
645 };
646
647 static int __init init_kerberos_module(void)
648 {
649         int status;
650
651         gss_krb5_prepare_enctype_priority_list();
652         status = gss_mech_register(&gss_kerberos_mech);
653         if (status)
654                 printk("Failed to register kerberos gss mechanism!\n");
655         return status;
656 }
657
658 static void __exit cleanup_kerberos_module(void)
659 {
660         gss_mech_unregister(&gss_kerberos_mech);
661 }
662
663 MODULE_LICENSE("GPL");
664 module_init(init_kerberos_module);
665 module_exit(cleanup_kerberos_module);