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 desc->flags = 0; 442 443 err = crypto_shash_digest(desc, sigkeyconstant, slen, ctx->cksum); 444 kzfree(desc); 445 if (err) 446 goto out_err_free_hmac; 447 /* 448 * allocate hash, and skciphers for data and seqnum encryption 449 */ 450 ctx->enc = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 451 if (IS_ERR(ctx->enc)) { 452 err = PTR_ERR(ctx->enc); 453 goto out_err_free_hmac; 454 } 455 456 ctx->seq = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 457 if (IS_ERR(ctx->seq)) { 458 crypto_free_sync_skcipher(ctx->enc); 459 err = PTR_ERR(ctx->seq); 460 goto out_err_free_hmac; 461 } 462 463 dprintk("RPC: %s: returning success\n", __func__); 464 465 err = 0; 466 467 out_err_free_hmac: 468 crypto_free_shash(hmac); 469 out_err: 470 dprintk("RPC: %s: returning %d\n", __func__, err); 471 return err; 472 } 473 474 static int 475 context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) 476 { 477 struct xdr_netobj c, keyin, keyout; 478 u8 cdata[GSS_KRB5_K5CLENGTH]; 479 u32 err; 480 481 c.len = GSS_KRB5_K5CLENGTH; 482 c.data = cdata; 483 484 keyin.data = ctx->Ksess; 485 keyin.len = ctx->gk5e->keylength; 486 keyout.len = ctx->gk5e->keylength; 487 488 /* initiator seal encryption */ 489 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 490 keyout.data = ctx->initiator_seal; 491 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 492 if (err) { 493 dprintk("%s: Error %d deriving initiator_seal key\n", 494 __func__, err); 495 goto out_err; 496 } 497 ctx->initiator_enc = context_v2_alloc_cipher(ctx, 498 ctx->gk5e->encrypt_name, 499 ctx->initiator_seal); 500 if (ctx->initiator_enc == NULL) 501 goto out_err; 502 503 /* acceptor seal encryption */ 504 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 505 keyout.data = ctx->acceptor_seal; 506 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 507 if (err) { 508 dprintk("%s: Error %d deriving acceptor_seal key\n", 509 __func__, err); 510 goto out_free_initiator_enc; 511 } 512 ctx->acceptor_enc = context_v2_alloc_cipher(ctx, 513 ctx->gk5e->encrypt_name, 514 ctx->acceptor_seal); 515 if (ctx->acceptor_enc == NULL) 516 goto out_free_initiator_enc; 517 518 /* initiator sign checksum */ 519 set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 520 keyout.data = ctx->initiator_sign; 521 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 522 if (err) { 523 dprintk("%s: Error %d deriving initiator_sign key\n", 524 __func__, err); 525 goto out_free_acceptor_enc; 526 } 527 528 /* acceptor sign checksum */ 529 set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 530 keyout.data = ctx->acceptor_sign; 531 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 532 if (err) { 533 dprintk("%s: Error %d deriving acceptor_sign key\n", 534 __func__, err); 535 goto out_free_acceptor_enc; 536 } 537 538 /* initiator seal integrity */ 539 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 540 keyout.data = ctx->initiator_integ; 541 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 542 if (err) { 543 dprintk("%s: Error %d deriving initiator_integ key\n", 544 __func__, err); 545 goto out_free_acceptor_enc; 546 } 547 548 /* acceptor seal integrity */ 549 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 550 keyout.data = ctx->acceptor_integ; 551 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 552 if (err) { 553 dprintk("%s: Error %d deriving acceptor_integ key\n", 554 __func__, err); 555 goto out_free_acceptor_enc; 556 } 557 558 switch (ctx->enctype) { 559 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 560 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 561 ctx->initiator_enc_aux = 562 context_v2_alloc_cipher(ctx, "cbc(aes)", 563 ctx->initiator_seal); 564 if (ctx->initiator_enc_aux == NULL) 565 goto out_free_acceptor_enc; 566 ctx->acceptor_enc_aux = 567 context_v2_alloc_cipher(ctx, "cbc(aes)", 568 ctx->acceptor_seal); 569 if (ctx->acceptor_enc_aux == NULL) { 570 crypto_free_sync_skcipher(ctx->initiator_enc_aux); 571 goto out_free_acceptor_enc; 572 } 573 } 574 575 return 0; 576 577 out_free_acceptor_enc: 578 crypto_free_sync_skcipher(ctx->acceptor_enc); 579 out_free_initiator_enc: 580 crypto_free_sync_skcipher(ctx->initiator_enc); 581 out_err: 582 return -EINVAL; 583 } 584 585 static int 586 gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, 587 gfp_t gfp_mask) 588 { 589 u64 seq_send64; 590 int keylen; 591 592 p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); 593 if (IS_ERR(p)) 594 goto out_err; 595 ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR; 596 597 p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); 598 if (IS_ERR(p)) 599 goto out_err; 600 p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64)); 601 if (IS_ERR(p)) 602 goto out_err; 603 atomic64_set(&ctx->seq_send64, seq_send64); 604 /* set seq_send for use by "older" enctypes */ 605 atomic_set(&ctx->seq_send, seq_send64); 606 if (seq_send64 != atomic_read(&ctx->seq_send)) { 607 dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__, 608 seq_send64, atomic_read(&ctx->seq_send)); 609 p = ERR_PTR(-EINVAL); 610 goto out_err; 611 } 612 p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); 613 if (IS_ERR(p)) 614 goto out_err; 615 /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */ 616 if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1) 617 ctx->enctype = ENCTYPE_DES3_CBC_RAW; 618 ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); 619 if (ctx->gk5e == NULL) { 620 dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n", 621 ctx->enctype); 622 p = ERR_PTR(-EINVAL); 623 goto out_err; 624 } 625 keylen = ctx->gk5e->keylength; 626 627 p = simple_get_bytes(p, end, ctx->Ksess, keylen); 628 if (IS_ERR(p)) 629 goto out_err; 630 631 if (p != end) { 632 p = ERR_PTR(-EINVAL); 633 goto out_err; 634 } 635 636 ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data, 637 gss_kerberos_mech.gm_oid.len, gfp_mask); 638 if (unlikely(ctx->mech_used.data == NULL)) { 639 p = ERR_PTR(-ENOMEM); 640 goto out_err; 641 } 642 ctx->mech_used.len = gss_kerberos_mech.gm_oid.len; 643 644 switch (ctx->enctype) { 645 case ENCTYPE_DES3_CBC_RAW: 646 return context_derive_keys_des3(ctx, gfp_mask); 647 case ENCTYPE_ARCFOUR_HMAC: 648 return context_derive_keys_rc4(ctx); 649 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 650 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 651 return context_derive_keys_new(ctx, gfp_mask); 652 default: 653 return -EINVAL; 654 } 655 656 out_err: 657 return PTR_ERR(p); 658 } 659 660 static int 661 gss_import_sec_context_kerberos(const void *p, size_t len, 662 struct gss_ctx *ctx_id, 663 time_t *endtime, 664 gfp_t gfp_mask) 665 { 666 const void *end = (const void *)((const char *)p + len); 667 struct krb5_ctx *ctx; 668 int ret; 669 670 ctx = kzalloc(sizeof(*ctx), gfp_mask); 671 if (ctx == NULL) 672 return -ENOMEM; 673 674 if (len == 85) 675 ret = gss_import_v1_context(p, end, ctx); 676 else 677 ret = gss_import_v2_context(p, end, ctx, gfp_mask); 678 679 if (ret == 0) { 680 ctx_id->internal_ctx_id = ctx; 681 if (endtime) 682 *endtime = ctx->endtime; 683 } else 684 kfree(ctx); 685 686 dprintk("RPC: %s: returning %d\n", __func__, ret); 687 return ret; 688 } 689 690 static void 691 gss_delete_sec_context_kerberos(void *internal_ctx) { 692 struct krb5_ctx *kctx = internal_ctx; 693 694 crypto_free_sync_skcipher(kctx->seq); 695 crypto_free_sync_skcipher(kctx->enc); 696 crypto_free_sync_skcipher(kctx->acceptor_enc); 697 crypto_free_sync_skcipher(kctx->initiator_enc); 698 crypto_free_sync_skcipher(kctx->acceptor_enc_aux); 699 crypto_free_sync_skcipher(kctx->initiator_enc_aux); 700 kfree(kctx->mech_used.data); 701 kfree(kctx); 702 } 703 704 static const struct gss_api_ops gss_kerberos_ops = { 705 .gss_import_sec_context = gss_import_sec_context_kerberos, 706 .gss_get_mic = gss_get_mic_kerberos, 707 .gss_verify_mic = gss_verify_mic_kerberos, 708 .gss_wrap = gss_wrap_kerberos, 709 .gss_unwrap = gss_unwrap_kerberos, 710 .gss_delete_sec_context = gss_delete_sec_context_kerberos, 711 }; 712 713 static struct pf_desc gss_kerberos_pfs[] = { 714 [0] = { 715 .pseudoflavor = RPC_AUTH_GSS_KRB5, 716 .qop = GSS_C_QOP_DEFAULT, 717 .service = RPC_GSS_SVC_NONE, 718 .name = "krb5", 719 }, 720 [1] = { 721 .pseudoflavor = RPC_AUTH_GSS_KRB5I, 722 .qop = GSS_C_QOP_DEFAULT, 723 .service = RPC_GSS_SVC_INTEGRITY, 724 .name = "krb5i", 725 .datatouch = true, 726 }, 727 [2] = { 728 .pseudoflavor = RPC_AUTH_GSS_KRB5P, 729 .qop = GSS_C_QOP_DEFAULT, 730 .service = RPC_GSS_SVC_PRIVACY, 731 .name = "krb5p", 732 .datatouch = true, 733 }, 734 }; 735 736 MODULE_ALIAS("rpc-auth-gss-krb5"); 737 MODULE_ALIAS("rpc-auth-gss-krb5i"); 738 MODULE_ALIAS("rpc-auth-gss-krb5p"); 739 MODULE_ALIAS("rpc-auth-gss-390003"); 740 MODULE_ALIAS("rpc-auth-gss-390004"); 741 MODULE_ALIAS("rpc-auth-gss-390005"); 742 MODULE_ALIAS("rpc-auth-gss-1.2.840.113554.1.2.2"); 743 744 static struct gss_api_mech gss_kerberos_mech = { 745 .gm_name = "krb5", 746 .gm_owner = THIS_MODULE, 747 .gm_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }, 748 .gm_ops = &gss_kerberos_ops, 749 .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), 750 .gm_pfs = gss_kerberos_pfs, 751 .gm_upcall_enctypes = KRB5_SUPPORTED_ENCTYPES, 752 }; 753 754 static int __init init_kerberos_module(void) 755 { 756 int status; 757 758 status = gss_mech_register(&gss_kerberos_mech); 759 if (status) 760 printk("Failed to register kerberos gss mechanism!\n"); 761 return status; 762 } 763 764 static void __exit cleanup_kerberos_module(void) 765 { 766 gss_mech_unregister(&gss_kerberos_mech); 767 } 768 769 MODULE_LICENSE("GPL"); 770 module_init(init_kerberos_module); 771 module_exit(cleanup_kerberos_module); 772