Print this page
3882 remove xmod & friends


  34 
  35 /*
  36  * des_crypt.c, DES encryption library routines
  37  */
  38 
  39 #include <sys/errno.h>
  40 #include <sys/modctl.h>
  41 
  42 #include <sys/systm.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/ddi.h>
  45 #include <sys/crypto/common.h>
  46 #include <sys/crypto/spi.h>
  47 #include <sys/sysmacros.h>
  48 #include <sys/strsun.h>
  49 #include <sys/note.h>
  50 #include <modes/modes.h>
  51 #define _DES_IMPL
  52 #include <des/des_impl.h>
  53 
  54 /* EXPORT DELETE START */
  55 #include <sys/types.h>
  56 #include <rpc/des_crypt.h>
  57 #include <des/des.h>
  58 
  59 #ifdef sun_hardware
  60 #include <sys/ioctl.h>
  61 #ifdef _KERNEL
  62 #include <sys/conf.h>
  63 static int g_desfd = -1;
  64 #define getdesfd()      (cdevsw[11].d_open(0, 0) ? -1 : 0)
  65 #define ioctl(a, b, c)  (cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0)
  66 #else
  67 #define getdesfd()      (open("/dev/des", 0, 0))
  68 #endif  /* _KERNEL */
  69 #endif  /* sun */
  70 
  71 static int common_crypt(char *key, char *buf, size_t len,
  72     unsigned int mode, struct desparams *desp);
  73 
  74 extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
  75 
  76 /* EXPORT DELETE END */
  77 
  78 extern struct mod_ops mod_cryptoops;
  79 
  80 /*
  81  * Module linkage information for the kernel.
  82  */
  83 static struct modlmisc modlmisc = {
  84         &mod_miscops,
  85         "des encryption",
  86 };
  87 
  88 static struct modlcrypto modlcrypto = {
  89         &mod_cryptoops,
  90         "DES Kernel SW Provider"
  91 };
  92 
  93 static struct modlinkage modlinkage = {
  94         MODREV_1,
  95         &modlmisc,
  96         &modlcrypto,
  97         NULL
  98 };
  99 
 100 /* EXPORT DELETE START */
 101 
 102 #define DES_MIN_KEY_LEN         DES_MINBYTES
 103 #define DES_MAX_KEY_LEN         DES_MAXBYTES
 104 #define DES3_MIN_KEY_LEN        DES3_MAXBYTES   /* no CKK_DES2 support */
 105 #define DES3_MAX_KEY_LEN        DES3_MAXBYTES
 106 
 107 /* EXPORT DELETE END */
 108 
 109 #ifndef DES_MIN_KEY_LEN
 110 #define DES_MIN_KEY_LEN         0
 111 #endif
 112 
 113 #ifndef DES_MAX_KEY_LEN
 114 #define DES_MAX_KEY_LEN         0
 115 #endif
 116 
 117 #ifndef DES3_MIN_KEY_LEN
 118 #define DES3_MIN_KEY_LEN        0
 119 #endif
 120 
 121 #ifndef DES3_MAX_KEY_LEN
 122 #define DES3_MAX_KEY_LEN        0
 123 #endif
 124 
 125 
 126 /*
 127  * Mechanism info structure passed to KCF during registration.
 128  */


 294  * Copy multiple of 8 bytes
 295  */
 296 #define DESCOPY(src, dst, len) { \
 297         char *a = (char *)dst; \
 298         char *b = (char *)src; \
 299         int i; \
 300         for (i = (size_t)len; i > 0; i -= 8) { \
 301                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 302                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 303         } \
 304 }
 305 
 306 /*
 307  * CBC mode encryption
 308  */
 309 /* ARGSUSED */
 310 int
 311 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
 312 {
 313         int err = 0;
 314 /* EXPORT DELETE START */
 315         struct desparams dp;
 316 
 317         dp.des_mode = CBC;
 318         COPY8(ivec, dp.des_ivec);
 319         err = common_crypt(key, buf, len, mode, &dp);
 320         COPY8(dp.des_ivec, ivec);
 321 /* EXPORT DELETE END */
 322         return (err);
 323 }
 324 
 325 
 326 /*
 327  * ECB mode encryption
 328  */
 329 /* ARGSUSED */
 330 int
 331 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
 332 {
 333         int err = 0;
 334 /* EXPORT DELETE START */
 335         struct desparams dp;
 336 
 337         dp.des_mode = ECB;
 338         err = common_crypt(key, buf, len, mode, &dp);
 339 /* EXPORT DELETE END */
 340         return (err);
 341 }
 342 
 343 
 344 
 345 /* EXPORT DELETE START */
 346 /*
 347  * Common code to cbc_crypt() & ecb_crypt()
 348  */
 349 static int
 350 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
 351     struct desparams *desp)
 352 {
 353         int desdev;
 354 
 355         if ((len % 8) != 0 || len > DES_MAXDATA)
 356                 return (DESERR_BADPARAM);
 357 
 358         desp->des_dir =
 359             ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
 360 
 361         desdev = mode & DES_DEVMASK;
 362         COPY8(key, desp->des_key);
 363 
 364 #ifdef sun_hardware
 365         if (desdev == DES_HW) {


 411                         return (CRYPTO_KEY_SIZE_RANGE);
 412                 if (strength == DES3 && key->ck_length != DES3_MAXBITS)
 413                         return (CRYPTO_KEY_SIZE_RANGE);
 414                 break;
 415         default:
 416                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
 417         }
 418 
 419         /*
 420          * Fix parity bits.
 421          * Initialize key schedule even if key is weak.
 422          */
 423         if (key->ck_data == NULL)
 424                 return (CRYPTO_ARGUMENTS_BAD);
 425 
 426         des_parity_fix(key->ck_data, strength, corrected_key);
 427         des_init_keysched(corrected_key, strength, newbie);
 428         return (CRYPTO_SUCCESS);
 429 }
 430 
 431 /* EXPORT DELETE END */
 432 
 433 /*
 434  * KCF software provider control entry points.
 435  */
 436 /* ARGSUSED */
 437 static void
 438 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
 439 {
 440         *status = CRYPTO_PROVIDER_READY;
 441 }
 442 
 443 /*
 444  * KCF software provider encrypt entry points.
 445  */
 446 static int
 447 des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
 448     crypto_key_t *key, crypto_spi_ctx_template_t template,
 449     crypto_req_handle_t req)
 450 {
 451 
 452 /* EXPORT DELETE START */
 453 
 454         des_strength_t strength;
 455         des_ctx_t *des_ctx = NULL;
 456         int rv;
 457         int kmflag;
 458 
 459         /*
 460          * Only keys by value are supported by this module.
 461          */
 462         if (key->ck_format != CRYPTO_KEY_RAW) {
 463                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
 464         }
 465 
 466         kmflag = crypto_kmflag(req);
 467         /* Check mechanism type and parameter length */
 468         switch (mechanism->cm_type) {
 469         case DES_ECB_MECH_INFO_TYPE:
 470                 des_ctx = ecb_alloc_ctx(kmflag);
 471                 /* FALLTHRU */
 472         case DES_CBC_MECH_INFO_TYPE:
 473                 if (mechanism->cm_param != NULL &&


 487                     mechanism->cm_param_len != DES_BLOCK_LEN)
 488                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 489                 if (key->ck_length != DES3_MAXBITS)
 490                         return (CRYPTO_KEY_SIZE_RANGE);
 491                 strength = DES3;
 492                 if (des_ctx == NULL)
 493                         des_ctx = cbc_alloc_ctx(kmflag);
 494                 break;
 495         default:
 496                 return (CRYPTO_MECHANISM_INVALID);
 497         }
 498 
 499         if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
 500             strength, kmflag)) != CRYPTO_SUCCESS) {
 501                 crypto_free_mode_ctx(des_ctx);
 502                 return (rv);
 503         }
 504 
 505         ctx->cc_provider_private = des_ctx;
 506 
 507 /* EXPORT DELETE END */
 508 
 509         return (CRYPTO_SUCCESS);
 510 }
 511 
 512 static void
 513 des_copy_block64(uint8_t *in, uint64_t *out)
 514 {
 515         if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
 516                 /* LINTED: pointer alignment */
 517                 out[0] = *(uint64_t *)&in[0];
 518         } else {
 519                 uint64_t tmp64;
 520 
 521 #ifdef _BIG_ENDIAN
 522                 tmp64 = (((uint64_t)in[0] << 56) |
 523                     ((uint64_t)in[1] << 48) |
 524                     ((uint64_t)in[2] << 40) |
 525                     ((uint64_t)in[3] << 32) |
 526                     ((uint64_t)in[4] << 24) |
 527                     ((uint64_t)in[5] << 16) |
 528                     ((uint64_t)in[6] << 8) |


 532                     ((uint64_t)in[6] << 48) |
 533                     ((uint64_t)in[5] << 40) |
 534                     ((uint64_t)in[4] << 32) |
 535                     ((uint64_t)in[3] << 24) |
 536                     ((uint64_t)in[2] << 16) |
 537                     ((uint64_t)in[1] << 8) |
 538                     (uint64_t)in[0]);
 539 #endif /* _BIG_ENDIAN */
 540 
 541                 out[0] = tmp64;
 542         }
 543 }
 544 
 545 /* ARGSUSED */
 546 static int
 547 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 548     crypto_data_t *ciphertext, crypto_req_handle_t req)
 549 {
 550         int ret;
 551 
 552 /* EXPORT DELETE START */
 553         des_ctx_t *des_ctx;
 554 
 555         /*
 556          * Plaintext must be a multiple of the block size.
 557          * This test only works for non-padded mechanisms
 558          * when blocksize is 2^N.
 559          */
 560         if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 561                 return (CRYPTO_DATA_LEN_RANGE);
 562 
 563         ASSERT(ctx->cc_provider_private != NULL);
 564         des_ctx = ctx->cc_provider_private;
 565 
 566         DES_ARG_INPLACE(plaintext, ciphertext);
 567 
 568         /*
 569          * We need to just return the length needed to store the output.
 570          * We should not destroy the context for the following case.
 571          */
 572         if (ciphertext->cd_length < plaintext->cd_length) {
 573                 ciphertext->cd_length = plaintext->cd_length;
 574                 return (CRYPTO_BUFFER_TOO_SMALL);
 575         }
 576 
 577         /*
 578          * Do an update on the specified input data.
 579          */
 580         ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
 581         ASSERT(des_ctx->dc_remainder_len == 0);
 582         (void) des_free_context(ctx);
 583 
 584 /* EXPORT DELETE END */
 585 
 586         /* LINTED */
 587         return (ret);
 588 }
 589 
 590 /* ARGSUSED */
 591 static int
 592 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 593     crypto_data_t *plaintext, crypto_req_handle_t req)
 594 {
 595         int ret;
 596 
 597 /* EXPORT DELETE START */
 598         des_ctx_t *des_ctx;
 599 
 600         /*
 601          * Ciphertext must be a multiple of the block size.
 602          * This test only works for non-padded mechanisms
 603          * when blocksize is 2^N.
 604          */
 605         if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 606                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 607 
 608         ASSERT(ctx->cc_provider_private != NULL);
 609         des_ctx = ctx->cc_provider_private;
 610 
 611         DES_ARG_INPLACE(ciphertext, plaintext);
 612 
 613         /*
 614          * We need to just return the length needed to store the output.
 615          * We should not destroy the context for the following case.
 616          */
 617         if (plaintext->cd_length < ciphertext->cd_length) {
 618                 plaintext->cd_length = ciphertext->cd_length;
 619                 return (CRYPTO_BUFFER_TOO_SMALL);
 620         }
 621 
 622         /*
 623          * Do an update on the specified input data.
 624          */
 625         ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
 626         ASSERT(des_ctx->dc_remainder_len == 0);
 627         (void) des_free_context(ctx);
 628 
 629 /* EXPORT DELETE END */
 630 
 631         /* LINTED */
 632         return (ret);
 633 }
 634 
 635 /* ARGSUSED */
 636 static int
 637 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 638     crypto_data_t *ciphertext, crypto_req_handle_t req)
 639 {
 640         off_t saved_offset;
 641         size_t saved_length, out_len;
 642         int ret = CRYPTO_SUCCESS;
 643 
 644 /* EXPORT DELETE START */
 645 
 646         ASSERT(ctx->cc_provider_private != NULL);
 647 
 648         DES_ARG_INPLACE(plaintext, ciphertext);
 649 
 650         /* compute number of bytes that will hold the ciphertext */
 651         out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 652         out_len += plaintext->cd_length;
 653         out_len &= ~(DES_BLOCK_LEN - 1);
 654 
 655         /* return length needed to store the output */
 656         if (ciphertext->cd_length < out_len) {
 657                 ciphertext->cd_length = out_len;
 658                 return (CRYPTO_BUFFER_TOO_SMALL);
 659         }
 660 
 661         saved_offset = ciphertext->cd_offset;
 662         saved_length = ciphertext->cd_length;
 663 
 664         /*
 665          * Do the DES update on the specified input data.


 676                     des_copy_block64);
 677                 break;
 678         case CRYPTO_DATA_MBLK:
 679                 ret = crypto_update_mp(ctx->cc_provider_private,
 680                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 681                     des_copy_block64);
 682                 break;
 683         default:
 684                 ret = CRYPTO_ARGUMENTS_BAD;
 685         }
 686 
 687         if (ret == CRYPTO_SUCCESS) {
 688                 if (plaintext != ciphertext)
 689                         ciphertext->cd_length =
 690                             ciphertext->cd_offset - saved_offset;
 691         } else {
 692                 ciphertext->cd_length = saved_length;
 693         }
 694         ciphertext->cd_offset = saved_offset;
 695 
 696 /* EXPORT DELETE END */
 697 
 698         return (ret);
 699 }
 700 
 701 /* ARGSUSED */
 702 static int
 703 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 704     crypto_data_t *plaintext, crypto_req_handle_t req)
 705 {
 706         off_t saved_offset;
 707         size_t saved_length, out_len;
 708         int ret = CRYPTO_SUCCESS;
 709 
 710 /* EXPORT DELETE START */
 711 
 712         ASSERT(ctx->cc_provider_private != NULL);
 713 
 714         DES_ARG_INPLACE(ciphertext, plaintext);
 715 
 716         /* compute number of bytes that will hold the plaintext */
 717         out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 718         out_len += ciphertext->cd_length;
 719         out_len &= ~(DES_BLOCK_LEN - 1);
 720 
 721         /* return length needed to store the output */
 722         if (plaintext->cd_length < out_len) {
 723                 plaintext->cd_length = out_len;
 724                 return (CRYPTO_BUFFER_TOO_SMALL);
 725         }
 726 
 727         saved_offset = plaintext->cd_offset;
 728         saved_length = plaintext->cd_length;
 729 
 730         /*
 731          * Do the DES update on the specified input data.


 742                     des_copy_block64);
 743                 break;
 744         case CRYPTO_DATA_MBLK:
 745                 ret = crypto_update_mp(ctx->cc_provider_private,
 746                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 747                     des_copy_block64);
 748                 break;
 749         default:
 750                 ret = CRYPTO_ARGUMENTS_BAD;
 751         }
 752 
 753         if (ret == CRYPTO_SUCCESS) {
 754                 if (ciphertext != plaintext)
 755                         plaintext->cd_length =
 756                             plaintext->cd_offset - saved_offset;
 757         } else {
 758                 plaintext->cd_length = saved_length;
 759         }
 760         plaintext->cd_offset = saved_offset;
 761 
 762 /* EXPORT DELETE END */
 763 
 764         return (ret);
 765 }
 766 
 767 /* ARGSUSED */
 768 static int
 769 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 770     crypto_req_handle_t req)
 771 {
 772 
 773 /* EXPORT DELETE START */
 774 
 775         des_ctx_t *des_ctx;
 776 
 777         ASSERT(ctx->cc_provider_private != NULL);
 778         des_ctx = ctx->cc_provider_private;
 779 
 780         /*
 781          * There must be no unprocessed plaintext.
 782          * This happens if the length of the last data is
 783          * not a multiple of the DES block length.
 784          */
 785         if (des_ctx->dc_remainder_len > 0)
 786                 return (CRYPTO_DATA_LEN_RANGE);
 787 
 788         (void) des_free_context(ctx);
 789         ciphertext->cd_length = 0;
 790 
 791 /* EXPORT DELETE END */
 792 
 793         return (CRYPTO_SUCCESS);
 794 }
 795 
 796 /* ARGSUSED */
 797 static int
 798 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 799     crypto_req_handle_t req)
 800 {
 801 
 802 /* EXPORT DELETE START */
 803 
 804         des_ctx_t *des_ctx;
 805 
 806         ASSERT(ctx->cc_provider_private != NULL);
 807         des_ctx = ctx->cc_provider_private;
 808 
 809         /*
 810          * There must be no unprocessed ciphertext.
 811          * This happens if the length of the last ciphertext is
 812          * not a multiple of the DES block length.
 813          */
 814         if (des_ctx->dc_remainder_len > 0)
 815                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 816 
 817         (void) des_free_context(ctx);
 818         plaintext->cd_length = 0;
 819 
 820 /* EXPORT DELETE END */
 821 
 822         return (CRYPTO_SUCCESS);
 823 }
 824 
 825 /* ARGSUSED */
 826 static int
 827 des_encrypt_atomic(crypto_provider_handle_t provider,
 828     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 829     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
 830     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 831 {
 832         int ret;
 833 
 834 /* EXPORT DELETE START */
 835 
 836         des_ctx_t des_ctx;              /* on the stack */
 837         des_strength_t strength;
 838         off_t saved_offset;
 839         size_t saved_length;
 840 
 841         DES_ARG_INPLACE(plaintext, ciphertext);
 842 
 843         /*
 844          * Plaintext must be a multiple of the block size.
 845          * This test only works for non-padded mechanisms
 846          * when blocksize is 2^N.
 847          */
 848         if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 849                 return (CRYPTO_DATA_LEN_RANGE);
 850 
 851         /* return length needed to store the output */
 852         if (ciphertext->cd_length < plaintext->cd_length) {
 853                 ciphertext->cd_length = plaintext->cd_length;
 854                 return (CRYPTO_BUFFER_TOO_SMALL);
 855         }


 906                 break;
 907         default:
 908                 ret = CRYPTO_ARGUMENTS_BAD;
 909         }
 910 
 911         if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
 912                 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 913                 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 914         }
 915 
 916         if (ret == CRYPTO_SUCCESS) {
 917                 ASSERT(des_ctx.dc_remainder_len == 0);
 918                 if (plaintext != ciphertext)
 919                         ciphertext->cd_length =
 920                             ciphertext->cd_offset - saved_offset;
 921         } else {
 922                 ciphertext->cd_length = saved_length;
 923         }
 924         ciphertext->cd_offset = saved_offset;
 925 
 926 /* EXPORT DELETE END */
 927 
 928         /* LINTED */
 929         return (ret);
 930 }
 931 
 932 /* ARGSUSED */
 933 static int
 934 des_decrypt_atomic(crypto_provider_handle_t provider,
 935     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 936     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
 937     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 938 {
 939         int ret;
 940 
 941 /* EXPORT DELETE START */
 942 
 943         des_ctx_t des_ctx;      /* on the stack */
 944         des_strength_t strength;
 945         off_t saved_offset;
 946         size_t saved_length;
 947 
 948         DES_ARG_INPLACE(ciphertext, plaintext);
 949 
 950         /*
 951          * Ciphertext must be a multiple of the block size.
 952          * This test only works for non-padded mechanisms
 953          * when blocksize is 2^N.
 954          */
 955         if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 956                 return (CRYPTO_DATA_LEN_RANGE);
 957 
 958         /* return length needed to store the output */
 959         if (plaintext->cd_length < ciphertext->cd_length) {
 960                 plaintext->cd_length = ciphertext->cd_length;
 961                 return (CRYPTO_BUFFER_TOO_SMALL);
 962         }


1013                 break;
1014         default:
1015                 ret = CRYPTO_ARGUMENTS_BAD;
1016         }
1017 
1018         if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1019                 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1020                 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1021         }
1022 
1023         if (ret == CRYPTO_SUCCESS) {
1024                 ASSERT(des_ctx.dc_remainder_len == 0);
1025                 if (ciphertext != plaintext)
1026                         plaintext->cd_length =
1027                             plaintext->cd_offset - saved_offset;
1028         } else {
1029                 plaintext->cd_length = saved_length;
1030         }
1031         plaintext->cd_offset = saved_offset;
1032 
1033 /* EXPORT DELETE END */
1034 
1035         /* LINTED */
1036         return (ret);
1037 }
1038 
1039 /*
1040  * KCF software provider context template entry points.
1041  */
1042 /* ARGSUSED */
1043 static int
1044 des_create_ctx_template(crypto_provider_handle_t provider,
1045     crypto_mechanism_t *mechanism, crypto_key_t *key,
1046     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1047 {
1048 
1049 /* EXPORT DELETE START */
1050 
1051         des_strength_t strength;
1052         void *keysched;
1053         size_t size;
1054         int rv;
1055 
1056         switch (mechanism->cm_type) {
1057         case DES_ECB_MECH_INFO_TYPE:
1058                 strength = DES;
1059                 break;
1060         case DES_CBC_MECH_INFO_TYPE:
1061                 strength = DES;
1062                 break;
1063         case DES3_ECB_MECH_INFO_TYPE:
1064                 strength = DES3;
1065                 break;
1066         case DES3_CBC_MECH_INFO_TYPE:
1067                 strength = DES3;
1068                 break;
1069         default:
1070                 return (CRYPTO_MECHANISM_INVALID);
1071         }
1072 
1073         if ((keysched = des_alloc_keysched(&size, strength,
1074             crypto_kmflag(req))) == NULL) {
1075                 return (CRYPTO_HOST_MEMORY);
1076         }
1077 
1078         /*
1079          * Initialize key schedule.  Key length information is stored
1080          * in the key.
1081          */
1082         if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1083                 bzero(keysched, size);
1084                 kmem_free(keysched, size);
1085                 return (rv);
1086         }
1087 
1088         *tmpl = keysched;
1089         *tmpl_size = size;
1090 
1091 /* EXPORT DELETE END */
1092 
1093         return (CRYPTO_SUCCESS);
1094 }
1095 
1096 /* ARGSUSED */
1097 static int
1098 des_free_context(crypto_ctx_t *ctx)
1099 {
1100 
1101 /* EXPORT DELETE START */
1102 
1103         des_ctx_t *des_ctx = ctx->cc_provider_private;
1104 
1105         if (des_ctx != NULL) {
1106                 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1107                         ASSERT(des_ctx->dc_keysched_len != 0);
1108                         bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1109                         kmem_free(des_ctx->dc_keysched,
1110                             des_ctx->dc_keysched_len);
1111                 }
1112                 crypto_free_mode_ctx(des_ctx);
1113                 ctx->cc_provider_private = NULL;
1114         }
1115 
1116 /* EXPORT DELETE END */
1117 
1118         return (CRYPTO_SUCCESS);
1119 }
1120 
1121 /*
1122  * Pass it to des_keycheck() which will
1123  * fix it (parity bits), and check if the fixed key is weak.
1124  */
1125 /* ARGSUSED */
1126 static int
1127 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1128     crypto_key_t *key)
1129 {
1130 
1131 /* EXPORT DELETE START */
1132 
1133         int expectedkeylen;
1134         des_strength_t strength;
1135         uint8_t keydata[DES3_MAX_KEY_LEN];
1136 
1137         if ((mech == NULL) || (key == NULL))
1138                 return (CRYPTO_ARGUMENTS_BAD);
1139 
1140         switch (mech->cm_type) {
1141         case DES_ECB_MECH_INFO_TYPE:
1142         case DES_CBC_MECH_INFO_TYPE:
1143                 expectedkeylen = DES_MINBITS;
1144                 strength = DES;
1145                 break;
1146         case DES3_ECB_MECH_INFO_TYPE:
1147         case DES3_CBC_MECH_INFO_TYPE:
1148                 expectedkeylen = DES3_MAXBITS;
1149                 strength = DES3;
1150                 break;
1151         default:
1152                 return (CRYPTO_MECHANISM_INVALID);
1153         }
1154 
1155         if (key->ck_format != CRYPTO_KEY_RAW)
1156                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
1157 
1158         if (key->ck_length != expectedkeylen)
1159                 return (CRYPTO_KEY_SIZE_RANGE);
1160 
1161         bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1162 
1163         if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1164                 return (CRYPTO_WEAK_KEY);
1165 
1166 /* EXPORT DELETE END */
1167 
1168         return (CRYPTO_SUCCESS);
1169 }
1170 
1171 /* ARGSUSED */
1172 static int
1173 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1174     crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1175     int kmflag)
1176 {
1177         int rv = CRYPTO_SUCCESS;
1178 
1179 /* EXPORT DELETE START */
1180 
1181         void *keysched;
1182         size_t size;
1183 
1184         if (template == NULL) {
1185                 if ((keysched = des_alloc_keysched(&size, strength,
1186                     kmflag)) == NULL)
1187                         return (CRYPTO_HOST_MEMORY);
1188                 /*
1189                  * Initialize key schedule.
1190                  * Key length is stored in the key.
1191                  */
1192                 if ((rv = init_keysched(key, keysched,
1193                     strength)) != CRYPTO_SUCCESS)
1194                         kmem_free(keysched, size);
1195 
1196                 des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1197                 des_ctx->dc_keysched_len = size;
1198         } else {
1199                 keysched = template;
1200         }


1205         }
1206 
1207         switch (mechanism->cm_type) {
1208         case DES_CBC_MECH_INFO_TYPE:
1209         case DES3_CBC_MECH_INFO_TYPE:
1210                 rv = cbc_init_ctx((cbc_ctx_t *)des_ctx, mechanism->cm_param,
1211                     mechanism->cm_param_len, DES_BLOCK_LEN, des_copy_block64);
1212                 break;
1213         case DES_ECB_MECH_INFO_TYPE:
1214         case DES3_ECB_MECH_INFO_TYPE:
1215                 des_ctx->dc_flags |= ECB_MODE;
1216         }
1217 
1218         if (rv != CRYPTO_SUCCESS) {
1219                 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1220                         bzero(keysched, size);
1221                         kmem_free(keysched, size);
1222                 }
1223         }
1224 
1225 /* EXPORT DELETE END */
1226 
1227         return (rv);
1228 }


  34 
  35 /*
  36  * des_crypt.c, DES encryption library routines
  37  */
  38 
  39 #include <sys/errno.h>
  40 #include <sys/modctl.h>
  41 
  42 #include <sys/systm.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/ddi.h>
  45 #include <sys/crypto/common.h>
  46 #include <sys/crypto/spi.h>
  47 #include <sys/sysmacros.h>
  48 #include <sys/strsun.h>
  49 #include <sys/note.h>
  50 #include <modes/modes.h>
  51 #define _DES_IMPL
  52 #include <des/des_impl.h>
  53 

  54 #include <sys/types.h>
  55 #include <rpc/des_crypt.h>
  56 #include <des/des.h>
  57 
  58 #ifdef sun_hardware
  59 #include <sys/ioctl.h>
  60 #ifdef _KERNEL
  61 #include <sys/conf.h>
  62 static int g_desfd = -1;
  63 #define getdesfd()      (cdevsw[11].d_open(0, 0) ? -1 : 0)
  64 #define ioctl(a, b, c)  (cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0)
  65 #else
  66 #define getdesfd()      (open("/dev/des", 0, 0))
  67 #endif  /* _KERNEL */
  68 #endif  /* sun */
  69 
  70 static int common_crypt(char *key, char *buf, size_t len,
  71     unsigned int mode, struct desparams *desp);
  72 
  73 extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
  74 


  75 extern struct mod_ops mod_cryptoops;
  76 
  77 /*
  78  * Module linkage information for the kernel.
  79  */
  80 static struct modlmisc modlmisc = {
  81         &mod_miscops,
  82         "des encryption",
  83 };
  84 
  85 static struct modlcrypto modlcrypto = {
  86         &mod_cryptoops,
  87         "DES Kernel SW Provider"
  88 };
  89 
  90 static struct modlinkage modlinkage = {
  91         MODREV_1,
  92         &modlmisc,
  93         &modlcrypto,
  94         NULL
  95 };
  96 


  97 #define DES_MIN_KEY_LEN         DES_MINBYTES
  98 #define DES_MAX_KEY_LEN         DES_MAXBYTES
  99 #define DES3_MIN_KEY_LEN        DES3_MAXBYTES   /* no CKK_DES2 support */
 100 #define DES3_MAX_KEY_LEN        DES3_MAXBYTES
 101 


 102 #ifndef DES_MIN_KEY_LEN
 103 #define DES_MIN_KEY_LEN         0
 104 #endif
 105 
 106 #ifndef DES_MAX_KEY_LEN
 107 #define DES_MAX_KEY_LEN         0
 108 #endif
 109 
 110 #ifndef DES3_MIN_KEY_LEN
 111 #define DES3_MIN_KEY_LEN        0
 112 #endif
 113 
 114 #ifndef DES3_MAX_KEY_LEN
 115 #define DES3_MAX_KEY_LEN        0
 116 #endif
 117 
 118 
 119 /*
 120  * Mechanism info structure passed to KCF during registration.
 121  */


 287  * Copy multiple of 8 bytes
 288  */
 289 #define DESCOPY(src, dst, len) { \
 290         char *a = (char *)dst; \
 291         char *b = (char *)src; \
 292         int i; \
 293         for (i = (size_t)len; i > 0; i -= 8) { \
 294                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 295                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 296         } \
 297 }
 298 
 299 /*
 300  * CBC mode encryption
 301  */
 302 /* ARGSUSED */
 303 int
 304 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
 305 {
 306         int err = 0;

 307         struct desparams dp;
 308 
 309         dp.des_mode = CBC;
 310         COPY8(ivec, dp.des_ivec);
 311         err = common_crypt(key, buf, len, mode, &dp);
 312         COPY8(dp.des_ivec, ivec);

 313         return (err);
 314 }
 315 
 316 
 317 /*
 318  * ECB mode encryption
 319  */
 320 /* ARGSUSED */
 321 int
 322 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
 323 {
 324         int err = 0;

 325         struct desparams dp;
 326 
 327         dp.des_mode = ECB;
 328         err = common_crypt(key, buf, len, mode, &dp);

 329         return (err);
 330 }
 331 
 332 
 333 

 334 /*
 335  * Common code to cbc_crypt() & ecb_crypt()
 336  */
 337 static int
 338 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
 339     struct desparams *desp)
 340 {
 341         int desdev;
 342 
 343         if ((len % 8) != 0 || len > DES_MAXDATA)
 344                 return (DESERR_BADPARAM);
 345 
 346         desp->des_dir =
 347             ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
 348 
 349         desdev = mode & DES_DEVMASK;
 350         COPY8(key, desp->des_key);
 351 
 352 #ifdef sun_hardware
 353         if (desdev == DES_HW) {


 399                         return (CRYPTO_KEY_SIZE_RANGE);
 400                 if (strength == DES3 && key->ck_length != DES3_MAXBITS)
 401                         return (CRYPTO_KEY_SIZE_RANGE);
 402                 break;
 403         default:
 404                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
 405         }
 406 
 407         /*
 408          * Fix parity bits.
 409          * Initialize key schedule even if key is weak.
 410          */
 411         if (key->ck_data == NULL)
 412                 return (CRYPTO_ARGUMENTS_BAD);
 413 
 414         des_parity_fix(key->ck_data, strength, corrected_key);
 415         des_init_keysched(corrected_key, strength, newbie);
 416         return (CRYPTO_SUCCESS);
 417 }
 418 


 419 /*
 420  * KCF software provider control entry points.
 421  */
 422 /* ARGSUSED */
 423 static void
 424 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
 425 {
 426         *status = CRYPTO_PROVIDER_READY;
 427 }
 428 
 429 /*
 430  * KCF software provider encrypt entry points.
 431  */
 432 static int
 433 des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
 434     crypto_key_t *key, crypto_spi_ctx_template_t template,
 435     crypto_req_handle_t req)
 436 {
 437 


 438         des_strength_t strength;
 439         des_ctx_t *des_ctx = NULL;
 440         int rv;
 441         int kmflag;
 442 
 443         /*
 444          * Only keys by value are supported by this module.
 445          */
 446         if (key->ck_format != CRYPTO_KEY_RAW) {
 447                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
 448         }
 449 
 450         kmflag = crypto_kmflag(req);
 451         /* Check mechanism type and parameter length */
 452         switch (mechanism->cm_type) {
 453         case DES_ECB_MECH_INFO_TYPE:
 454                 des_ctx = ecb_alloc_ctx(kmflag);
 455                 /* FALLTHRU */
 456         case DES_CBC_MECH_INFO_TYPE:
 457                 if (mechanism->cm_param != NULL &&


 471                     mechanism->cm_param_len != DES_BLOCK_LEN)
 472                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 473                 if (key->ck_length != DES3_MAXBITS)
 474                         return (CRYPTO_KEY_SIZE_RANGE);
 475                 strength = DES3;
 476                 if (des_ctx == NULL)
 477                         des_ctx = cbc_alloc_ctx(kmflag);
 478                 break;
 479         default:
 480                 return (CRYPTO_MECHANISM_INVALID);
 481         }
 482 
 483         if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
 484             strength, kmflag)) != CRYPTO_SUCCESS) {
 485                 crypto_free_mode_ctx(des_ctx);
 486                 return (rv);
 487         }
 488 
 489         ctx->cc_provider_private = des_ctx;
 490 


 491         return (CRYPTO_SUCCESS);
 492 }
 493 
 494 static void
 495 des_copy_block64(uint8_t *in, uint64_t *out)
 496 {
 497         if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
 498                 /* LINTED: pointer alignment */
 499                 out[0] = *(uint64_t *)&in[0];
 500         } else {
 501                 uint64_t tmp64;
 502 
 503 #ifdef _BIG_ENDIAN
 504                 tmp64 = (((uint64_t)in[0] << 56) |
 505                     ((uint64_t)in[1] << 48) |
 506                     ((uint64_t)in[2] << 40) |
 507                     ((uint64_t)in[3] << 32) |
 508                     ((uint64_t)in[4] << 24) |
 509                     ((uint64_t)in[5] << 16) |
 510                     ((uint64_t)in[6] << 8) |


 514                     ((uint64_t)in[6] << 48) |
 515                     ((uint64_t)in[5] << 40) |
 516                     ((uint64_t)in[4] << 32) |
 517                     ((uint64_t)in[3] << 24) |
 518                     ((uint64_t)in[2] << 16) |
 519                     ((uint64_t)in[1] << 8) |
 520                     (uint64_t)in[0]);
 521 #endif /* _BIG_ENDIAN */
 522 
 523                 out[0] = tmp64;
 524         }
 525 }
 526 
 527 /* ARGSUSED */
 528 static int
 529 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 530     crypto_data_t *ciphertext, crypto_req_handle_t req)
 531 {
 532         int ret;
 533 

 534         des_ctx_t *des_ctx;
 535 
 536         /*
 537          * Plaintext must be a multiple of the block size.
 538          * This test only works for non-padded mechanisms
 539          * when blocksize is 2^N.
 540          */
 541         if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 542                 return (CRYPTO_DATA_LEN_RANGE);
 543 
 544         ASSERT(ctx->cc_provider_private != NULL);
 545         des_ctx = ctx->cc_provider_private;
 546 
 547         DES_ARG_INPLACE(plaintext, ciphertext);
 548 
 549         /*
 550          * We need to just return the length needed to store the output.
 551          * We should not destroy the context for the following case.
 552          */
 553         if (ciphertext->cd_length < plaintext->cd_length) {
 554                 ciphertext->cd_length = plaintext->cd_length;
 555                 return (CRYPTO_BUFFER_TOO_SMALL);
 556         }
 557 
 558         /*
 559          * Do an update on the specified input data.
 560          */
 561         ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
 562         ASSERT(des_ctx->dc_remainder_len == 0);
 563         (void) des_free_context(ctx);
 564 


 565         /* LINTED */
 566         return (ret);
 567 }
 568 
 569 /* ARGSUSED */
 570 static int
 571 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 572     crypto_data_t *plaintext, crypto_req_handle_t req)
 573 {
 574         int ret;
 575 

 576         des_ctx_t *des_ctx;
 577 
 578         /*
 579          * Ciphertext must be a multiple of the block size.
 580          * This test only works for non-padded mechanisms
 581          * when blocksize is 2^N.
 582          */
 583         if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 584                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 585 
 586         ASSERT(ctx->cc_provider_private != NULL);
 587         des_ctx = ctx->cc_provider_private;
 588 
 589         DES_ARG_INPLACE(ciphertext, plaintext);
 590 
 591         /*
 592          * We need to just return the length needed to store the output.
 593          * We should not destroy the context for the following case.
 594          */
 595         if (plaintext->cd_length < ciphertext->cd_length) {
 596                 plaintext->cd_length = ciphertext->cd_length;
 597                 return (CRYPTO_BUFFER_TOO_SMALL);
 598         }
 599 
 600         /*
 601          * Do an update on the specified input data.
 602          */
 603         ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
 604         ASSERT(des_ctx->dc_remainder_len == 0);
 605         (void) des_free_context(ctx);
 606 


 607         /* LINTED */
 608         return (ret);
 609 }
 610 
 611 /* ARGSUSED */
 612 static int
 613 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 614     crypto_data_t *ciphertext, crypto_req_handle_t req)
 615 {
 616         off_t saved_offset;
 617         size_t saved_length, out_len;
 618         int ret = CRYPTO_SUCCESS;
 619 


 620         ASSERT(ctx->cc_provider_private != NULL);
 621 
 622         DES_ARG_INPLACE(plaintext, ciphertext);
 623 
 624         /* compute number of bytes that will hold the ciphertext */
 625         out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 626         out_len += plaintext->cd_length;
 627         out_len &= ~(DES_BLOCK_LEN - 1);
 628 
 629         /* return length needed to store the output */
 630         if (ciphertext->cd_length < out_len) {
 631                 ciphertext->cd_length = out_len;
 632                 return (CRYPTO_BUFFER_TOO_SMALL);
 633         }
 634 
 635         saved_offset = ciphertext->cd_offset;
 636         saved_length = ciphertext->cd_length;
 637 
 638         /*
 639          * Do the DES update on the specified input data.


 650                     des_copy_block64);
 651                 break;
 652         case CRYPTO_DATA_MBLK:
 653                 ret = crypto_update_mp(ctx->cc_provider_private,
 654                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 655                     des_copy_block64);
 656                 break;
 657         default:
 658                 ret = CRYPTO_ARGUMENTS_BAD;
 659         }
 660 
 661         if (ret == CRYPTO_SUCCESS) {
 662                 if (plaintext != ciphertext)
 663                         ciphertext->cd_length =
 664                             ciphertext->cd_offset - saved_offset;
 665         } else {
 666                 ciphertext->cd_length = saved_length;
 667         }
 668         ciphertext->cd_offset = saved_offset;
 669 


 670         return (ret);
 671 }
 672 
 673 /* ARGSUSED */
 674 static int
 675 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 676     crypto_data_t *plaintext, crypto_req_handle_t req)
 677 {
 678         off_t saved_offset;
 679         size_t saved_length, out_len;
 680         int ret = CRYPTO_SUCCESS;
 681 


 682         ASSERT(ctx->cc_provider_private != NULL);
 683 
 684         DES_ARG_INPLACE(ciphertext, plaintext);
 685 
 686         /* compute number of bytes that will hold the plaintext */
 687         out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 688         out_len += ciphertext->cd_length;
 689         out_len &= ~(DES_BLOCK_LEN - 1);
 690 
 691         /* return length needed to store the output */
 692         if (plaintext->cd_length < out_len) {
 693                 plaintext->cd_length = out_len;
 694                 return (CRYPTO_BUFFER_TOO_SMALL);
 695         }
 696 
 697         saved_offset = plaintext->cd_offset;
 698         saved_length = plaintext->cd_length;
 699 
 700         /*
 701          * Do the DES update on the specified input data.


 712                     des_copy_block64);
 713                 break;
 714         case CRYPTO_DATA_MBLK:
 715                 ret = crypto_update_mp(ctx->cc_provider_private,
 716                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 717                     des_copy_block64);
 718                 break;
 719         default:
 720                 ret = CRYPTO_ARGUMENTS_BAD;
 721         }
 722 
 723         if (ret == CRYPTO_SUCCESS) {
 724                 if (ciphertext != plaintext)
 725                         plaintext->cd_length =
 726                             plaintext->cd_offset - saved_offset;
 727         } else {
 728                 plaintext->cd_length = saved_length;
 729         }
 730         plaintext->cd_offset = saved_offset;
 731 


 732         return (ret);
 733 }
 734 
 735 /* ARGSUSED */
 736 static int
 737 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 738     crypto_req_handle_t req)
 739 {



 740         des_ctx_t *des_ctx;
 741 
 742         ASSERT(ctx->cc_provider_private != NULL);
 743         des_ctx = ctx->cc_provider_private;
 744 
 745         /*
 746          * There must be no unprocessed plaintext.
 747          * This happens if the length of the last data is
 748          * not a multiple of the DES block length.
 749          */
 750         if (des_ctx->dc_remainder_len > 0)
 751                 return (CRYPTO_DATA_LEN_RANGE);
 752 
 753         (void) des_free_context(ctx);
 754         ciphertext->cd_length = 0;
 755 


 756         return (CRYPTO_SUCCESS);
 757 }
 758 
 759 /* ARGSUSED */
 760 static int
 761 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 762     crypto_req_handle_t req)
 763 {



 764         des_ctx_t *des_ctx;
 765 
 766         ASSERT(ctx->cc_provider_private != NULL);
 767         des_ctx = ctx->cc_provider_private;
 768 
 769         /*
 770          * There must be no unprocessed ciphertext.
 771          * This happens if the length of the last ciphertext is
 772          * not a multiple of the DES block length.
 773          */
 774         if (des_ctx->dc_remainder_len > 0)
 775                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 776 
 777         (void) des_free_context(ctx);
 778         plaintext->cd_length = 0;
 779 


 780         return (CRYPTO_SUCCESS);
 781 }
 782 
 783 /* ARGSUSED */
 784 static int
 785 des_encrypt_atomic(crypto_provider_handle_t provider,
 786     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 787     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
 788     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 789 {
 790         int ret;
 791 


 792         des_ctx_t des_ctx;              /* on the stack */
 793         des_strength_t strength;
 794         off_t saved_offset;
 795         size_t saved_length;
 796 
 797         DES_ARG_INPLACE(plaintext, ciphertext);
 798 
 799         /*
 800          * Plaintext must be a multiple of the block size.
 801          * This test only works for non-padded mechanisms
 802          * when blocksize is 2^N.
 803          */
 804         if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 805                 return (CRYPTO_DATA_LEN_RANGE);
 806 
 807         /* return length needed to store the output */
 808         if (ciphertext->cd_length < plaintext->cd_length) {
 809                 ciphertext->cd_length = plaintext->cd_length;
 810                 return (CRYPTO_BUFFER_TOO_SMALL);
 811         }


 862                 break;
 863         default:
 864                 ret = CRYPTO_ARGUMENTS_BAD;
 865         }
 866 
 867         if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
 868                 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 869                 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 870         }
 871 
 872         if (ret == CRYPTO_SUCCESS) {
 873                 ASSERT(des_ctx.dc_remainder_len == 0);
 874                 if (plaintext != ciphertext)
 875                         ciphertext->cd_length =
 876                             ciphertext->cd_offset - saved_offset;
 877         } else {
 878                 ciphertext->cd_length = saved_length;
 879         }
 880         ciphertext->cd_offset = saved_offset;
 881 


 882         /* LINTED */
 883         return (ret);
 884 }
 885 
 886 /* ARGSUSED */
 887 static int
 888 des_decrypt_atomic(crypto_provider_handle_t provider,
 889     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 890     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
 891     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 892 {
 893         int ret;
 894 


 895         des_ctx_t des_ctx;      /* on the stack */
 896         des_strength_t strength;
 897         off_t saved_offset;
 898         size_t saved_length;
 899 
 900         DES_ARG_INPLACE(ciphertext, plaintext);
 901 
 902         /*
 903          * Ciphertext must be a multiple of the block size.
 904          * This test only works for non-padded mechanisms
 905          * when blocksize is 2^N.
 906          */
 907         if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 908                 return (CRYPTO_DATA_LEN_RANGE);
 909 
 910         /* return length needed to store the output */
 911         if (plaintext->cd_length < ciphertext->cd_length) {
 912                 plaintext->cd_length = ciphertext->cd_length;
 913                 return (CRYPTO_BUFFER_TOO_SMALL);
 914         }


 965                 break;
 966         default:
 967                 ret = CRYPTO_ARGUMENTS_BAD;
 968         }
 969 
 970         if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
 971                 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 972                 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 973         }
 974 
 975         if (ret == CRYPTO_SUCCESS) {
 976                 ASSERT(des_ctx.dc_remainder_len == 0);
 977                 if (ciphertext != plaintext)
 978                         plaintext->cd_length =
 979                             plaintext->cd_offset - saved_offset;
 980         } else {
 981                 plaintext->cd_length = saved_length;
 982         }
 983         plaintext->cd_offset = saved_offset;
 984 


 985         /* LINTED */
 986         return (ret);
 987 }
 988 
 989 /*
 990  * KCF software provider context template entry points.
 991  */
 992 /* ARGSUSED */
 993 static int
 994 des_create_ctx_template(crypto_provider_handle_t provider,
 995     crypto_mechanism_t *mechanism, crypto_key_t *key,
 996     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
 997 {
 998 


 999         des_strength_t strength;
1000         void *keysched;
1001         size_t size;
1002         int rv;
1003 
1004         switch (mechanism->cm_type) {
1005         case DES_ECB_MECH_INFO_TYPE:
1006                 strength = DES;
1007                 break;
1008         case DES_CBC_MECH_INFO_TYPE:
1009                 strength = DES;
1010                 break;
1011         case DES3_ECB_MECH_INFO_TYPE:
1012                 strength = DES3;
1013                 break;
1014         case DES3_CBC_MECH_INFO_TYPE:
1015                 strength = DES3;
1016                 break;
1017         default:
1018                 return (CRYPTO_MECHANISM_INVALID);
1019         }
1020 
1021         if ((keysched = des_alloc_keysched(&size, strength,
1022             crypto_kmflag(req))) == NULL) {
1023                 return (CRYPTO_HOST_MEMORY);
1024         }
1025 
1026         /*
1027          * Initialize key schedule.  Key length information is stored
1028          * in the key.
1029          */
1030         if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1031                 bzero(keysched, size);
1032                 kmem_free(keysched, size);
1033                 return (rv);
1034         }
1035 
1036         *tmpl = keysched;
1037         *tmpl_size = size;
1038 


1039         return (CRYPTO_SUCCESS);
1040 }
1041 
1042 /* ARGSUSED */
1043 static int
1044 des_free_context(crypto_ctx_t *ctx)
1045 {



1046         des_ctx_t *des_ctx = ctx->cc_provider_private;
1047 
1048         if (des_ctx != NULL) {
1049                 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1050                         ASSERT(des_ctx->dc_keysched_len != 0);
1051                         bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1052                         kmem_free(des_ctx->dc_keysched,
1053                             des_ctx->dc_keysched_len);
1054                 }
1055                 crypto_free_mode_ctx(des_ctx);
1056                 ctx->cc_provider_private = NULL;
1057         }
1058 


