]> Git Repo - linux.git/blob - net/sunrpc/auth_gss/gss_krb5_mech.c
arm64: avoid prototype warnings for syscalls
[linux.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 <[email protected]>
9  *  J. Bruce Fields <[email protected]>
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
33 #if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED)
34 static int gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask);
35 static int gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask);
36 #endif
37 #if defined(CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM)
38 static int gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask);
39 #endif
40
41 static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = {
42 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES)
43         /*
44          * DES (All DES enctypes are mapped to the same gss functionality)
45          */
46         {
47           .etype = ENCTYPE_DES_CBC_RAW,
48           .ctype = CKSUMTYPE_RSA_MD5,
49           .name = "des-cbc-crc",
50           .encrypt_name = "cbc(des)",
51           .cksum_name = "md5",
52           .import_ctx = gss_krb5_import_ctx_des,
53           .get_mic = gss_krb5_get_mic_v1,
54           .verify_mic = gss_krb5_verify_mic_v1,
55           .wrap = gss_krb5_wrap_v1,
56           .unwrap = gss_krb5_unwrap_v1,
57           .signalg = SGN_ALG_DES_MAC_MD5,
58           .sealalg = SEAL_ALG_DES,
59           .keybytes = 7,
60           .keylength = 8,
61           .cksumlength = 8,
62           .keyed_cksum = 0,
63         },
64         /*
65          * 3DES
66          */
67         {
68           .etype = ENCTYPE_DES3_CBC_RAW,
69           .ctype = CKSUMTYPE_HMAC_SHA1_DES3,
70           .name = "des3-hmac-sha1",
71           .encrypt_name = "cbc(des3_ede)",
72           .cksum_name = "hmac(sha1)",
73           .import_ctx = gss_krb5_import_ctx_v1,
74           .derive_key = krb5_derive_key_v1,
75           .get_mic = gss_krb5_get_mic_v1,
76           .verify_mic = gss_krb5_verify_mic_v1,
77           .wrap = gss_krb5_wrap_v1,
78           .unwrap = gss_krb5_unwrap_v1,
79           .signalg = SGN_ALG_HMAC_SHA1_DES3_KD,
80           .sealalg = SEAL_ALG_DES3KD,
81           .keybytes = 21,
82           .keylength = 24,
83           .cksumlength = 20,
84           .keyed_cksum = 1,
85         },
86 #endif
87
88 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1)
89         /*
90          * AES-128 with SHA-1 (RFC 3962)
91          */
92         {
93           .etype = ENCTYPE_AES128_CTS_HMAC_SHA1_96,
94           .ctype = CKSUMTYPE_HMAC_SHA1_96_AES128,
95           .name = "aes128-cts",
96           .encrypt_name = "cts(cbc(aes))",
97           .aux_cipher = "cbc(aes)",
98           .cksum_name = "hmac(sha1)",
99           .import_ctx = gss_krb5_import_ctx_v2,
100           .derive_key = krb5_derive_key_v2,
101           .encrypt = gss_krb5_aes_encrypt,
102           .decrypt = gss_krb5_aes_decrypt,
103
104           .get_mic = gss_krb5_get_mic_v2,
105           .verify_mic = gss_krb5_verify_mic_v2,
106           .wrap = gss_krb5_wrap_v2,
107           .unwrap = gss_krb5_unwrap_v2,
108
109           .signalg = -1,
110           .sealalg = -1,
111           .keybytes = 16,
112           .keylength = BITS2OCTETS(128),
113           .Kc_length = BITS2OCTETS(128),
114           .Ke_length = BITS2OCTETS(128),
115           .Ki_length = BITS2OCTETS(128),
116           .cksumlength = BITS2OCTETS(96),
117           .keyed_cksum = 1,
118         },
119         /*
120          * AES-256 with SHA-1 (RFC 3962)
121          */
122         {
123           .etype = ENCTYPE_AES256_CTS_HMAC_SHA1_96,
124           .ctype = CKSUMTYPE_HMAC_SHA1_96_AES256,
125           .name = "aes256-cts",
126           .encrypt_name = "cts(cbc(aes))",
127           .aux_cipher = "cbc(aes)",
128           .cksum_name = "hmac(sha1)",
129           .import_ctx = gss_krb5_import_ctx_v2,
130           .derive_key = krb5_derive_key_v2,
131           .encrypt = gss_krb5_aes_encrypt,
132           .decrypt = gss_krb5_aes_decrypt,
133
134           .get_mic = gss_krb5_get_mic_v2,
135           .verify_mic = gss_krb5_verify_mic_v2,
136           .wrap = gss_krb5_wrap_v2,
137           .unwrap = gss_krb5_unwrap_v2,
138
139           .signalg = -1,
140           .sealalg = -1,
141           .keybytes = 32,
142           .keylength = BITS2OCTETS(256),
143           .Kc_length = BITS2OCTETS(256),
144           .Ke_length = BITS2OCTETS(256),
145           .Ki_length = BITS2OCTETS(256),
146           .cksumlength = BITS2OCTETS(96),
147           .keyed_cksum = 1,
148         },
149 #endif
150
151 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA)
152         /*
153          * Camellia-128 with CMAC (RFC 6803)
154          */
155         {
156                 .etype          = ENCTYPE_CAMELLIA128_CTS_CMAC,
157                 .ctype          = CKSUMTYPE_CMAC_CAMELLIA128,
158                 .name           = "camellia128-cts-cmac",
159                 .encrypt_name   = "cts(cbc(camellia))",
160                 .aux_cipher     = "cbc(camellia)",
161                 .cksum_name     = "cmac(camellia)",
162                 .cksumlength    = BITS2OCTETS(128),
163                 .keyed_cksum    = 1,
164                 .keylength      = BITS2OCTETS(128),
165                 .Kc_length      = BITS2OCTETS(128),
166                 .Ke_length      = BITS2OCTETS(128),
167                 .Ki_length      = BITS2OCTETS(128),
168
169                 .import_ctx     = gss_krb5_import_ctx_v2,
170                 .derive_key     = krb5_kdf_feedback_cmac,
171                 .encrypt        = gss_krb5_aes_encrypt,
172                 .decrypt        = gss_krb5_aes_decrypt,
173
174                 .get_mic        = gss_krb5_get_mic_v2,
175                 .verify_mic     = gss_krb5_verify_mic_v2,
176                 .wrap           = gss_krb5_wrap_v2,
177                 .unwrap         = gss_krb5_unwrap_v2,
178         },
179         /*
180          * Camellia-256 with CMAC (RFC 6803)
181          */
182         {
183                 .etype          = ENCTYPE_CAMELLIA256_CTS_CMAC,
184                 .ctype          = CKSUMTYPE_CMAC_CAMELLIA256,
185                 .name           = "camellia256-cts-cmac",
186                 .encrypt_name   = "cts(cbc(camellia))",
187                 .aux_cipher     = "cbc(camellia)",
188                 .cksum_name     = "cmac(camellia)",
189                 .cksumlength    = BITS2OCTETS(128),
190                 .keyed_cksum    = 1,
191                 .keylength      = BITS2OCTETS(256),
192                 .Kc_length      = BITS2OCTETS(256),
193                 .Ke_length      = BITS2OCTETS(256),
194                 .Ki_length      = BITS2OCTETS(256),
195
196                 .import_ctx     = gss_krb5_import_ctx_v2,
197                 .derive_key     = krb5_kdf_feedback_cmac,
198                 .encrypt        = gss_krb5_aes_encrypt,
199                 .decrypt        = gss_krb5_aes_decrypt,
200
201                 .get_mic        = gss_krb5_get_mic_v2,
202                 .verify_mic     = gss_krb5_verify_mic_v2,
203                 .wrap           = gss_krb5_wrap_v2,
204                 .unwrap         = gss_krb5_unwrap_v2,
205         },
206 #endif
207
208 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2)
209         /*
210          * AES-128 with SHA-256 (RFC 8009)
211          */
212         {
213                 .etype          = ENCTYPE_AES128_CTS_HMAC_SHA256_128,
214                 .ctype          = CKSUMTYPE_HMAC_SHA256_128_AES128,
215                 .name           = "aes128-cts-hmac-sha256-128",
216                 .encrypt_name   = "cts(cbc(aes))",
217                 .aux_cipher     = "cbc(aes)",
218                 .cksum_name     = "hmac(sha256)",
219                 .cksumlength    = BITS2OCTETS(128),
220                 .keyed_cksum    = 1,
221                 .keylength      = BITS2OCTETS(128),
222                 .Kc_length      = BITS2OCTETS(128),
223                 .Ke_length      = BITS2OCTETS(128),
224                 .Ki_length      = BITS2OCTETS(128),
225
226                 .import_ctx     = gss_krb5_import_ctx_v2,
227                 .derive_key     = krb5_kdf_hmac_sha2,
228                 .encrypt        = krb5_etm_encrypt,
229                 .decrypt        = krb5_etm_decrypt,
230
231                 .get_mic        = gss_krb5_get_mic_v2,
232                 .verify_mic     = gss_krb5_verify_mic_v2,
233                 .wrap           = gss_krb5_wrap_v2,
234                 .unwrap         = gss_krb5_unwrap_v2,
235         },
236         /*
237          * AES-256 with SHA-384 (RFC 8009)
238          */
239         {
240                 .etype          = ENCTYPE_AES256_CTS_HMAC_SHA384_192,
241                 .ctype          = CKSUMTYPE_HMAC_SHA384_192_AES256,
242                 .name           = "aes256-cts-hmac-sha384-192",
243                 .encrypt_name   = "cts(cbc(aes))",
244                 .aux_cipher     = "cbc(aes)",
245                 .cksum_name     = "hmac(sha384)",
246                 .cksumlength    = BITS2OCTETS(192),
247                 .keyed_cksum    = 1,
248                 .keylength      = BITS2OCTETS(256),
249                 .Kc_length      = BITS2OCTETS(192),
250                 .Ke_length      = BITS2OCTETS(256),
251                 .Ki_length      = BITS2OCTETS(192),
252
253                 .import_ctx     = gss_krb5_import_ctx_v2,
254                 .derive_key     = krb5_kdf_hmac_sha2,
255                 .encrypt        = krb5_etm_encrypt,
256                 .decrypt        = krb5_etm_decrypt,
257
258                 .get_mic        = gss_krb5_get_mic_v2,
259                 .verify_mic     = gss_krb5_verify_mic_v2,
260                 .wrap           = gss_krb5_wrap_v2,
261                 .unwrap         = gss_krb5_unwrap_v2,
262         },
263 #endif
264 };
265
266 /*
267  * The list of advertised enctypes is specified in order of most
268  * preferred to least.
269  */
270 static char gss_krb5_enctype_priority_list[64];
271
272 static void gss_krb5_prepare_enctype_priority_list(void)
273 {
274         static const u32 gss_krb5_enctypes[] = {
275 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2)
276                 ENCTYPE_AES256_CTS_HMAC_SHA384_192,
277                 ENCTYPE_AES128_CTS_HMAC_SHA256_128,
278 #endif
279 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA)
280                 ENCTYPE_CAMELLIA256_CTS_CMAC,
281                 ENCTYPE_CAMELLIA128_CTS_CMAC,
282 #endif
283 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1)
284                 ENCTYPE_AES256_CTS_HMAC_SHA1_96,
285                 ENCTYPE_AES128_CTS_HMAC_SHA1_96,
286 #endif
287 #if defined(CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_DES)
288                 ENCTYPE_DES3_CBC_SHA1,
289                 ENCTYPE_DES_CBC_MD5,
290                 ENCTYPE_DES_CBC_CRC,
291                 ENCTYPE_DES_CBC_MD4,
292 #endif
293         };
294         size_t total, i;
295         char buf[16];
296         char *sep;
297         int n;
298
299         sep = "";
300         gss_krb5_enctype_priority_list[0] = '\0';
301         for (total = 0, i = 0; i < ARRAY_SIZE(gss_krb5_enctypes); i++) {
302                 n = sprintf(buf, "%s%u", sep, gss_krb5_enctypes[i]);
303                 if (n < 0)
304                         break;
305                 if (total + n >= sizeof(gss_krb5_enctype_priority_list))
306                         break;
307                 strcat(gss_krb5_enctype_priority_list, buf);
308                 sep = ",";
309                 total += n;
310         }
311 }
312
313 /**
314  * gss_krb5_lookup_enctype - Retrieve profile information for a given enctype
315  * @etype: ENCTYPE value
316  *
317  * Returns a pointer to a gss_krb5_enctype structure, or NULL if no
318  * matching etype is found.
319  */
320 VISIBLE_IF_KUNIT
321 const struct gss_krb5_enctype *gss_krb5_lookup_enctype(u32 etype)
322 {
323         size_t i;
324
325         for (i = 0; i < ARRAY_SIZE(supported_gss_krb5_enctypes); i++)
326                 if (supported_gss_krb5_enctypes[i].etype == etype)
327                         return &supported_gss_krb5_enctypes[i];
328         return NULL;
329 }
330 EXPORT_SYMBOL_IF_KUNIT(gss_krb5_lookup_enctype);
331
332 static struct crypto_sync_skcipher *
333 gss_krb5_alloc_cipher_v1(struct krb5_ctx *ctx, struct xdr_netobj *key)
334 {
335         struct crypto_sync_skcipher *tfm;
336
337         tfm = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0);
338         if (IS_ERR(tfm))
339                 return NULL;
340         if (crypto_sync_skcipher_setkey(tfm, key->data, key->len)) {
341                 crypto_free_sync_skcipher(tfm);
342                 return NULL;
343         }
344         return tfm;
345 }
346
347 static inline const void *
348 get_key(const void *p, const void *end,
349         struct krb5_ctx *ctx, struct crypto_sync_skcipher **res)
350 {
351         struct crypto_sync_skcipher *tfm;
352         struct xdr_netobj       key;
353         int                     alg;
354
355         p = simple_get_bytes(p, end, &alg, sizeof(alg));
356         if (IS_ERR(p))
357                 goto out_err;
358         switch (alg) {
359         case ENCTYPE_DES_CBC_CRC:
360         case ENCTYPE_DES_CBC_MD4:
361         case ENCTYPE_DES_CBC_MD5:
362                 /* Map all these key types to ENCTYPE_DES_CBC_RAW */
363                 alg = ENCTYPE_DES_CBC_RAW;
364                 break;
365         }
366         if (!gss_krb5_lookup_enctype(alg)) {
367                 pr_warn("gss_krb5: unsupported enctype: %d\n", alg);
368                 goto out_err_inval;
369         }
370
371         p = simple_get_netobj(p, end, &key);
372         if (IS_ERR(p))
373                 goto out_err;
374         tfm = gss_krb5_alloc_cipher_v1(ctx, &key);
375         kfree(key.data);
376         if (!tfm) {
377                 pr_warn("gss_krb5: failed to initialize cipher '%s'\n",
378                         ctx->gk5e->encrypt_name);
379                 goto out_err_inval;
380         }
381         *res = tfm;
382
383         return p;
384
385 out_err_inval:
386         p = ERR_PTR(-EINVAL);
387 out_err:
388         return p;
389 }
390
391 static int
392 gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
393 {
394         u32 seq_send;
395         int tmp;
396         u32 time32;
397
398         p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
399         if (IS_ERR(p))
400                 goto out_err;
401
402         /* Old format supports only DES!  Any other enctype uses new format */
403         ctx->enctype = ENCTYPE_DES_CBC_RAW;
404
405         ctx->gk5e = gss_krb5_lookup_enctype(ctx->enctype);
406         if (ctx->gk5e == NULL) {
407                 p = ERR_PTR(-EINVAL);
408                 goto out_err;
409         }
410
411         /* The downcall format was designed before we completely understood
412          * the uses of the context fields; so it includes some stuff we
413          * just give some minimal sanity-checking, and some we ignore
414          * completely (like the next twenty bytes): */
415         if (unlikely(p + 20 > end || p + 20 < p)) {
416                 p = ERR_PTR(-EFAULT);
417                 goto out_err;
418         }
419         p += 20;
420         p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
421         if (IS_ERR(p))
422                 goto out_err;
423         if (tmp != SGN_ALG_DES_MAC_MD5) {
424                 p = ERR_PTR(-ENOSYS);
425                 goto out_err;
426         }
427         p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
428         if (IS_ERR(p))
429                 goto out_err;
430         if (tmp != SEAL_ALG_DES) {
431                 p = ERR_PTR(-ENOSYS);
432                 goto out_err;
433         }
434         p = simple_get_bytes(p, end, &time32, sizeof(time32));
435         if (IS_ERR(p))
436                 goto out_err;
437         /* unsigned 32-bit time overflows in year 2106 */
438         ctx->endtime = (time64_t)time32;
439         p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send));
440         if (IS_ERR(p))
441                 goto out_err;
442         atomic_set(&ctx->seq_send, seq_send);
443         p = simple_get_netobj(p, end, &ctx->mech_used);
444         if (IS_ERR(p))
445                 goto out_err;
446         p = get_key(p, end, ctx, &ctx->enc);
447         if (IS_ERR(p))
448                 goto out_err_free_mech;
449         p = get_key(p, end, ctx, &ctx->seq);
450         if (IS_ERR(p))
451                 goto out_err_free_key1;
452         if (p != end) {
453                 p = ERR_PTR(-EFAULT);
454                 goto out_err_free_key2;
455         }
456
457         return 0;
458
459 out_err_free_key2:
460         crypto_free_sync_skcipher(ctx->seq);
461 out_err_free_key1:
462         crypto_free_sync_skcipher(ctx->enc);
463 out_err_free_mech:
464         kfree(ctx->mech_used.data);
465 out_err:
466         return PTR_ERR(p);
467 }
468
469 #if defined(CONFIG_RPCSEC_GSS_KRB5_SIMPLIFIED)
470 static int
471 gss_krb5_import_ctx_des(struct krb5_ctx *ctx, gfp_t gfp_mask)
472 {
473         return -EINVAL;
474 }
475
476 static int
477 gss_krb5_import_ctx_v1(struct krb5_ctx *ctx, gfp_t gfp_mask)
478 {
479         struct xdr_netobj keyin, keyout;
480
481         keyin.data = ctx->Ksess;
482         keyin.len = ctx->gk5e->keylength;
483
484         ctx->seq = gss_krb5_alloc_cipher_v1(ctx, &keyin);
485         if (ctx->seq == NULL)
486                 goto out_err;
487         ctx->enc = gss_krb5_alloc_cipher_v1(ctx, &keyin);
488         if (ctx->enc == NULL)
489                 goto out_free_seq;
490
491         /* derive cksum */
492         keyout.data = ctx->cksum;
493         keyout.len = ctx->gk5e->keylength;
494         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_SIGN,
495                             KEY_USAGE_SEED_CHECKSUM, gfp_mask))
496                 goto out_free_enc;
497
498         return 0;
499
500 out_free_enc:
501         crypto_free_sync_skcipher(ctx->enc);
502 out_free_seq:
503         crypto_free_sync_skcipher(ctx->seq);
504 out_err:
505         return -EINVAL;
506 }
507 #endif
508
509 #if defined(CONFIG_RPCSEC_GSS_KRB5_CRYPTOSYSTEM)
510
511 static struct crypto_sync_skcipher *
512 gss_krb5_alloc_cipher_v2(const char *cname, const struct xdr_netobj *key)
513 {
514         struct crypto_sync_skcipher *tfm;
515
516         tfm = crypto_alloc_sync_skcipher(cname, 0, 0);
517         if (IS_ERR(tfm))
518                 return NULL;
519         if (crypto_sync_skcipher_setkey(tfm, key->data, key->len)) {
520                 crypto_free_sync_skcipher(tfm);
521                 return NULL;
522         }
523         return tfm;
524 }
525
526 static struct crypto_ahash *
527 gss_krb5_alloc_hash_v2(struct krb5_ctx *kctx, const struct xdr_netobj *key)
528 {
529         struct crypto_ahash *tfm;
530
531         tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
532         if (IS_ERR(tfm))
533                 return NULL;
534         if (crypto_ahash_setkey(tfm, key->data, key->len)) {
535                 crypto_free_ahash(tfm);
536                 return NULL;
537         }
538         return tfm;
539 }
540
541 static int
542 gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
543 {
544         struct xdr_netobj keyin = {
545                 .len    = ctx->gk5e->keylength,
546                 .data   = ctx->Ksess,
547         };
548         struct xdr_netobj keyout;
549         int ret = -EINVAL;
550
551         keyout.data = kmalloc(GSS_KRB5_MAX_KEYLEN, gfp_mask);
552         if (!keyout.data)
553                 return -ENOMEM;
554
555         /* initiator seal encryption */
556         keyout.len = ctx->gk5e->Ke_length;
557         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL,
558                             KEY_USAGE_SEED_ENCRYPTION, gfp_mask))
559                 goto out;
560         ctx->initiator_enc = gss_krb5_alloc_cipher_v2(ctx->gk5e->encrypt_name,
561                                                       &keyout);
562         if (ctx->initiator_enc == NULL)
563                 goto out;
564         if (ctx->gk5e->aux_cipher) {
565                 ctx->initiator_enc_aux =
566                         gss_krb5_alloc_cipher_v2(ctx->gk5e->aux_cipher,
567                                                  &keyout);
568                 if (ctx->initiator_enc_aux == NULL)
569                         goto out_free;
570         }
571
572         /* acceptor seal encryption */
573         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL,
574                             KEY_USAGE_SEED_ENCRYPTION, gfp_mask))
575                 goto out_free;
576         ctx->acceptor_enc = gss_krb5_alloc_cipher_v2(ctx->gk5e->encrypt_name,
577                                                      &keyout);
578         if (ctx->acceptor_enc == NULL)
579                 goto out_free;
580         if (ctx->gk5e->aux_cipher) {
581                 ctx->acceptor_enc_aux =
582                         gss_krb5_alloc_cipher_v2(ctx->gk5e->aux_cipher,
583                                                  &keyout);
584                 if (ctx->acceptor_enc_aux == NULL)
585                         goto out_free;
586         }
587
588         /* initiator sign checksum */
589         keyout.len = ctx->gk5e->Kc_length;
590         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SIGN,
591                             KEY_USAGE_SEED_CHECKSUM, gfp_mask))
592                 goto out_free;
593         ctx->initiator_sign = gss_krb5_alloc_hash_v2(ctx, &keyout);
594         if (ctx->initiator_sign == NULL)
595                 goto out_free;
596
597         /* acceptor sign checksum */
598         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SIGN,
599                             KEY_USAGE_SEED_CHECKSUM, gfp_mask))
600                 goto out_free;
601         ctx->acceptor_sign = gss_krb5_alloc_hash_v2(ctx, &keyout);
602         if (ctx->acceptor_sign == NULL)
603                 goto out_free;
604
605         /* initiator seal integrity */
606         keyout.len = ctx->gk5e->Ki_length;
607         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_INITIATOR_SEAL,
608                             KEY_USAGE_SEED_INTEGRITY, gfp_mask))
609                 goto out_free;
610         ctx->initiator_integ = gss_krb5_alloc_hash_v2(ctx, &keyout);
611         if (ctx->initiator_integ == NULL)
612                 goto out_free;
613
614         /* acceptor seal integrity */
615         if (krb5_derive_key(ctx, &keyin, &keyout, KG_USAGE_ACCEPTOR_SEAL,
616                             KEY_USAGE_SEED_INTEGRITY, gfp_mask))
617                 goto out_free;
618         ctx->acceptor_integ = gss_krb5_alloc_hash_v2(ctx, &keyout);
619         if (ctx->acceptor_integ == NULL)
620                 goto out_free;
621
622         ret = 0;
623 out:
624         kfree_sensitive(keyout.data);
625         return ret;
626
627 out_free:
628         crypto_free_ahash(ctx->acceptor_integ);
629         crypto_free_ahash(ctx->initiator_integ);
630         crypto_free_ahash(ctx->acceptor_sign);
631         crypto_free_ahash(ctx->initiator_sign);
632         crypto_free_sync_skcipher(ctx->acceptor_enc_aux);
633         crypto_free_sync_skcipher(ctx->acceptor_enc);
634         crypto_free_sync_skcipher(ctx->initiator_enc_aux);
635         crypto_free_sync_skcipher(ctx->initiator_enc);
636         goto out;
637 }
638
639 #endif
640
641 static int
642 gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
643                 gfp_t gfp_mask)
644 {
645         u64 seq_send64;
646         int keylen;
647         u32 time32;
648
649         p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
650         if (IS_ERR(p))
651                 goto out_err;
652         ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR;
653
654         p = simple_get_bytes(p, end, &time32, sizeof(time32));
655         if (IS_ERR(p))
656                 goto out_err;
657         /* unsigned 32-bit time overflows in year 2106 */
658         ctx->endtime = (time64_t)time32;
659         p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64));
660         if (IS_ERR(p))
661                 goto out_err;
662         atomic64_set(&ctx->seq_send64, seq_send64);
663         /* set seq_send for use by "older" enctypes */
664         atomic_set(&ctx->seq_send, seq_send64);
665         if (seq_send64 != atomic_read(&ctx->seq_send)) {
666                 dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__,
667                         seq_send64, atomic_read(&ctx->seq_send));
668                 p = ERR_PTR(-EINVAL);
669                 goto out_err;
670         }
671         p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype));
672         if (IS_ERR(p))
673                 goto out_err;
674         /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */
675         if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1)
676                 ctx->enctype = ENCTYPE_DES3_CBC_RAW;
677         ctx->gk5e = gss_krb5_lookup_enctype(ctx->enctype);
678         if (ctx->gk5e == NULL) {
679                 dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n",
680                         ctx->enctype);
681                 p = ERR_PTR(-EINVAL);
682                 goto out_err;
683         }
684         keylen = ctx->gk5e->keylength;
685
686         p = simple_get_bytes(p, end, ctx->Ksess, keylen);
687         if (IS_ERR(p))
688                 goto out_err;
689
690         if (p != end) {
691                 p = ERR_PTR(-EINVAL);
692                 goto out_err;
693         }
694
695         ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data,
696                                       gss_kerberos_mech.gm_oid.len, gfp_mask);
697         if (unlikely(ctx->mech_used.data == NULL)) {
698                 p = ERR_PTR(-ENOMEM);
699                 goto out_err;
700         }
701         ctx->mech_used.len = gss_kerberos_mech.gm_oid.len;
702
703         return ctx->gk5e->import_ctx(ctx, gfp_mask);
704
705 out_err:
706         return PTR_ERR(p);
707 }
708
709 static int
710 gss_krb5_import_sec_context(const void *p, size_t len, struct gss_ctx *ctx_id,
711                             time64_t *endtime, gfp_t gfp_mask)
712 {
713         const void *end = (const void *)((const char *)p + len);
714         struct  krb5_ctx *ctx;
715         int ret;
716
717         ctx = kzalloc(sizeof(*ctx), gfp_mask);
718         if (ctx == NULL)
719                 return -ENOMEM;
720
721         if (len == 85)
722                 ret = gss_import_v1_context(p, end, ctx);
723         else
724                 ret = gss_import_v2_context(p, end, ctx, gfp_mask);
725         memzero_explicit(&ctx->Ksess, sizeof(ctx->Ksess));
726         if (ret) {
727                 kfree(ctx);
728                 return ret;
729         }
730
731         ctx_id->internal_ctx_id = ctx;
732         if (endtime)
733                 *endtime = ctx->endtime;
734         return 0;
735 }
736
737 static void
738 gss_krb5_delete_sec_context(void *internal_ctx)
739 {
740         struct krb5_ctx *kctx = internal_ctx;
741
742         crypto_free_sync_skcipher(kctx->seq);
743         crypto_free_sync_skcipher(kctx->enc);
744         crypto_free_sync_skcipher(kctx->acceptor_enc);
745         crypto_free_sync_skcipher(kctx->initiator_enc);
746         crypto_free_sync_skcipher(kctx->acceptor_enc_aux);
747         crypto_free_sync_skcipher(kctx->initiator_enc_aux);
748         crypto_free_ahash(kctx->acceptor_sign);
749         crypto_free_ahash(kctx->initiator_sign);
750         crypto_free_ahash(kctx->acceptor_integ);
751         crypto_free_ahash(kctx->initiator_integ);
752         kfree(kctx->mech_used.data);
753         kfree(kctx);
754 }
755
756 /**
757  * gss_krb5_get_mic - get_mic for the Kerberos GSS mechanism
758  * @gctx: GSS context
759  * @text: plaintext to checksum
760  * @token: buffer into which to write the computed checksum
761  *
762  * Return values:
763  *    %GSS_S_COMPLETE - success, and @token is filled in
764  *    %GSS_S_FAILURE - checksum could not be generated
765  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
766  */
767 static u32 gss_krb5_get_mic(struct gss_ctx *gctx, struct xdr_buf *text,
768                             struct xdr_netobj *token)
769 {
770         struct krb5_ctx *kctx = gctx->internal_ctx_id;
771
772         return kctx->gk5e->get_mic(kctx, text, token);
773 }
774
775 /**
776  * gss_krb5_verify_mic - verify_mic for the Kerberos GSS mechanism
777  * @gctx: GSS context
778  * @message_buffer: plaintext to check
779  * @read_token: received checksum to check
780  *
781  * Return values:
782  *    %GSS_S_COMPLETE - computed and received checksums match
783  *    %GSS_S_DEFECTIVE_TOKEN - received checksum is not valid
784  *    %GSS_S_BAD_SIG - computed and received checksums do not match
785  *    %GSS_S_FAILURE - received checksum could not be checked
786  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
787  */
788 static u32 gss_krb5_verify_mic(struct gss_ctx *gctx,
789                                struct xdr_buf *message_buffer,
790                                struct xdr_netobj *read_token)
791 {
792         struct krb5_ctx *kctx = gctx->internal_ctx_id;
793
794         return kctx->gk5e->verify_mic(kctx, message_buffer, read_token);
795 }
796
797 /**
798  * gss_krb5_wrap - gss_wrap for the Kerberos GSS mechanism
799  * @gctx: initialized GSS context
800  * @offset: byte offset in @buf to start writing the cipher text
801  * @buf: OUT: send buffer
802  * @pages: plaintext to wrap
803  *
804  * Return values:
805  *    %GSS_S_COMPLETE - success, @buf has been updated
806  *    %GSS_S_FAILURE - @buf could not be wrapped
807  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
808  */
809 static u32 gss_krb5_wrap(struct gss_ctx *gctx, int offset,
810                          struct xdr_buf *buf, struct page **pages)
811 {
812         struct krb5_ctx *kctx = gctx->internal_ctx_id;
813
814         return kctx->gk5e->wrap(kctx, offset, buf, pages);
815 }
816
817 /**
818  * gss_krb5_unwrap - gss_unwrap for the Kerberos GSS mechanism
819  * @gctx: initialized GSS context
820  * @offset: starting byte offset into @buf
821  * @len: size of ciphertext to unwrap
822  * @buf: ciphertext to unwrap
823  *
824  * Return values:
825  *    %GSS_S_COMPLETE - success, @buf has been updated
826  *    %GSS_S_DEFECTIVE_TOKEN - received blob is not valid
827  *    %GSS_S_BAD_SIG - computed and received checksums do not match
828  *    %GSS_S_FAILURE - @buf could not be unwrapped
829  *    %GSS_S_CONTEXT_EXPIRED - Kerberos context is no longer valid
830  */
831 static u32 gss_krb5_unwrap(struct gss_ctx *gctx, int offset,
832                            int len, struct xdr_buf *buf)
833 {
834         struct krb5_ctx *kctx = gctx->internal_ctx_id;
835
836         return kctx->gk5e->unwrap(kctx, offset, len, buf,
837                                   &gctx->slack, &gctx->align);
838 }
839
840 static const struct gss_api_ops gss_kerberos_ops = {
841         .gss_import_sec_context = gss_krb5_import_sec_context,
842         .gss_get_mic            = gss_krb5_get_mic,
843         .gss_verify_mic         = gss_krb5_verify_mic,
844         .gss_wrap               = gss_krb5_wrap,
845         .gss_unwrap             = gss_krb5_unwrap,
846         .gss_delete_sec_context = gss_krb5_delete_sec_context,
847 };
848
849 static struct pf_desc gss_kerberos_pfs[] = {
850         [0] = {
851                 .pseudoflavor = RPC_AUTH_GSS_KRB5,
852                 .qop = GSS_C_QOP_DEFAULT,
853                 .service = RPC_GSS_SVC_NONE,
854                 .name = "krb5",
855         },
856         [1] = {
857                 .pseudoflavor = RPC_AUTH_GSS_KRB5I,
858                 .qop = GSS_C_QOP_DEFAULT,
859                 .service = RPC_GSS_SVC_INTEGRITY,
860                 .name = "krb5i",
861                 .datatouch = true,
862         },
863         [2] = {
864                 .pseudoflavor = RPC_AUTH_GSS_KRB5P,
865                 .qop = GSS_C_QOP_DEFAULT,
866                 .service = RPC_GSS_SVC_PRIVACY,
867                 .name = "krb5p",
868                 .datatouch = true,
869         },
870 };
871
872 MODULE_ALIAS("rpc-auth-gss-krb5");
873 MODULE_ALIAS("rpc-auth-gss-krb5i");
874 MODULE_ALIAS("rpc-auth-gss-krb5p");
875 MODULE_ALIAS("rpc-auth-gss-390003");
876 MODULE_ALIAS("rpc-auth-gss-390004");
877 MODULE_ALIAS("rpc-auth-gss-390005");
878 MODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2");
879
880 static struct gss_api_mech gss_kerberos_mech = {
881         .gm_name        = "krb5",
882         .gm_owner       = THIS_MODULE,
883         .gm_oid         = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" },
884         .gm_ops         = &gss_kerberos_ops,
885         .gm_pf_num      = ARRAY_SIZE(gss_kerberos_pfs),
886         .gm_pfs         = gss_kerberos_pfs,
887         .gm_upcall_enctypes = gss_krb5_enctype_priority_list,
888 };
889
890 static int __init init_kerberos_module(void)
891 {
892         int status;
893
894         gss_krb5_prepare_enctype_priority_list();
895         status = gss_mech_register(&gss_kerberos_mech);
896         if (status)
897                 printk("Failed to register kerberos gss mechanism!\n");
898         return status;
899 }
900
901 static void __exit cleanup_kerberos_module(void)
902 {
903         gss_mech_unregister(&gss_kerberos_mech);
904 }
905
906 MODULE_LICENSE("GPL");
907 module_init(init_kerberos_module);
908 module_exit(cleanup_kerberos_module);
This page took 0.091557 seconds and 4 git commands to generate.