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