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