hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/net/sunrpc/auth_gss/gss_krb5_wrap.c
....@@ -137,7 +137,7 @@
137137 switch (conflen) {
138138 case 16:
139139 *q++ = i++;
140
- /* fall through */
140
+ fallthrough;
141141 case 8:
142142 *q++ = i++;
143143 break;
....@@ -163,7 +163,7 @@
163163 .data = cksumdata};
164164 int blocksize = 0, plainlen;
165165 unsigned char *ptr, *msg_start;
166
- s32 now;
166
+ time64_t now;
167167 int headlen;
168168 struct page **tmp_pages;
169169 u32 seq_send;
....@@ -172,9 +172,9 @@
172172
173173 dprintk("RPC: %s\n", __func__);
174174
175
- now = get_seconds();
175
+ now = ktime_get_real_seconds();
176176
177
- blocksize = crypto_skcipher_blocksize(kctx->enc);
177
+ blocksize = crypto_sync_skcipher_blocksize(kctx->enc);
178178 gss_krb5_add_padding(buf, offset, blocksize);
179179 BUG_ON((buf->len - offset) % blocksize);
180180 plainlen = conflen + buf->len - offset;
....@@ -228,9 +228,7 @@
228228
229229 memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
230230
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);
234232
235233 /* XXX would probably be more efficient to compute checksum
236234 * and encrypt at the same time: */
....@@ -238,39 +236,24 @@
238236 seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8)))
239237 return GSS_S_FAILURE;
240238
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;
261242
262243 return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
263244 }
264245
265246 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)
267250 {
268251 int signalg;
269252 int sealalg;
270253 char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
271254 struct xdr_netobj md5cksum = {.len = sizeof(cksumdata),
272255 .data = cksumdata};
273
- s32 now;
256
+ time64_t now;
274257 int direction;
275258 s32 seqnum;
276259 unsigned char *ptr;
....@@ -281,12 +264,13 @@
281264 u32 conflen = kctx->gk5e->conflen;
282265 int crypt_offset;
283266 u8 *cksumkey;
267
+ unsigned int saved_len = buf->len;
284268
285269 dprintk("RPC: gss_unwrap_kerberos\n");
286270
287271 ptr = (u8 *)buf->head[0].iov_base + offset;
288272 if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr,
289
- buf->len - offset))
273
+ len - offset))
290274 return GSS_S_DEFECTIVE_TOKEN;
291275
292276 if ((ptr[0] != ((KG_TOK_WRAP_MSG >> 8) & 0xff)) ||
....@@ -315,36 +299,9 @@
315299 crypt_offset = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) -
316300 (unsigned char *)buf->head[0].iov_base;
317301
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;
348305
349306 if (kctx->gk5e->keyed_cksum)
350307 cksumkey = kctx->cksum;
....@@ -361,28 +318,40 @@
361318
362319 /* it got through unscathed. Make sure the context is unexpired */
363320
364
- now = get_seconds();
321
+ now = ktime_get_real_seconds();
365322
366323 if (now > kctx->endtime)
367324 return GSS_S_CONTEXT_EXPIRED;
368325
369326 /* do sequencing checks */
370327
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
+
371336 /* Copy the data back to the right position. XXX: Would probably be
372337 * better to copy and encrypt at the same time. */
373338
374
- blocksize = crypto_skcipher_blocksize(kctx->enc);
339
+ blocksize = crypto_sync_skcipher_blocksize(kctx->enc);
375340 data_start = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) +
376341 conflen;
377342 orig_start = buf->head[0].iov_base + offset;
378343 data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
379344 memmove(orig_start, data_start, data_len);
380345 buf->head[0].iov_len -= (data_start - orig_start);
381
- buf->len -= (data_start - orig_start);
346
+ buf->len = len - (data_start - orig_start);
382347
383348 if (gss_krb5_remove_padding(buf, blocksize))
384349 return GSS_S_DEFECTIVE_TOKEN;
385350
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;
386355 return GSS_S_COMPLETE;
387356 }
388357
....@@ -441,7 +410,7 @@
441410 struct xdr_buf *buf, struct page **pages)
442411 {
443412 u8 *ptr, *plainhdr;
444
- s32 now;
413
+ time64_t now;
445414 u8 flags = 0x00;
446415 __be16 *be16ptr;
447416 __be64 *be64ptr;
....@@ -477,22 +446,22 @@
477446 *be16ptr++ = 0;
478447
479448 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));
483450
484451 err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, pages);
485452 if (err)
486453 return err;
487454
488
- now = get_seconds();
455
+ now = ktime_get_real_seconds();
489456 return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
490457 }
491458
492459 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)
494463 {
495
- s32 now;
464
+ time64_t now;
496465 u8 *ptr;
497466 u8 flags = 0x00;
498467 u16 ec, rrc;
....@@ -536,7 +505,7 @@
536505 if (rrc != 0)
537506 rotate_left(offset + 16, buf, rrc);
538507
539
- err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf,
508
+ err = (*kctx->gk5e->decrypt_v2)(kctx, offset, len, buf,
540509 &headskip, &tailskip);
541510 if (err)
542511 return GSS_S_FAILURE;
....@@ -546,7 +515,7 @@
546515 * it against the original
547516 */
548517 err = read_bytes_from_xdr_buf(buf,
549
- buf->len - GSS_KRB5_TOK_HDR_LEN - tailskip,
518
+ len - GSS_KRB5_TOK_HDR_LEN - tailskip,
550519 decrypted_hdr, GSS_KRB5_TOK_HDR_LEN);
551520 if (err) {
552521 dprintk("%s: error %u getting decrypted_hdr\n", __func__, err);
....@@ -561,7 +530,7 @@
561530 /* do sequencing checks */
562531
563532 /* it got through unscathed. Make sure the context is unexpired */
564
- now = get_seconds();
533
+ now = ktime_get_real_seconds();
565534 if (now > kctx->endtime)
566535 return GSS_S_CONTEXT_EXPIRED;
567536
....@@ -572,16 +541,19 @@
572541 * Note that buf->head[0].iov_len may indicate the available
573542 * head buffer space rather than that actually occupied.
574543 */
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);
576545 movelen -= offset + GSS_KRB5_TOK_HDR_LEN + headskip;
577546 BUG_ON(offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen >
578547 buf->head[0].iov_len);
579548 memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen);
580549 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);
582551
583552 /* Trim off the trailing "extra count" and checksum blob */
584553 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);
585557 return GSS_S_COMPLETE;
586558 }
587559
....@@ -596,7 +568,6 @@
596568 BUG();
597569 case ENCTYPE_DES_CBC_RAW:
598570 case ENCTYPE_DES3_CBC_RAW:
599
- case ENCTYPE_ARCFOUR_HMAC:
600571 return gss_wrap_kerberos_v1(kctx, offset, buf, pages);
601572 case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
602573 case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
....@@ -605,7 +576,8 @@
605576 }
606577
607578 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)
609581 {
610582 struct krb5_ctx *kctx = gctx->internal_ctx_id;
611583
....@@ -614,10 +586,11 @@
614586 BUG();
615587 case ENCTYPE_DES_CBC_RAW:
616588 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);
619591 case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
620592 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);
622595 }
623596 }