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_sync_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_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 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_sync_skcipher_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_sync_skcipher(*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 u32 seq_send; 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, &seq_send, sizeof(seq_send)); 320 if (IS_ERR(p)) 321 goto out_err; 322 atomic_set(&ctx->seq_send, seq_send); 323 p = simple_get_netobj(p, end, &ctx->mech_used); 324 if (IS_ERR(p)) 325 goto out_err; 326 p = get_key(p, end, ctx, &ctx->enc); 327 if (IS_ERR(p)) 328 goto out_err_free_mech; 329 p = get_key(p, end, ctx, &ctx->seq); 330 if (IS_ERR(p)) 331 goto out_err_free_key1; 332 if (p != end) { 333 p = ERR_PTR(-EFAULT); 334 goto out_err_free_key2; 335 } 336 337 return 0; 338 339 out_err_free_key2: 340 crypto_free_sync_skcipher(ctx->seq); 341 out_err_free_key1: 342 crypto_free_sync_skcipher(ctx->enc); 343 out_err_free_mech: 344 kfree(ctx->mech_used.data); 345 out_err: 346 return PTR_ERR(p); 347 } 348 349 static struct crypto_sync_skcipher * 350 context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) 351 { 352 struct crypto_sync_skcipher *cp; 353 354 cp = crypto_alloc_sync_skcipher(cname, 0, 0); 355 if (IS_ERR(cp)) { 356 dprintk("gss_kerberos_mech: unable to initialize " 357 "crypto algorithm %s\n", cname); 358 return NULL; 359 } 360 if (crypto_sync_skcipher_setkey(cp, key, ctx->gk5e->keylength)) { 361 dprintk("gss_kerberos_mech: error setting key for " 362 "crypto algorithm %s\n", cname); 363 crypto_free_sync_skcipher(cp); 364 return NULL; 365 } 366 return cp; 367 } 368 369 static inline void 370 set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed) 371 { 372 cdata[0] = (usage>>24)&0xff; 373 cdata[1] = (usage>>16)&0xff; 374 cdata[2] = (usage>>8)&0xff; 375 cdata[3] = usage&0xff; 376 cdata[4] = seed; 377 } 378 379 static int 380 context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask) 381 { 382 struct xdr_netobj c, keyin, keyout; 383 u8 cdata[GSS_KRB5_K5CLENGTH]; 384 u32 err; 385 386 c.len = GSS_KRB5_K5CLENGTH; 387 c.data = cdata; 388 389 keyin.data = ctx->Ksess; 390 keyin.len = ctx->gk5e->keylength; 391 keyout.len = ctx->gk5e->keylength; 392 393 /* seq uses the raw key */ 394 ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, 395 ctx->Ksess); 396 if (ctx->seq == NULL) 397 goto out_err; 398 399 ctx->enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name, 400 ctx->Ksess); 401 if (ctx->enc == NULL) 402 goto out_free_seq; 403 404 /* derive cksum */ 405 set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM); 406 keyout.data = ctx->cksum; 407 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 408 if (err) { 409 dprintk("%s: Error %d deriving cksum key\n", 410 __func__, err); 411 goto out_free_enc; 412 } 413 414 return 0; 415 416 out_free_enc: 417 crypto_free_sync_skcipher(ctx->enc); 418 out_free_seq: 419 crypto_free_sync_skcipher(ctx->seq); 420 out_err: 421 return -EINVAL; 422 } 423 424 /* 425 * Note that RC4 depends on deriving keys using the sequence 426 * number or the checksum of a token. Therefore, the final keys 427 * cannot be calculated until the token is being constructed! 428 */ 429 static int 430 context_derive_keys_rc4(struct krb5_ctx *ctx) 431 { 432 struct crypto_shash *hmac; 433 char sigkeyconstant[] = "signaturekey"; 434 int slen = strlen(sigkeyconstant) + 1; /* include null terminator */ 435 struct shash_desc *desc; 436 int err; 437 438 dprintk("RPC: %s: entered\n", __func__); 439 /* 440 * derive cksum (aka Ksign) key 441 */ 442 hmac = crypto_alloc_shash(ctx->gk5e->cksum_name, 0, 0); 443 if (IS_ERR(hmac)) { 444 dprintk("%s: error %ld allocating hash '%s'\n", 445 __func__, PTR_ERR(hmac), ctx->gk5e->cksum_name); 446 err = PTR_ERR(hmac); 447 goto out_err; 448 } 449 450 err = crypto_shash_setkey(hmac, ctx->Ksess, ctx->gk5e->keylength); 451 if (err) 452 goto out_err_free_hmac; 453 454 455 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), GFP_NOFS); 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_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 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_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); 480 if (IS_ERR(ctx->seq)) { 481 crypto_free_sync_skcipher(ctx->enc); 482 err = PTR_ERR(ctx->seq); 483 goto out_err_free_hmac; 484 } 485 486 dprintk("RPC: %s: returning success\n", __func__); 487 488 err = 0; 489 490 out_err_free_hmac: 491 crypto_free_shash(hmac); 492 out_err: 493 dprintk("RPC: %s: returning %d\n", __func__, err); 494 return err; 495 } 496 497 static int 498 context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask) 499 { 500 struct xdr_netobj c, keyin, keyout; 501 u8 cdata[GSS_KRB5_K5CLENGTH]; 502 u32 err; 503 504 c.len = GSS_KRB5_K5CLENGTH; 505 c.data = cdata; 506 507 keyin.data = ctx->Ksess; 508 keyin.len = ctx->gk5e->keylength; 509 keyout.len = ctx->gk5e->keylength; 510 511 /* initiator seal encryption */ 512 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 513 keyout.data = ctx->initiator_seal; 514 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 515 if (err) { 516 dprintk("%s: Error %d deriving initiator_seal key\n", 517 __func__, err); 518 goto out_err; 519 } 520 ctx->initiator_enc = context_v2_alloc_cipher(ctx, 521 ctx->gk5e->encrypt_name, 522 ctx->initiator_seal); 523 if (ctx->initiator_enc == NULL) 524 goto out_err; 525 526 /* acceptor seal encryption */ 527 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION); 528 keyout.data = ctx->acceptor_seal; 529 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 530 if (err) { 531 dprintk("%s: Error %d deriving acceptor_seal key\n", 532 __func__, err); 533 goto out_free_initiator_enc; 534 } 535 ctx->acceptor_enc = context_v2_alloc_cipher(ctx, 536 ctx->gk5e->encrypt_name, 537 ctx->acceptor_seal); 538 if (ctx->acceptor_enc == NULL) 539 goto out_free_initiator_enc; 540 541 /* initiator sign checksum */ 542 set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 543 keyout.data = ctx->initiator_sign; 544 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 545 if (err) { 546 dprintk("%s: Error %d deriving initiator_sign key\n", 547 __func__, err); 548 goto out_free_acceptor_enc; 549 } 550 551 /* acceptor sign checksum */ 552 set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM); 553 keyout.data = ctx->acceptor_sign; 554 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 555 if (err) { 556 dprintk("%s: Error %d deriving acceptor_sign key\n", 557 __func__, err); 558 goto out_free_acceptor_enc; 559 } 560 561 /* initiator seal integrity */ 562 set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 563 keyout.data = ctx->initiator_integ; 564 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 565 if (err) { 566 dprintk("%s: Error %d deriving initiator_integ key\n", 567 __func__, err); 568 goto out_free_acceptor_enc; 569 } 570 571 /* acceptor seal integrity */ 572 set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY); 573 keyout.data = ctx->acceptor_integ; 574 err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask); 575 if (err) { 576 dprintk("%s: Error %d deriving acceptor_integ key\n", 577 __func__, err); 578 goto out_free_acceptor_enc; 579 } 580 581 switch (ctx->enctype) { 582 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 583 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 584 ctx->initiator_enc_aux = 585 context_v2_alloc_cipher(ctx, "cbc(aes)", 586 ctx->initiator_seal); 587 if (ctx->initiator_enc_aux == NULL) 588 goto out_free_acceptor_enc; 589 ctx->acceptor_enc_aux = 590 context_v2_alloc_cipher(ctx, "cbc(aes)", 591 ctx->acceptor_seal); 592 if (ctx->acceptor_enc_aux == NULL) { 593 crypto_free_sync_skcipher(ctx->initiator_enc_aux); 594 goto out_free_acceptor_enc; 595 } 596 } 597 598 return 0; 599 600 out_free_acceptor_enc: 601 crypto_free_sync_skcipher(ctx->acceptor_enc); 602 out_free_initiator_enc: 603 crypto_free_sync_skcipher(ctx->initiator_enc); 604 out_err: 605 return -EINVAL; 606 } 607 608 static int 609 gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, 610 gfp_t gfp_mask) 611 { 612 u64 seq_send64; 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, &seq_send64, sizeof(seq_send64)); 624 if (IS_ERR(p)) 625 goto out_err; 626 atomic64_set(&ctx->seq_send64, seq_send64); 627 /* set seq_send for use by "older" enctypes */ 628 atomic_set(&ctx->seq_send, seq_send64); 629 if (seq_send64 != atomic_read(&ctx->seq_send)) { 630 dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__, 631 seq_send64, atomic_read(&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_sync_skcipher(kctx->seq); 718 crypto_free_sync_skcipher(kctx->enc); 719 crypto_free_sync_skcipher(kctx->acceptor_enc); 720 crypto_free_sync_skcipher(kctx->initiator_enc); 721 crypto_free_sync_skcipher(kctx->acceptor_enc_aux); 722 crypto_free_sync_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