| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: BSD-3-Clause |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/net/sunrpc/gss_krb5_mech.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Andy Adamson <andros@umich.edu> |
|---|
| 8 | 9 | * 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 | 10 | */ |
|---|
| 36 | 11 | |
|---|
| 37 | 12 | #include <crypto/hash.h> |
|---|
| .. | .. |
|---|
| 55 | 30 | static struct gss_api_mech gss_kerberos_mech; /* forward declaration */ |
|---|
| 56 | 31 | |
|---|
| 57 | 32 | static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = { |
|---|
| 33 | +#ifndef CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES |
|---|
| 58 | 34 | /* |
|---|
| 59 | 35 | * DES (All DES enctypes are mapped to the same gss functionality) |
|---|
| 60 | 36 | */ |
|---|
| .. | .. |
|---|
| 76 | 52 | .cksumlength = 8, |
|---|
| 77 | 53 | .keyed_cksum = 0, |
|---|
| 78 | 54 | }, |
|---|
| 79 | | - /* |
|---|
| 80 | | - * RC4-HMAC |
|---|
| 81 | | - */ |
|---|
| 82 | | - { |
|---|
| 83 | | - .etype = ENCTYPE_ARCFOUR_HMAC, |
|---|
| 84 | | - .ctype = CKSUMTYPE_HMAC_MD5_ARCFOUR, |
|---|
| 85 | | - .name = "rc4-hmac", |
|---|
| 86 | | - .encrypt_name = "ecb(arc4)", |
|---|
| 87 | | - .cksum_name = "hmac(md5)", |
|---|
| 88 | | - .encrypt = krb5_encrypt, |
|---|
| 89 | | - .decrypt = krb5_decrypt, |
|---|
| 90 | | - .mk_key = NULL, |
|---|
| 91 | | - .signalg = SGN_ALG_HMAC_MD5, |
|---|
| 92 | | - .sealalg = SEAL_ALG_MICROSOFT_RC4, |
|---|
| 93 | | - .keybytes = 16, |
|---|
| 94 | | - .keylength = 16, |
|---|
| 95 | | - .blocksize = 1, |
|---|
| 96 | | - .conflen = 8, |
|---|
| 97 | | - .cksumlength = 8, |
|---|
| 98 | | - .keyed_cksum = 1, |
|---|
| 99 | | - }, |
|---|
| 55 | +#endif /* CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES */ |
|---|
| 100 | 56 | /* |
|---|
| 101 | 57 | * 3DES |
|---|
| 102 | 58 | */ |
|---|
| .. | .. |
|---|
| 191 | 147 | |
|---|
| 192 | 148 | static inline const void * |
|---|
| 193 | 149 | get_key(const void *p, const void *end, |
|---|
| 194 | | - struct krb5_ctx *ctx, struct crypto_skcipher **res) |
|---|
| 150 | + struct krb5_ctx *ctx, struct crypto_sync_skcipher **res) |
|---|
| 195 | 151 | { |
|---|
| 196 | 152 | struct xdr_netobj key; |
|---|
| 197 | 153 | int alg; |
|---|
| .. | .. |
|---|
| 219 | 175 | if (IS_ERR(p)) |
|---|
| 220 | 176 | goto out_err; |
|---|
| 221 | 177 | |
|---|
| 222 | | - *res = crypto_alloc_skcipher(ctx->gk5e->encrypt_name, 0, |
|---|
| 223 | | - CRYPTO_ALG_ASYNC); |
|---|
| 178 | + *res = crypto_alloc_sync_skcipher(ctx->gk5e->encrypt_name, 0, 0); |
|---|
| 224 | 179 | if (IS_ERR(*res)) { |
|---|
| 225 | 180 | printk(KERN_WARNING "gss_kerberos_mech: unable to initialize " |
|---|
| 226 | 181 | "crypto algorithm %s\n", ctx->gk5e->encrypt_name); |
|---|
| 227 | 182 | *res = NULL; |
|---|
| 228 | 183 | goto out_err_free_key; |
|---|
| 229 | 184 | } |
|---|
| 230 | | - if (crypto_skcipher_setkey(*res, key.data, key.len)) { |
|---|
| 185 | + if (crypto_sync_skcipher_setkey(*res, key.data, key.len)) { |
|---|
| 231 | 186 | printk(KERN_WARNING "gss_kerberos_mech: error setting key for " |
|---|
| 232 | 187 | "crypto algorithm %s\n", ctx->gk5e->encrypt_name); |
|---|
| 233 | 188 | goto out_err_free_tfm; |
|---|
| .. | .. |
|---|
| 237 | 192 | return p; |
|---|
| 238 | 193 | |
|---|
| 239 | 194 | out_err_free_tfm: |
|---|
| 240 | | - crypto_free_skcipher(*res); |
|---|
| 195 | + crypto_free_sync_skcipher(*res); |
|---|
| 241 | 196 | out_err_free_key: |
|---|
| 242 | 197 | kfree(key.data); |
|---|
| 243 | 198 | p = ERR_PTR(-EINVAL); |
|---|
| .. | .. |
|---|
| 248 | 203 | static int |
|---|
| 249 | 204 | gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) |
|---|
| 250 | 205 | { |
|---|
| 206 | + u32 seq_send; |
|---|
| 251 | 207 | int tmp; |
|---|
| 208 | + u32 time32; |
|---|
| 252 | 209 | |
|---|
| 253 | 210 | p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); |
|---|
| 254 | 211 | if (IS_ERR(p)) |
|---|
| .. | .. |
|---|
| 286 | 243 | p = ERR_PTR(-ENOSYS); |
|---|
| 287 | 244 | goto out_err; |
|---|
| 288 | 245 | } |
|---|
| 289 | | - p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); |
|---|
| 246 | + p = simple_get_bytes(p, end, &time32, sizeof(time32)); |
|---|
| 290 | 247 | if (IS_ERR(p)) |
|---|
| 291 | 248 | goto out_err; |
|---|
| 292 | | - p = simple_get_bytes(p, end, &ctx->seq_send, sizeof(ctx->seq_send)); |
|---|
| 249 | + /* unsigned 32-bit time overflows in year 2106 */ |
|---|
| 250 | + ctx->endtime = (time64_t)time32; |
|---|
| 251 | + p = simple_get_bytes(p, end, &seq_send, sizeof(seq_send)); |
|---|
| 293 | 252 | if (IS_ERR(p)) |
|---|
| 294 | 253 | goto out_err; |
|---|
| 254 | + atomic_set(&ctx->seq_send, seq_send); |
|---|
| 295 | 255 | p = simple_get_netobj(p, end, &ctx->mech_used); |
|---|
| 296 | 256 | if (IS_ERR(p)) |
|---|
| 297 | 257 | goto out_err; |
|---|
| .. | .. |
|---|
| 309 | 269 | return 0; |
|---|
| 310 | 270 | |
|---|
| 311 | 271 | out_err_free_key2: |
|---|
| 312 | | - crypto_free_skcipher(ctx->seq); |
|---|
| 272 | + crypto_free_sync_skcipher(ctx->seq); |
|---|
| 313 | 273 | out_err_free_key1: |
|---|
| 314 | | - crypto_free_skcipher(ctx->enc); |
|---|
| 274 | + crypto_free_sync_skcipher(ctx->enc); |
|---|
| 315 | 275 | out_err_free_mech: |
|---|
| 316 | 276 | kfree(ctx->mech_used.data); |
|---|
| 317 | 277 | out_err: |
|---|
| 318 | 278 | return PTR_ERR(p); |
|---|
| 319 | 279 | } |
|---|
| 320 | 280 | |
|---|
| 321 | | -static struct crypto_skcipher * |
|---|
| 281 | +static struct crypto_sync_skcipher * |
|---|
| 322 | 282 | context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key) |
|---|
| 323 | 283 | { |
|---|
| 324 | | - struct crypto_skcipher *cp; |
|---|
| 284 | + struct crypto_sync_skcipher *cp; |
|---|
| 325 | 285 | |
|---|
| 326 | | - cp = crypto_alloc_skcipher(cname, 0, CRYPTO_ALG_ASYNC); |
|---|
| 286 | + cp = crypto_alloc_sync_skcipher(cname, 0, 0); |
|---|
| 327 | 287 | if (IS_ERR(cp)) { |
|---|
| 328 | 288 | dprintk("gss_kerberos_mech: unable to initialize " |
|---|
| 329 | 289 | "crypto algorithm %s\n", cname); |
|---|
| 330 | 290 | return NULL; |
|---|
| 331 | 291 | } |
|---|
| 332 | | - if (crypto_skcipher_setkey(cp, key, ctx->gk5e->keylength)) { |
|---|
| 292 | + if (crypto_sync_skcipher_setkey(cp, key, ctx->gk5e->keylength)) { |
|---|
| 333 | 293 | dprintk("gss_kerberos_mech: error setting key for " |
|---|
| 334 | 294 | "crypto algorithm %s\n", cname); |
|---|
| 335 | | - crypto_free_skcipher(cp); |
|---|
| 295 | + crypto_free_sync_skcipher(cp); |
|---|
| 336 | 296 | return NULL; |
|---|
| 337 | 297 | } |
|---|
| 338 | 298 | return cp; |
|---|
| .. | .. |
|---|
| 386 | 346 | return 0; |
|---|
| 387 | 347 | |
|---|
| 388 | 348 | out_free_enc: |
|---|
| 389 | | - crypto_free_skcipher(ctx->enc); |
|---|
| 349 | + crypto_free_sync_skcipher(ctx->enc); |
|---|
| 390 | 350 | out_free_seq: |
|---|
| 391 | | - crypto_free_skcipher(ctx->seq); |
|---|
| 351 | + crypto_free_sync_skcipher(ctx->seq); |
|---|
| 392 | 352 | out_err: |
|---|
| 393 | 353 | return -EINVAL; |
|---|
| 394 | | -} |
|---|
| 395 | | - |
|---|
| 396 | | -/* |
|---|
| 397 | | - * Note that RC4 depends on deriving keys using the sequence |
|---|
| 398 | | - * number or the checksum of a token. Therefore, the final keys |
|---|
| 399 | | - * cannot be calculated until the token is being constructed! |
|---|
| 400 | | - */ |
|---|
| 401 | | -static int |
|---|
| 402 | | -context_derive_keys_rc4(struct krb5_ctx *ctx) |
|---|
| 403 | | -{ |
|---|
| 404 | | - struct crypto_shash *hmac; |
|---|
| 405 | | - char sigkeyconstant[] = "signaturekey"; |
|---|
| 406 | | - int slen = strlen(sigkeyconstant) + 1; /* include null terminator */ |
|---|
| 407 | | - struct shash_desc *desc; |
|---|
| 408 | | - int err; |
|---|
| 409 | | - |
|---|
| 410 | | - dprintk("RPC: %s: entered\n", __func__); |
|---|
| 411 | | - /* |
|---|
| 412 | | - * derive cksum (aka Ksign) key |
|---|
| 413 | | - */ |
|---|
| 414 | | - hmac = crypto_alloc_shash(ctx->gk5e->cksum_name, 0, 0); |
|---|
| 415 | | - if (IS_ERR(hmac)) { |
|---|
| 416 | | - dprintk("%s: error %ld allocating hash '%s'\n", |
|---|
| 417 | | - __func__, PTR_ERR(hmac), ctx->gk5e->cksum_name); |
|---|
| 418 | | - err = PTR_ERR(hmac); |
|---|
| 419 | | - goto out_err; |
|---|
| 420 | | - } |
|---|
| 421 | | - |
|---|
| 422 | | - err = crypto_shash_setkey(hmac, ctx->Ksess, ctx->gk5e->keylength); |
|---|
| 423 | | - if (err) |
|---|
| 424 | | - goto out_err_free_hmac; |
|---|
| 425 | | - |
|---|
| 426 | | - |
|---|
| 427 | | - desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac), GFP_NOFS); |
|---|
| 428 | | - if (!desc) { |
|---|
| 429 | | - dprintk("%s: failed to allocate hash descriptor for '%s'\n", |
|---|
| 430 | | - __func__, ctx->gk5e->cksum_name); |
|---|
| 431 | | - err = -ENOMEM; |
|---|
| 432 | | - goto out_err_free_hmac; |
|---|
| 433 | | - } |
|---|
| 434 | | - |
|---|
| 435 | | - desc->tfm = hmac; |
|---|
| 436 | | - desc->flags = 0; |
|---|
| 437 | | - |
|---|
| 438 | | - err = crypto_shash_digest(desc, sigkeyconstant, slen, ctx->cksum); |
|---|
| 439 | | - kzfree(desc); |
|---|
| 440 | | - if (err) |
|---|
| 441 | | - goto out_err_free_hmac; |
|---|
| 442 | | - /* |
|---|
| 443 | | - * allocate hash, and skciphers for data and seqnum encryption |
|---|
| 444 | | - */ |
|---|
| 445 | | - ctx->enc = crypto_alloc_skcipher(ctx->gk5e->encrypt_name, 0, |
|---|
| 446 | | - CRYPTO_ALG_ASYNC); |
|---|
| 447 | | - if (IS_ERR(ctx->enc)) { |
|---|
| 448 | | - err = PTR_ERR(ctx->enc); |
|---|
| 449 | | - goto out_err_free_hmac; |
|---|
| 450 | | - } |
|---|
| 451 | | - |
|---|
| 452 | | - ctx->seq = crypto_alloc_skcipher(ctx->gk5e->encrypt_name, 0, |
|---|
| 453 | | - CRYPTO_ALG_ASYNC); |
|---|
| 454 | | - if (IS_ERR(ctx->seq)) { |
|---|
| 455 | | - crypto_free_skcipher(ctx->enc); |
|---|
| 456 | | - err = PTR_ERR(ctx->seq); |
|---|
| 457 | | - goto out_err_free_hmac; |
|---|
| 458 | | - } |
|---|
| 459 | | - |
|---|
| 460 | | - dprintk("RPC: %s: returning success\n", __func__); |
|---|
| 461 | | - |
|---|
| 462 | | - err = 0; |
|---|
| 463 | | - |
|---|
| 464 | | -out_err_free_hmac: |
|---|
| 465 | | - crypto_free_shash(hmac); |
|---|
| 466 | | -out_err: |
|---|
| 467 | | - dprintk("RPC: %s: returning %d\n", __func__, err); |
|---|
| 468 | | - return err; |
|---|
| 469 | 354 | } |
|---|
| 470 | 355 | |
|---|
| 471 | 356 | static int |
|---|
| .. | .. |
|---|
| 564 | 449 | context_v2_alloc_cipher(ctx, "cbc(aes)", |
|---|
| 565 | 450 | ctx->acceptor_seal); |
|---|
| 566 | 451 | if (ctx->acceptor_enc_aux == NULL) { |
|---|
| 567 | | - crypto_free_skcipher(ctx->initiator_enc_aux); |
|---|
| 452 | + crypto_free_sync_skcipher(ctx->initiator_enc_aux); |
|---|
| 568 | 453 | goto out_free_acceptor_enc; |
|---|
| 569 | 454 | } |
|---|
| 570 | 455 | } |
|---|
| .. | .. |
|---|
| 572 | 457 | return 0; |
|---|
| 573 | 458 | |
|---|
| 574 | 459 | out_free_acceptor_enc: |
|---|
| 575 | | - crypto_free_skcipher(ctx->acceptor_enc); |
|---|
| 460 | + crypto_free_sync_skcipher(ctx->acceptor_enc); |
|---|
| 576 | 461 | out_free_initiator_enc: |
|---|
| 577 | | - crypto_free_skcipher(ctx->initiator_enc); |
|---|
| 462 | + crypto_free_sync_skcipher(ctx->initiator_enc); |
|---|
| 578 | 463 | out_err: |
|---|
| 579 | 464 | return -EINVAL; |
|---|
| 580 | 465 | } |
|---|
| .. | .. |
|---|
| 583 | 468 | gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, |
|---|
| 584 | 469 | gfp_t gfp_mask) |
|---|
| 585 | 470 | { |
|---|
| 471 | + u64 seq_send64; |
|---|
| 586 | 472 | int keylen; |
|---|
| 473 | + u32 time32; |
|---|
| 587 | 474 | |
|---|
| 588 | 475 | p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); |
|---|
| 589 | 476 | if (IS_ERR(p)) |
|---|
| 590 | 477 | goto out_err; |
|---|
| 591 | 478 | ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR; |
|---|
| 592 | 479 | |
|---|
| 593 | | - p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); |
|---|
| 480 | + p = simple_get_bytes(p, end, &time32, sizeof(time32)); |
|---|
| 594 | 481 | if (IS_ERR(p)) |
|---|
| 595 | 482 | goto out_err; |
|---|
| 596 | | - p = simple_get_bytes(p, end, &ctx->seq_send64, sizeof(ctx->seq_send64)); |
|---|
| 483 | + /* unsigned 32-bit time overflows in year 2106 */ |
|---|
| 484 | + ctx->endtime = (time64_t)time32; |
|---|
| 485 | + p = simple_get_bytes(p, end, &seq_send64, sizeof(seq_send64)); |
|---|
| 597 | 486 | if (IS_ERR(p)) |
|---|
| 598 | 487 | goto out_err; |
|---|
| 488 | + atomic64_set(&ctx->seq_send64, seq_send64); |
|---|
| 599 | 489 | /* set seq_send for use by "older" enctypes */ |
|---|
| 600 | | - ctx->seq_send = ctx->seq_send64; |
|---|
| 601 | | - if (ctx->seq_send64 != ctx->seq_send) { |
|---|
| 602 | | - dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__, |
|---|
| 603 | | - (unsigned long)ctx->seq_send64, ctx->seq_send); |
|---|
| 490 | + atomic_set(&ctx->seq_send, seq_send64); |
|---|
| 491 | + if (seq_send64 != atomic_read(&ctx->seq_send)) { |
|---|
| 492 | + dprintk("%s: seq_send64 %llx, seq_send %x overflow?\n", __func__, |
|---|
| 493 | + seq_send64, atomic_read(&ctx->seq_send)); |
|---|
| 604 | 494 | p = ERR_PTR(-EINVAL); |
|---|
| 605 | 495 | goto out_err; |
|---|
| 606 | 496 | } |
|---|
| .. | .. |
|---|
| 639 | 529 | switch (ctx->enctype) { |
|---|
| 640 | 530 | case ENCTYPE_DES3_CBC_RAW: |
|---|
| 641 | 531 | return context_derive_keys_des3(ctx, gfp_mask); |
|---|
| 642 | | - case ENCTYPE_ARCFOUR_HMAC: |
|---|
| 643 | | - return context_derive_keys_rc4(ctx); |
|---|
| 644 | 532 | case ENCTYPE_AES128_CTS_HMAC_SHA1_96: |
|---|
| 645 | 533 | case ENCTYPE_AES256_CTS_HMAC_SHA1_96: |
|---|
| 646 | 534 | return context_derive_keys_new(ctx, gfp_mask); |
|---|
| .. | .. |
|---|
| 655 | 543 | static int |
|---|
| 656 | 544 | gss_import_sec_context_kerberos(const void *p, size_t len, |
|---|
| 657 | 545 | struct gss_ctx *ctx_id, |
|---|
| 658 | | - time_t *endtime, |
|---|
| 546 | + time64_t *endtime, |
|---|
| 659 | 547 | gfp_t gfp_mask) |
|---|
| 660 | 548 | { |
|---|
| 661 | 549 | const void *end = (const void *)((const char *)p + len); |
|---|
| .. | .. |
|---|
| 686 | 574 | gss_delete_sec_context_kerberos(void *internal_ctx) { |
|---|
| 687 | 575 | struct krb5_ctx *kctx = internal_ctx; |
|---|
| 688 | 576 | |
|---|
| 689 | | - crypto_free_skcipher(kctx->seq); |
|---|
| 690 | | - crypto_free_skcipher(kctx->enc); |
|---|
| 691 | | - crypto_free_skcipher(kctx->acceptor_enc); |
|---|
| 692 | | - crypto_free_skcipher(kctx->initiator_enc); |
|---|
| 693 | | - crypto_free_skcipher(kctx->acceptor_enc_aux); |
|---|
| 694 | | - crypto_free_skcipher(kctx->initiator_enc_aux); |
|---|
| 577 | + crypto_free_sync_skcipher(kctx->seq); |
|---|
| 578 | + crypto_free_sync_skcipher(kctx->enc); |
|---|
| 579 | + crypto_free_sync_skcipher(kctx->acceptor_enc); |
|---|
| 580 | + crypto_free_sync_skcipher(kctx->initiator_enc); |
|---|
| 581 | + crypto_free_sync_skcipher(kctx->acceptor_enc_aux); |
|---|
| 582 | + crypto_free_sync_skcipher(kctx->initiator_enc_aux); |
|---|
| 695 | 583 | kfree(kctx->mech_used.data); |
|---|
| 696 | 584 | kfree(kctx); |
|---|
| 697 | 585 | } |
|---|