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