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