| .. | .. |
|---|
| 137 | 137 | switch (conflen) { |
|---|
| 138 | 138 | case 16: |
|---|
| 139 | 139 | *q++ = i++; |
|---|
| 140 | | - /* fall through */ |
|---|
| 140 | + fallthrough; |
|---|
| 141 | 141 | case 8: |
|---|
| 142 | 142 | *q++ = i++; |
|---|
| 143 | 143 | break; |
|---|
| .. | .. |
|---|
| 163 | 163 | .data = cksumdata}; |
|---|
| 164 | 164 | int blocksize = 0, plainlen; |
|---|
| 165 | 165 | unsigned char *ptr, *msg_start; |
|---|
| 166 | | - s32 now; |
|---|
| 166 | + time64_t now; |
|---|
| 167 | 167 | int headlen; |
|---|
| 168 | 168 | struct page **tmp_pages; |
|---|
| 169 | 169 | u32 seq_send; |
|---|
| .. | .. |
|---|
| 172 | 172 | |
|---|
| 173 | 173 | dprintk("RPC: %s\n", __func__); |
|---|
| 174 | 174 | |
|---|
| 175 | | - now = get_seconds(); |
|---|
| 175 | + now = ktime_get_real_seconds(); |
|---|
| 176 | 176 | |
|---|
| 177 | | - blocksize = crypto_skcipher_blocksize(kctx->enc); |
|---|
| 177 | + blocksize = crypto_sync_skcipher_blocksize(kctx->enc); |
|---|
| 178 | 178 | gss_krb5_add_padding(buf, offset, blocksize); |
|---|
| 179 | 179 | BUG_ON((buf->len - offset) % blocksize); |
|---|
| 180 | 180 | plainlen = conflen + buf->len - offset; |
|---|
| .. | .. |
|---|
| 228 | 228 | |
|---|
| 229 | 229 | memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len); |
|---|
| 230 | 230 | |
|---|
| 231 | | - spin_lock(&krb5_seq_lock); |
|---|
| 232 | | - seq_send = kctx->seq_send++; |
|---|
| 233 | | - spin_unlock(&krb5_seq_lock); |
|---|
| 231 | + seq_send = atomic_fetch_inc(&kctx->seq_send); |
|---|
| 234 | 232 | |
|---|
| 235 | 233 | /* XXX would probably be more efficient to compute checksum |
|---|
| 236 | 234 | * and encrypt at the same time: */ |
|---|
| .. | .. |
|---|
| 238 | 236 | seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8))) |
|---|
| 239 | 237 | return GSS_S_FAILURE; |
|---|
| 240 | 238 | |
|---|
| 241 | | - if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC) { |
|---|
| 242 | | - struct crypto_skcipher *cipher; |
|---|
| 243 | | - int err; |
|---|
| 244 | | - cipher = crypto_alloc_skcipher(kctx->gk5e->encrypt_name, 0, |
|---|
| 245 | | - CRYPTO_ALG_ASYNC); |
|---|
| 246 | | - if (IS_ERR(cipher)) |
|---|
| 247 | | - return GSS_S_FAILURE; |
|---|
| 248 | | - |
|---|
| 249 | | - krb5_rc4_setup_enc_key(kctx, cipher, seq_send); |
|---|
| 250 | | - |
|---|
| 251 | | - err = gss_encrypt_xdr_buf(cipher, buf, |
|---|
| 252 | | - offset + headlen - conflen, pages); |
|---|
| 253 | | - crypto_free_skcipher(cipher); |
|---|
| 254 | | - if (err) |
|---|
| 255 | | - return GSS_S_FAILURE; |
|---|
| 256 | | - } else { |
|---|
| 257 | | - if (gss_encrypt_xdr_buf(kctx->enc, buf, |
|---|
| 258 | | - offset + headlen - conflen, pages)) |
|---|
| 259 | | - return GSS_S_FAILURE; |
|---|
| 260 | | - } |
|---|
| 239 | + if (gss_encrypt_xdr_buf(kctx->enc, buf, |
|---|
| 240 | + offset + headlen - conflen, pages)) |
|---|
| 241 | + return GSS_S_FAILURE; |
|---|
| 261 | 242 | |
|---|
| 262 | 243 | return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; |
|---|
| 263 | 244 | } |
|---|
| 264 | 245 | |
|---|
| 265 | 246 | static u32 |
|---|
| 266 | | -gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) |
|---|
| 247 | +gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, int len, |
|---|
| 248 | + struct xdr_buf *buf, unsigned int *slack, |
|---|
| 249 | + unsigned int *align) |
|---|
| 267 | 250 | { |
|---|
| 268 | 251 | int signalg; |
|---|
| 269 | 252 | int sealalg; |
|---|
| 270 | 253 | char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; |
|---|
| 271 | 254 | struct xdr_netobj md5cksum = {.len = sizeof(cksumdata), |
|---|
| 272 | 255 | .data = cksumdata}; |
|---|
| 273 | | - s32 now; |
|---|
| 256 | + time64_t now; |
|---|
| 274 | 257 | int direction; |
|---|
| 275 | 258 | s32 seqnum; |
|---|
| 276 | 259 | unsigned char *ptr; |
|---|
| .. | .. |
|---|
| 281 | 264 | u32 conflen = kctx->gk5e->conflen; |
|---|
| 282 | 265 | int crypt_offset; |
|---|
| 283 | 266 | u8 *cksumkey; |
|---|
| 267 | + unsigned int saved_len = buf->len; |
|---|
| 284 | 268 | |
|---|
| 285 | 269 | dprintk("RPC: gss_unwrap_kerberos\n"); |
|---|
| 286 | 270 | |
|---|
| 287 | 271 | ptr = (u8 *)buf->head[0].iov_base + offset; |
|---|
| 288 | 272 | if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr, |
|---|
| 289 | | - buf->len - offset)) |
|---|
| 273 | + len - offset)) |
|---|
| 290 | 274 | return GSS_S_DEFECTIVE_TOKEN; |
|---|
| 291 | 275 | |
|---|
| 292 | 276 | if ((ptr[0] != ((KG_TOK_WRAP_MSG >> 8) & 0xff)) || |
|---|
| .. | .. |
|---|
| 315 | 299 | crypt_offset = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) - |
|---|
| 316 | 300 | (unsigned char *)buf->head[0].iov_base; |
|---|
| 317 | 301 | |
|---|
| 318 | | - /* |
|---|
| 319 | | - * Need plaintext seqnum to derive encryption key for arcfour-hmac |
|---|
| 320 | | - */ |
|---|
| 321 | | - if (krb5_get_seq_num(kctx, ptr + GSS_KRB5_TOK_HDR_LEN, |
|---|
| 322 | | - ptr + 8, &direction, &seqnum)) |
|---|
| 323 | | - return GSS_S_BAD_SIG; |
|---|
| 324 | | - |
|---|
| 325 | | - if ((kctx->initiate && direction != 0xff) || |
|---|
| 326 | | - (!kctx->initiate && direction != 0)) |
|---|
| 327 | | - return GSS_S_BAD_SIG; |
|---|
| 328 | | - |
|---|
| 329 | | - if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC) { |
|---|
| 330 | | - struct crypto_skcipher *cipher; |
|---|
| 331 | | - int err; |
|---|
| 332 | | - |
|---|
| 333 | | - cipher = crypto_alloc_skcipher(kctx->gk5e->encrypt_name, 0, |
|---|
| 334 | | - CRYPTO_ALG_ASYNC); |
|---|
| 335 | | - if (IS_ERR(cipher)) |
|---|
| 336 | | - return GSS_S_FAILURE; |
|---|
| 337 | | - |
|---|
| 338 | | - krb5_rc4_setup_enc_key(kctx, cipher, seqnum); |
|---|
| 339 | | - |
|---|
| 340 | | - err = gss_decrypt_xdr_buf(cipher, buf, crypt_offset); |
|---|
| 341 | | - crypto_free_skcipher(cipher); |
|---|
| 342 | | - if (err) |
|---|
| 343 | | - return GSS_S_DEFECTIVE_TOKEN; |
|---|
| 344 | | - } else { |
|---|
| 345 | | - if (gss_decrypt_xdr_buf(kctx->enc, buf, crypt_offset)) |
|---|
| 346 | | - return GSS_S_DEFECTIVE_TOKEN; |
|---|
| 347 | | - } |
|---|
| 302 | + buf->len = len; |
|---|
| 303 | + if (gss_decrypt_xdr_buf(kctx->enc, buf, crypt_offset)) |
|---|
| 304 | + return GSS_S_DEFECTIVE_TOKEN; |
|---|
| 348 | 305 | |
|---|
| 349 | 306 | if (kctx->gk5e->keyed_cksum) |
|---|
| 350 | 307 | cksumkey = kctx->cksum; |
|---|
| .. | .. |
|---|
| 361 | 318 | |
|---|
| 362 | 319 | /* it got through unscathed. Make sure the context is unexpired */ |
|---|
| 363 | 320 | |
|---|
| 364 | | - now = get_seconds(); |
|---|
| 321 | + now = ktime_get_real_seconds(); |
|---|
| 365 | 322 | |
|---|
| 366 | 323 | if (now > kctx->endtime) |
|---|
| 367 | 324 | return GSS_S_CONTEXT_EXPIRED; |
|---|
| 368 | 325 | |
|---|
| 369 | 326 | /* do sequencing checks */ |
|---|
| 370 | 327 | |
|---|
| 328 | + if (krb5_get_seq_num(kctx, ptr + GSS_KRB5_TOK_HDR_LEN, |
|---|
| 329 | + ptr + 8, &direction, &seqnum)) |
|---|
| 330 | + return GSS_S_BAD_SIG; |
|---|
| 331 | + |
|---|
| 332 | + if ((kctx->initiate && direction != 0xff) || |
|---|
| 333 | + (!kctx->initiate && direction != 0)) |
|---|
| 334 | + return GSS_S_BAD_SIG; |
|---|
| 335 | + |
|---|
| 371 | 336 | /* Copy the data back to the right position. XXX: Would probably be |
|---|
| 372 | 337 | * better to copy and encrypt at the same time. */ |
|---|
| 373 | 338 | |
|---|
| 374 | | - blocksize = crypto_skcipher_blocksize(kctx->enc); |
|---|
| 339 | + blocksize = crypto_sync_skcipher_blocksize(kctx->enc); |
|---|
| 375 | 340 | data_start = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) + |
|---|
| 376 | 341 | conflen; |
|---|
| 377 | 342 | orig_start = buf->head[0].iov_base + offset; |
|---|
| 378 | 343 | data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start; |
|---|
| 379 | 344 | memmove(orig_start, data_start, data_len); |
|---|
| 380 | 345 | buf->head[0].iov_len -= (data_start - orig_start); |
|---|
| 381 | | - buf->len -= (data_start - orig_start); |
|---|
| 346 | + buf->len = len - (data_start - orig_start); |
|---|
| 382 | 347 | |
|---|
| 383 | 348 | if (gss_krb5_remove_padding(buf, blocksize)) |
|---|
| 384 | 349 | return GSS_S_DEFECTIVE_TOKEN; |
|---|
| 385 | 350 | |
|---|
| 351 | + /* slack must include room for krb5 padding */ |
|---|
| 352 | + *slack = XDR_QUADLEN(saved_len - buf->len); |
|---|
| 353 | + /* The GSS blob always precedes the RPC message payload */ |
|---|
| 354 | + *align = *slack; |
|---|
| 386 | 355 | return GSS_S_COMPLETE; |
|---|
| 387 | 356 | } |
|---|
| 388 | 357 | |
|---|
| .. | .. |
|---|
| 441 | 410 | struct xdr_buf *buf, struct page **pages) |
|---|
| 442 | 411 | { |
|---|
| 443 | 412 | u8 *ptr, *plainhdr; |
|---|
| 444 | | - s32 now; |
|---|
| 413 | + time64_t now; |
|---|
| 445 | 414 | u8 flags = 0x00; |
|---|
| 446 | 415 | __be16 *be16ptr; |
|---|
| 447 | 416 | __be64 *be64ptr; |
|---|
| .. | .. |
|---|
| 477 | 446 | *be16ptr++ = 0; |
|---|
| 478 | 447 | |
|---|
| 479 | 448 | be64ptr = (__be64 *)be16ptr; |
|---|
| 480 | | - spin_lock(&krb5_seq_lock); |
|---|
| 481 | | - *be64ptr = cpu_to_be64(kctx->seq_send64++); |
|---|
| 482 | | - spin_unlock(&krb5_seq_lock); |
|---|
| 449 | + *be64ptr = cpu_to_be64(atomic64_fetch_inc(&kctx->seq_send64)); |
|---|
| 483 | 450 | |
|---|
| 484 | 451 | err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, pages); |
|---|
| 485 | 452 | if (err) |
|---|
| 486 | 453 | return err; |
|---|
| 487 | 454 | |
|---|
| 488 | | - now = get_seconds(); |
|---|
| 455 | + now = ktime_get_real_seconds(); |
|---|
| 489 | 456 | return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE; |
|---|
| 490 | 457 | } |
|---|
| 491 | 458 | |
|---|
| 492 | 459 | static u32 |
|---|
| 493 | | -gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf) |
|---|
| 460 | +gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len, |
|---|
| 461 | + struct xdr_buf *buf, unsigned int *slack, |
|---|
| 462 | + unsigned int *align) |
|---|
| 494 | 463 | { |
|---|
| 495 | | - s32 now; |
|---|
| 464 | + time64_t now; |
|---|
| 496 | 465 | u8 *ptr; |
|---|
| 497 | 466 | u8 flags = 0x00; |
|---|
| 498 | 467 | u16 ec, rrc; |
|---|
| .. | .. |
|---|
| 536 | 505 | if (rrc != 0) |
|---|
| 537 | 506 | rotate_left(offset + 16, buf, rrc); |
|---|
| 538 | 507 | |
|---|
| 539 | | - err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf, |
|---|
| 508 | + err = (*kctx->gk5e->decrypt_v2)(kctx, offset, len, buf, |
|---|
| 540 | 509 | &headskip, &tailskip); |
|---|
| 541 | 510 | if (err) |
|---|
| 542 | 511 | return GSS_S_FAILURE; |
|---|
| .. | .. |
|---|
| 546 | 515 | * it against the original |
|---|
| 547 | 516 | */ |
|---|
| 548 | 517 | err = read_bytes_from_xdr_buf(buf, |
|---|
| 549 | | - buf->len - GSS_KRB5_TOK_HDR_LEN - tailskip, |
|---|
| 518 | + len - GSS_KRB5_TOK_HDR_LEN - tailskip, |
|---|
| 550 | 519 | decrypted_hdr, GSS_KRB5_TOK_HDR_LEN); |
|---|
| 551 | 520 | if (err) { |
|---|
| 552 | 521 | dprintk("%s: error %u getting decrypted_hdr\n", __func__, err); |
|---|
| .. | .. |
|---|
| 561 | 530 | /* do sequencing checks */ |
|---|
| 562 | 531 | |
|---|
| 563 | 532 | /* it got through unscathed. Make sure the context is unexpired */ |
|---|
| 564 | | - now = get_seconds(); |
|---|
| 533 | + now = ktime_get_real_seconds(); |
|---|
| 565 | 534 | if (now > kctx->endtime) |
|---|
| 566 | 535 | return GSS_S_CONTEXT_EXPIRED; |
|---|
| 567 | 536 | |
|---|
| .. | .. |
|---|
| 572 | 541 | * Note that buf->head[0].iov_len may indicate the available |
|---|
| 573 | 542 | * head buffer space rather than that actually occupied. |
|---|
| 574 | 543 | */ |
|---|
| 575 | | - movelen = min_t(unsigned int, buf->head[0].iov_len, buf->len); |
|---|
| 544 | + movelen = min_t(unsigned int, buf->head[0].iov_len, len); |
|---|
| 576 | 545 | movelen -= offset + GSS_KRB5_TOK_HDR_LEN + headskip; |
|---|
| 577 | 546 | BUG_ON(offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen > |
|---|
| 578 | 547 | buf->head[0].iov_len); |
|---|
| 579 | 548 | memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen); |
|---|
| 580 | 549 | buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; |
|---|
| 581 | | - buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip; |
|---|
| 550 | + buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip); |
|---|
| 582 | 551 | |
|---|
| 583 | 552 | /* Trim off the trailing "extra count" and checksum blob */ |
|---|
| 584 | 553 | xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip); |
|---|
| 554 | + |
|---|
| 555 | + *align = XDR_QUADLEN(GSS_KRB5_TOK_HDR_LEN + headskip); |
|---|
| 556 | + *slack = *align + XDR_QUADLEN(ec + GSS_KRB5_TOK_HDR_LEN + tailskip); |
|---|
| 585 | 557 | return GSS_S_COMPLETE; |
|---|
| 586 | 558 | } |
|---|
| 587 | 559 | |
|---|
| .. | .. |
|---|
| 596 | 568 | BUG(); |
|---|
| 597 | 569 | case ENCTYPE_DES_CBC_RAW: |
|---|
| 598 | 570 | case ENCTYPE_DES3_CBC_RAW: |
|---|
| 599 | | - case ENCTYPE_ARCFOUR_HMAC: |
|---|
| 600 | 571 | return gss_wrap_kerberos_v1(kctx, offset, buf, pages); |
|---|
| 601 | 572 | case ENCTYPE_AES128_CTS_HMAC_SHA1_96: |
|---|
| 602 | 573 | case ENCTYPE_AES256_CTS_HMAC_SHA1_96: |
|---|
| .. | .. |
|---|
| 605 | 576 | } |
|---|
| 606 | 577 | |
|---|
| 607 | 578 | u32 |
|---|
| 608 | | -gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, struct xdr_buf *buf) |
|---|
| 579 | +gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, |
|---|
| 580 | + int len, struct xdr_buf *buf) |
|---|
| 609 | 581 | { |
|---|
| 610 | 582 | struct krb5_ctx *kctx = gctx->internal_ctx_id; |
|---|
| 611 | 583 | |
|---|
| .. | .. |
|---|
| 614 | 586 | BUG(); |
|---|
| 615 | 587 | case ENCTYPE_DES_CBC_RAW: |
|---|
| 616 | 588 | case ENCTYPE_DES3_CBC_RAW: |
|---|
| 617 | | - case ENCTYPE_ARCFOUR_HMAC: |
|---|
| 618 | | - return gss_unwrap_kerberos_v1(kctx, offset, buf); |
|---|
| 589 | + return gss_unwrap_kerberos_v1(kctx, offset, len, buf, |
|---|
| 590 | + &gctx->slack, &gctx->align); |
|---|
| 619 | 591 | case ENCTYPE_AES128_CTS_HMAC_SHA1_96: |
|---|
| 620 | 592 | case ENCTYPE_AES256_CTS_HMAC_SHA1_96: |
|---|
| 621 | | - return gss_unwrap_kerberos_v2(kctx, offset, buf); |
|---|
| 593 | + return gss_unwrap_kerberos_v2(kctx, offset, len, buf, |
|---|
| 594 | + &gctx->slack, &gctx->align); |
|---|
| 622 | 595 | } |
|---|
| 623 | 596 | } |
|---|