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 <linux/sunrpc/gss_krb5_enctypes.h> 23 24 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 25 # define RPCDBG_FACILITY RPCDBG_AUTH 26 #endif 27 28 static struct gss_api_mech gss_kerberos_mech; /* forward declaration */ 29 30 static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { 31 #ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES 32 /* 33 * DES (All DES enctypes are mapped to the same gss functionality) 34 */ 35 { 36 .etype = ENCTYPE_DES_CBC_RAW, 37 .ctype = CKSUMTYPE_RSA_MD5, 38 .name = "des-cbc-crc", 39 .encrypt_name = "cbc(des)", 40 .cksum_name = "md5", 41 .encrypt = krb5_encrypt, 42 .decrypt = krb5_decrypt, 43 .mk_key = NULL, 44 .signalg = SGN_ALG_DES_MAC_MD5, 45 .sealalg = SEAL_ALG_DES, 46 .keybytes = 7, 47 .keylength = 8, 48 .blocksize = 8, 49 .conflen = 8, 50 .cksumlength = 8, 51 .keyed_cksum = 0, 52 }, 53 #endif /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */ 54 /* 55 * 3DES 56 */ 57 { 58 .etype = ENCTYPE_DES3_CBC_RAW, 59 .ctype = CKSUMTYPE_HMAC_SHA1_DES3, 60 .name = "des3-hmac-sha1", 61 .encrypt_name = "cbc(des3_ede)", 62 .cksum_name = "hmac(sha1)", 63 .encrypt = krb5_encrypt, 64 .decrypt = krb5_decrypt, 65 .mk_key = gss_krb5_des3_make_key, 66 .signalg = SGN_ALG_HMAC_SHA1_DES3_KD, 67 .sealalg = SEAL_ALG_DES3KD, 68 .keybytes = 21, 69 .keylength = 24, 70 .blocksize = 8, 71 .conflen = 8, 72 .cksumlength = 20, 73 .keyed_cksum = 1, 74 }, 75 /* 76 * AES128 77 */ 78 { 79 .etype = ENCTYPE_AES128_CTS_HMAC_SHA1_96, 80 .ctype = CKSUMTYPE_HMAC_SHA1_96_AES128, 81 .name = "aes128-cts", 82 .encrypt_name = "cts(cbc(aes))", 83 .cksum_name = "hmac(sha1)", 84 .encrypt = krb5_encrypt, 85 .decrypt = krb5_decrypt, 86 .mk_key = gss_krb5_aes_make_key, 87 .encrypt_v2 = gss_krb5_aes_encrypt, 88 .decrypt_v2 = gss_krb5_aes_decrypt, 89 .signalg = -1, 90 .sealalg = -1, 91 .keybytes = 16, 92 .keylength = 16, 93 .blocksize = 16, 94 .conflen = 16, 95 .cksumlength = 12, 96 .keyed_cksum = 1, 97 }, 98 /* 99 * AES256 100 */ 101 { 102 .etype = ENCTYPE_AES256_CTS_HMAC_SHA1_96, 103 .ctype = CKSUMTYPE_HMAC_SHA1_96_AES256, 104 .name = "aes256-cts", 105 .encrypt_name = "cts(cbc(aes))", 106 .cksum_name = "hmac(sha1)", 107 .encrypt = krb5_encrypt, 108 .decrypt = krb5_decrypt, 109 .mk_key = gss_krb5_aes_make_key, 110 .encrypt_v2 = gss_krb5_aes_encrypt, 111 .decrypt_v2 = gss_krb5_aes_decrypt, 112 .signalg = -1, 113 .sealalg = -1, 114 .keybytes = 32, 115 .keylength = 32, 116 .blocksize = 16, 117 .conflen = 16, 118 .cksumlength = 12, 119 .keyed_cksum = 1, 120 }, 121 }; 122 123 static const int num_supported_enctypes = 124 ARRAY_SIZE(supported_gss_krb5_enctypes); 125 126 static int 127 supported_gss_krb5_enctype(int etype) 128 { 129 int i; 130 for (i = 0; i < num_supported_enctypes; i++) 131 if (supported_gss_krb5_enctypes[i].etype == etype) 132 return 1; 133 return 0; 134 } 135 136 static const struct gss_krb5_enctype * 137 get_gss_krb5_enctype(int etype) 138 { 139 int i; 140 for (i = 0; i < num_supported_enctypes; i++) 141 if (supported_gss_krb5_enctypes[i].etype == etype) 142 return &supported_gss_krb5_enctypes[i]; 143 return NULL; 144 } 145 146 static const void * 147 simple_get_bytes(const void *p, const void *end, void *res, int len) 148 { 149 const void *q = (const void *)((const char *)p + len); 150 if (unlikely(q > end || q < p)) 151 return ERR_PTR(-EFAULT); 152 memcpy(res, p, len); 153 return q; 154 } 155 156 static const void * 157 simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) 158 { 159 const void *q; 160 unsigned int len; 161 162 p = simple_get_bytes(p, end, &len, sizeof(len)); 163 if (IS_ERR(p)) 164 return p; 165 q = (const void *)((const char *)p + len); 166 if (unlikely(q > end || q < p)) 167 return ERR_PTR(-EFAULT); 168 res->data = kmemdup(p, len, GFP_NOFS); 169 if (unlikely(res->data == NULL)) 170 return ERR_PTR(-ENOMEM); 171 res->len = len; 172 return q; 173 } 174 175 static inline const void * 176 get_key(const void *p, const void *end, 177 struct krb5_ctx *ctx, struct crypto_sync_skcipher **res) 178 { 179 struct xdr_netobj key; 180 int alg; 181 182 p = simple_get_bytes(p, end, &alg, sizeof(alg)); 183 if (IS_ERR(p)) 184 goto out_err; 185 186 switch (alg) { 187 case ENCTYPE_DES_CBC_CRC: 188 case ENCTYPE_DES_CBC_MD4: 189 case ENCTYPE_DES_CBC_MD5: 190 /* Map all these key types to ENCTYPE_DES_CBC_RAW */ 191 alg = ENCTYPE_DES_CBC_RAW; 192 break; 193 } 194 195 if (!supported_gss_krb5_enctype(alg)) { 196 printk(KERN_WARNING "gss_kerberos_mech: unsupported " 197 "encryption key algorithm %d\n", alg); 198 p = ERR_PTR(-EINVAL); 199 goto out_err; 200 } 201 p = simple_get_netobj(p, end, &key); 202 if (IS_ERR(p)) 203 goto out_err; 204 205 *res = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 206 if (IS_ERR(*res)) { 207 printk(KERN_WARNING "gss_kerberos_mech: unable to initialize " 208 "crypto algorithm %s\n", ctx->gk5e->encrypt_name); 209 *res = NULL; 210 goto out_err_free_key; 211 } 212 if (crypto_sync_skcipher_setkey(*res, key.data, key.len)) { 213 printk(KERN_WARNING "gss_kerberos_mech: error setting key for " 214 "crypto algorithm %s\n", ctx->gk5e->encrypt_name); 215 goto out_err_free_tfm; 216 } 217 218 kfree(key.data); 219 return p; 220 221 out_err_free_tfm: 222 crypto_free_sync_skcipher(*res); 223 out_err_free_key: 224 kfree(key.data); 225 p = ERR_PTR(-EINVAL); 226 out_err: 227 return p; 228 } 229 230 static int 231 gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) 232 { 233 u32 seq_send; 234 int tmp; 235 u32 time32; 236 237 p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); 238 if (IS_ERR(p)) 239 goto out_err; 240 241 /* Old format supports only DES! Any other enctype uses new format */ 242 ctx->enctype = ENCTYPE_DES_CBC_RAW; 243 244 ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); 245 if (ctx->gk5e == NULL) { 246 p = ERR_PTR(-EINVAL); 247 goto out_err; 248 } 249 250 /* The downcall format was designed before we completely understood 251 * the uses of the context fields; so it includes some stuff we 252 * just give some minimal sanity-checking, and some we ignore 253 * completely (like the next twenty bytes): */ 254 if (unlikely(p + 20 > end || p + 20 < p)) { 255 p = ERR_PTR(-EFAULT); 256 goto out_err; 257 } 258 p += 20; 259 p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); 260 if (IS_ERR(p)) 261 goto out_err; 262 if (tmp != SGN_ALG_DES_MAC_MD5) { 263 p = ERR_PTR(-ENOSYS); 264 goto out_err; 265 } 266 p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); 267 if (IS_ERR(p)) 268 goto out_err; 269 if (tmp != SEAL_ALG_DES) { 270 p = ERR_PTR(-ENOSYS); 271 goto out_err; 272 } 273 p = simple_get_bytes(p, end, &time32, sizeof(time32)); 274 if (IS_ERR(p)) 275 goto out_err; 276 /* unsigned 32-bit time overflows in year 2106 */ 277 ctx->endtime = (time64_t)time32; 278 p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send)); 279 if (IS_ERR(p)) 280 goto out_err; 281 atomic_set(&ctx->seq_send, seq_send); 282 p = simple_get_netobj(p, end, &ctx->mech_used); 283 if (IS_ERR(p)) 284 goto out_err; 285 p = get_key(p, end, ctx, &ctx->enc); 286 if (IS_ERR(p)) 287 goto out_err_free_mech; 288 p = get_key(p, end, ctx, &ctx->seq); 289 if (IS_ERR(p)) 290 goto out_err_free_key1; 291 if (p != end) { 292 p = ERR_PTR(-EFAULT); 293 goto out_err_free_key2; 294 } 295 296 return 0; 297 298 out_err_free_key2: 299 crypto_free_sync_skcipher(ctx->seq); 300 out_err_free_key1: 301 crypto_free_sync_skcipher(ctx->enc); 302 out_err_free_mech: 303 kfree(ctx->mech_used.data); 304 out_err: 305 return PTR_ERR(p); 306 } 307 308 static struct crypto_sync_skcipher * 309 context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) 310 { 311 struct crypto_sync_skcipher *cp; 312 313 cp = crypto_alloc_sync_skcipher(cname, 0, 0); 314 if (IS_ERR(cp)) { 315 dprintk("gss_kerberos_mech: unable to initialize " 316 "crypto algorithm %s\n", cname); 317 return NULL; 318 } 319 if (crypto_sync_skcipher_setkey(cp, key, ctx->gk5e->keylength)) { 320 dprintk("gss_kerberos_mech: error setting key for " 321 "crypto algorithm %s\n", cname); 322 crypto_free_sync_skcipher(cp); 323 return NULL; 324 } 325 return cp; 326 } 327 328 static inline void 329 set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed) 330 { 331 cdata[0] = (usage>>24)&0xff; 332 cdata[1] = (usage>>16)&0xff; 333 cdata[2] = (usage>>8)&0xff; 334 cdata[3] = usage&0xff; 335 cdata[4] = seed; 336 } 337 338 static int 339 context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask) 340 { 341 struct xdr_netobj c, keyin, keyout; 342 u8 cdata[GSS_KRB5_K5CLENGTH]; 343 u32 err; 344 345 c.len = GSS_KRB5_K5CLENGTH; 346 c.data = cdata; 347 348 keyin.data = ctx->Ksess; 349 keyin.len = ctx->gk5e->keylength; 350 keyout.len = ctx->gk5e->keylength; 351 352 /* seq uses the raw key */ 353 ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, 354 ctx->Ksess); 355 if (ctx->seq == NULL) 356 goto out_err; 357 358 ctx->enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, 359 ctx->Ksess); 360 if (ctx->enc == NULL) 361 goto out_free_seq; 362 363 /* derive cksum */ 364 set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM); 365 keyout.data = ctx->cksum; 366 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 367 if (err) { 368 dprintk("%s: Error %d deriving cksum key\n", 369 __func__, err); 370 goto out_free_enc; 371 } 372 373 return 0; 374 375 out_free_enc: 376 crypto_free_sync_skcipher(ctx->enc); 377 out_free_seq: 378 crypto_free_sync_skcipher(ctx->seq); 379 out_err: 380 return -EINVAL; 381 } 382 383 static int 384 context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) 385 { 386 struct xdr_netobj c, keyin, keyout; 387 u8 cdata[GSS_KRB5_K5CLENGTH]; 388 u32 err; 389 390 c.len = GSS_KRB5_K5CLENGTH; 391 c.data = cdata; 392 393 keyin.data = ctx->Ksess; 394 keyin.len = ctx->gk5e->keylength; 395 keyout.len = ctx->gk5e->keylength; 396 397 /* initiator seal encryption */ 398 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 399 keyout.data = ctx->initiator_seal; 400 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 401 if (err) { 402 dprintk("%s: Error %d deriving initiator_seal key\n", 403 __func__, err); 404 goto out_err; 405 } 406 ctx->initiator_enc = context_v2_alloc_cipher(ctx, 407 ctx->gk5e->encrypt_name, 408 ctx->initiator_seal); 409 if (ctx->initiator_enc == NULL) 410 goto out_err; 411 412 /* acceptor seal encryption */ 413 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 414 keyout.data = ctx->acceptor_seal; 415 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 416 if (err) { 417 dprintk("%s: Error %d deriving acceptor_seal key\n", 418 __func__, err); 419 goto out_free_initiator_enc; 420 } 421 ctx->acceptor_enc = context_v2_alloc_cipher(ctx, 422 ctx->gk5e->encrypt_name, 423 ctx->acceptor_seal); 424 if (ctx->acceptor_enc == NULL) 425 goto out_free_initiator_enc; 426 427 /* initiator sign checksum */ 428 set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 429 keyout.data = ctx->initiator_sign; 430 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 431 if (err) { 432 dprintk("%s: Error %d deriving initiator_sign key\n", 433 __func__, err); 434 goto out_free_acceptor_enc; 435 } 436 437 /* acceptor sign checksum */ 438 set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 439 keyout.data = ctx->acceptor_sign; 440 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 441 if (err) { 442 dprintk("%s: Error %d deriving acceptor_sign key\n", 443 __func__, err); 444 goto out_free_acceptor_enc; 445 } 446 447 /* initiator seal integrity */ 448 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 449 keyout.data = ctx->initiator_integ; 450 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 451 if (err) { 452 dprintk("%s: Error %d deriving initiator_integ key\n", 453 __func__, err); 454 goto out_free_acceptor_enc; 455 } 456 457 /* acceptor seal integrity */ 458 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 459 keyout.data = ctx->acceptor_integ; 460 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 461 if (err) { 462 dprintk("%s: Error %d deriving acceptor_integ key\n", 463 __func__, err); 464 goto out_free_acceptor_enc; 465 } 466 467 switch (ctx->enctype) { 468 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 469 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 470 ctx->initiator_enc_aux = 471 context_v2_alloc_cipher(ctx, "cbc(aes)", 472 ctx->initiator_seal); 473 if (ctx->initiator_enc_aux == NULL) 474 goto out_free_acceptor_enc; 475 ctx->acceptor_enc_aux = 476 context_v2_alloc_cipher(ctx, "cbc(aes)", 477 ctx->acceptor_seal); 478 if (ctx->acceptor_enc_aux == NULL) { 479 crypto_free_sync_skcipher(ctx->initiator_enc_aux); 480 goto out_free_acceptor_enc; 481 } 482 } 483 484 return 0; 485 486 out_free_acceptor_enc: 487 crypto_free_sync_skcipher(ctx->acceptor_enc); 488 out_free_initiator_enc: 489 crypto_free_sync_skcipher(ctx->initiator_enc); 490 out_err: 491 return -EINVAL; 492 } 493 494 static int 495 gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, 496 gfp_t gfp_mask) 497 { 498 u64 seq_send64; 499 int keylen; 500 u32 time32; 501 502 p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); 503 if (IS_ERR(p)) 504 goto out_err; 505 ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR; 506 507 p = simple_get_bytes(p, end, &time32, sizeof(time32)); 508 if (IS_ERR(p)) 509 goto out_err; 510 /* unsigned 32-bit time overflows in year 2106 */ 511 ctx->endtime = (time64_t)time32; 512 p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64)); 513 if (IS_ERR(p)) 514 goto out_err; 515 atomic64_set(&ctx->seq_send64, seq_send64); 516 /* set seq_send for use by "older" enctypes */ 517 atomic_set(&ctx->seq_send, seq_send64); 518 if (seq_send64 != atomic_read(&ctx->seq_send)) { 519 dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__, 520 seq_send64, atomic_read(&ctx->seq_send)); 521 p = ERR_PTR(-EINVAL); 522 goto out_err; 523 } 524 p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); 525 if (IS_ERR(p)) 526 goto out_err; 527 /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */ 528 if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1) 529 ctx->enctype = ENCTYPE_DES3_CBC_RAW; 530 ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); 531 if (ctx->gk5e == NULL) { 532 dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n", 533 ctx->enctype); 534 p = ERR_PTR(-EINVAL); 535 goto out_err; 536 } 537 keylen = ctx->gk5e->keylength; 538 539 p = simple_get_bytes(p, end, ctx->Ksess, keylen); 540 if (IS_ERR(p)) 541 goto out_err; 542 543 if (p != end) { 544 p = ERR_PTR(-EINVAL); 545 goto out_err; 546 } 547 548 ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data, 549 gss_kerberos_mech.gm_oid.len, gfp_mask); 550 if (unlikely(ctx->mech_used.data == NULL)) { 551 p = ERR_PTR(-ENOMEM); 552 goto out_err; 553 } 554 ctx->mech_used.len = gss_kerberos_mech.gm_oid.len; 555 556 switch (ctx->enctype) { 557 case ENCTYPE_DES3_CBC_RAW: 558 return context_derive_keys_des3(ctx, gfp_mask); 559 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 560 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 561 return context_derive_keys_new(ctx, gfp_mask); 562 default: 563 return -EINVAL; 564 } 565 566 out_err: 567 return PTR_ERR(p); 568 } 569 570 static int 571 gss_import_sec_context_kerberos(const void *p, size_t len, 572 struct gss_ctx *ctx_id, 573 time64_t *endtime, 574 gfp_t gfp_mask) 575 { 576 const void *end = (const void *)((const char *)p + len); 577 struct krb5_ctx *ctx; 578 int ret; 579 580 ctx = kzalloc(sizeof(*ctx), gfp_mask); 581 if (ctx == NULL) 582 return -ENOMEM; 583 584 if (len == 85) 585 ret = gss_import_v1_context(p, end, ctx); 586 else 587 ret = gss_import_v2_context(p, end, ctx, gfp_mask); 588 589 if (ret == 0) { 590 ctx_id->internal_ctx_id = ctx; 591 if (endtime) 592 *endtime = ctx->endtime; 593 } else 594 kfree(ctx); 595 596 dprintk("RPC: %s: returning %d\n", __func__, ret); 597 return ret; 598 } 599 600 static void 601 gss_delete_sec_context_kerberos(void *internal_ctx) { 602 struct krb5_ctx *kctx = internal_ctx; 603 604 crypto_free_sync_skcipher(kctx->seq); 605 crypto_free_sync_skcipher(kctx->enc); 606 crypto_free_sync_skcipher(kctx->acceptor_enc); 607 crypto_free_sync_skcipher(kctx->initiator_enc); 608 crypto_free_sync_skcipher(kctx->acceptor_enc_aux); 609 crypto_free_sync_skcipher(kctx->initiator_enc_aux); 610 kfree(kctx->mech_used.data); 611 kfree(kctx); 612 } 613 614 static const struct gss_api_ops gss_kerberos_ops = { 615 .gss_import_sec_context = gss_import_sec_context_kerberos, 616 .gss_get_mic = gss_get_mic_kerberos, 617 .gss_verify_mic = gss_verify_mic_kerberos, 618 .gss_wrap = gss_wrap_kerberos, 619 .gss_unwrap = gss_unwrap_kerberos, 620 .gss_delete_sec_context = gss_delete_sec_context_kerberos, 621 }; 622 623 static struct pf_desc gss_kerberos_pfs[] = { 624 [0] = { 625 .pseudoflavor = RPC_AUTH_GSS_KRB5, 626 .qop = GSS_C_QOP_DEFAULT, 627 .service = RPC_GSS_SVC_NONE, 628 .name = "krb5", 629 }, 630 [1] = { 631 .pseudoflavor = RPC_AUTH_GSS_KRB5I, 632 .qop = GSS_C_QOP_DEFAULT, 633 .service = RPC_GSS_SVC_INTEGRITY, 634 .name = "krb5i", 635 .datatouch = true, 636 }, 637 [2] = { 638 .pseudoflavor = RPC_AUTH_GSS_KRB5P, 639 .qop = GSS_C_QOP_DEFAULT, 640 .service = RPC_GSS_SVC_PRIVACY, 641 .name = "krb5p", 642 .datatouch = true, 643 }, 644 }; 645 646 MODULE_ALIAS("rpc-auth-gss-krb5"); 647 MODULE_ALIAS("rpc-auth-gss-krb5i"); 648 MODULE_ALIAS("rpc-auth-gss-krb5p"); 649 MODULE_ALIAS("rpc-auth-gss-390003"); 650 MODULE_ALIAS("rpc-auth-gss-390004"); 651 MODULE_ALIAS("rpc-auth-gss-390005"); 652 MODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2"); 653 654 static struct gss_api_mech gss_kerberos_mech = { 655 .gm_name = "krb5", 656 .gm_owner = THIS_MODULE, 657 .gm_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }, 658 .gm_ops = &gss_kerberos_ops, 659 .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), 660 .gm_pfs = gss_kerberos_pfs, 661 .gm_upcall_enctypes = KRB5_SUPPORTED_ENCTYPES, 662 }; 663 664 static int __init init_kerberos_module(void) 665 { 666 int status; 667 668 status = gss_mech_register(&gss_kerberos_mech); 669 if (status) 670 printk("Failed to register kerberos gss mechanism!\n"); 671 return status; 672 } 673 674 static void __exit cleanup_kerberos_module(void) 675 { 676 gss_mech_unregister(&gss_kerberos_mech); 677 } 678 679 MODULE_LICENSE("GPL"); 680 module_init(init_kerberos_module); 681 module_exit(cleanup_kerberos_module); 682