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