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