1059         return (CRYPTO_SUCCESS);
1060 }
1061 
1062 /*
1063  * Pass it to des_keycheck() which will
1064  * fix it (parity bits), and check if the fixed key is weak.
1065  */
1066 /* ARGSUSED */
1067 static int
1068 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1069     crypto_key_t *key)
1070 {



1071         int expectedkeylen;
1072         des_strength_t strength;
1073         uint8_t keydata[DES3_MAX_KEY_LEN];
1074 
1075         if ((mech == NULL) || (key == NULL))
1076                 return (CRYPTO_ARGUMENTS_BAD);
1077 
1078         switch (mech->cm_type) {
1079         case DES_ECB_MECH_INFO_TYPE:
1080         case DES_CBC_MECH_INFO_TYPE:
1081                 expectedkeylen = DES_MINBITS;
1082                 strength = DES;
1083                 break;
1084         case DES3_ECB_MECH_INFO_TYPE:
1085         case DES3_CBC_MECH_INFO_TYPE:
1086                 expectedkeylen = DES3_MAXBITS;
1087                 strength = DES3;
1088                 break;
1089         default:
1090                 return (CRYPTO_MECHANISM_INVALID);
1091         }
1092 
1093         if (key->ck_format != CRYPTO_KEY_RAW)
1094                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
1095 
1096         if (key->ck_length != expectedkeylen)
1097                 return (CRYPTO_KEY_SIZE_RANGE);
1098 
1099         bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1100 
1101         if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1102                 return (CRYPTO_WEAK_KEY);
1103 


1104         return (CRYPTO_SUCCESS);
1105 }
1106 
1107 /* ARGSUSED */
1108 static int
1109 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1110     crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1111     int kmflag)
1112 {
1113         int rv = CRYPTO_SUCCESS;
1114 


1115         void *keysched;
1116         size_t size;
1117 
1118         if (template == NULL) {
1119                 if ((keysched = des_alloc_keysched(&size, strength,
1120                     kmflag)) == NULL)
1121                         return (CRYPTO_HOST_MEMORY);
1122                 /*
1123                  * Initialize key schedule.
1124                  * Key length is stored in the key.
1125                  */
1126                 if ((rv = init_keysched(key, keysched,
1127                     strength)) != CRYPTO_SUCCESS)
1128                         kmem_free(keysched, size);
1129 
1130                 des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1131                 des_ctx->dc_keysched_len = size;
1132         } else {
1133                 keysched = template;
1134         }


1139         }
1140 
1141         switch (mechanism->cm_type) {
1142         case DES_CBC_MECH_INFO_TYPE:
1143         case DES3_CBC_MECH_INFO_TYPE:
1144                 rv = cbc_init_ctx((cbc_ctx_t *)des_ctx, mechanism->cm_param,
1145                     mechanism->cm_param_len, DES_BLOCK_LEN, des_copy_block64);
1146                 break;
1147         case DES_ECB_MECH_INFO_TYPE:
1148         case DES3_ECB_MECH_INFO_TYPE:
1149                 des_ctx->dc_flags |= ECB_MODE;
1150         }
1151 
1152         if (rv != CRYPTO_SUCCESS) {
1153                 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1154                         bzero(keysched, size);
1155                         kmem_free(keysched, size);
1156                 }
1157         }
1158 


1159         return (rv);
1160 }