.. | .. |
---|
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 | } |
---|