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