1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  *
  21  */
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright 2015 by Saso Kiselkov. All rights reserved.
  28  */
  29 
  30 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  31 /*        All Rights Reserved   */
  32 
  33 /*
  34  * Portions of this source code were derived from Berkeley 4.3 BSD
  35  * under license from the Regents of the University of California.
  36  */
  37 
  38 /*
  39  * des_crypt.c, DES encryption library routines
  40  */
  41 
  42 #include <sys/errno.h>
  43 #include <sys/modctl.h>
  44 
  45 #include <sys/systm.h>
  46 #include <sys/cmn_err.h>
  47 #include <sys/ddi.h>
  48 #include <sys/crypto/common.h>
  49 #include <sys/crypto/spi.h>
  50 #include <sys/sysmacros.h>
  51 #include <sys/strsun.h>
  52 #include <sys/note.h>
  53 #include <modes/modes.h>
  54 #define _DES_IMPL
  55 #include <des/des_impl.h>
  56 
  57 #include <sys/types.h>
  58 #include <rpc/des_crypt.h>
  59 #include <des/des.h>
  60 
  61 #ifdef sun_hardware
  62 #include <sys/ioctl.h>
  63 #ifdef _KERNEL
  64 #include <sys/conf.h>
  65 static int g_desfd = -1;
  66 #define getdesfd()      (cdevsw[11].d_open(0, 0) ? -1 : 0)
  67 #define ioctl(a, b, c)  (cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0)
  68 #else
  69 #define getdesfd()      (open("/dev/des", 0, 0))
  70 #endif  /* _KERNEL */
  71 #endif  /* sun */
  72 
  73 static int common_crypt(char *key, char *buf, size_t len,
  74     unsigned int mode, struct desparams *desp);
  75 
  76 extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
  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 #define DES_MIN_KEY_LEN         DES_MINBYTES
 101 #define DES_MAX_KEY_LEN         DES_MAXBYTES
 102 #define DES3_MIN_KEY_LEN        DES3_MAXBYTES   /* no CKK_DES2 support */
 103 #define DES3_MAX_KEY_LEN        DES3_MAXBYTES
 104 
 105 #ifndef DES_MIN_KEY_LEN
 106 #define DES_MIN_KEY_LEN         0
 107 #endif
 108 
 109 #ifndef DES_MAX_KEY_LEN
 110 #define DES_MAX_KEY_LEN         0
 111 #endif
 112 
 113 #ifndef DES3_MIN_KEY_LEN
 114 #define DES3_MIN_KEY_LEN        0
 115 #endif
 116 
 117 #ifndef DES3_MAX_KEY_LEN
 118 #define DES3_MAX_KEY_LEN        0
 119 #endif
 120 
 121 
 122 /*
 123  * Mechanism info structure passed to KCF during registration.
 124  */
 125 static crypto_mech_info_t des_mech_info_tab[] = {
 126         /* DES_ECB */
 127         {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
 128             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 129             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 130             DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
 131         /* DES_CBC */
 132         {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
 133             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 134             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 135             DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
 136         /* DES3_ECB */
 137         {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
 138             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 139             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 140             DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
 141         /* DES3_CBC */
 142         {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
 143             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 144             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 145             DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
 146 };
 147 
 148 /* operations are in-place if the output buffer is NULL */
 149 #define DES_ARG_INPLACE(input, output)                          \
 150         if ((output) == NULL)                                   \
 151                 (output) = (input);
 152 
 153 static void des_provider_status(crypto_provider_handle_t, uint_t *);
 154 
 155 static crypto_control_ops_t des_control_ops = {
 156         des_provider_status
 157 };
 158 
 159 static int
 160 des_common_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
 161     crypto_spi_ctx_template_t, crypto_req_handle_t);
 162 static int des_common_init_ctx(des_ctx_t *, crypto_spi_ctx_template_t *,
 163     crypto_mechanism_t *, crypto_key_t *, des_strength_t, int);
 164 static int des_encrypt_final(crypto_ctx_t *, crypto_data_t *,
 165     crypto_req_handle_t);
 166 static int des_decrypt_final(crypto_ctx_t *, crypto_data_t *,
 167     crypto_req_handle_t);
 168 
 169 static int des_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
 170     crypto_req_handle_t);
 171 static int des_encrypt_update(crypto_ctx_t *, crypto_data_t *,
 172     crypto_data_t *, crypto_req_handle_t);
 173 static int des_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
 174     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
 175     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
 176 
 177 static int des_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
 178     crypto_req_handle_t);
 179 static int des_decrypt_update(crypto_ctx_t *, crypto_data_t *,
 180     crypto_data_t *, crypto_req_handle_t);
 181 static int des_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
 182     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
 183     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
 184 
 185 static crypto_cipher_ops_t des_cipher_ops = {
 186         des_common_init,
 187         des_encrypt,
 188         des_encrypt_update,
 189         des_encrypt_final,
 190         des_encrypt_atomic,
 191         des_common_init,
 192         des_decrypt,
 193         des_decrypt_update,
 194         des_decrypt_final,
 195         des_decrypt_atomic
 196 };
 197 
 198 static int des_create_ctx_template(crypto_provider_handle_t,
 199     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
 200     size_t *, crypto_req_handle_t);
 201 static int des_free_context(crypto_ctx_t *);
 202 
 203 static crypto_ctx_ops_t des_ctx_ops = {
 204         des_create_ctx_template,
 205         des_free_context
 206 };
 207 
 208 static int des_key_check(crypto_provider_handle_t, crypto_mechanism_t *,
 209     crypto_key_t *);
 210 
 211 static crypto_key_ops_t des_key_ops = {
 212         NULL,
 213         NULL,
 214         NULL,
 215         NULL,
 216         NULL,
 217         des_key_check
 218 };
 219 
 220 static crypto_ops_t des_crypto_ops = {
 221         &des_control_ops,
 222         NULL,
 223         &des_cipher_ops,
 224         NULL,
 225         NULL,
 226         NULL,
 227         NULL,
 228         NULL,
 229         NULL,
 230         NULL,
 231         NULL,
 232         &des_key_ops,
 233         NULL,
 234         &des_ctx_ops,
 235         NULL,
 236         NULL,
 237         NULL
 238 };
 239 
 240 static crypto_provider_info_t des_prov_info = {
 241         CRYPTO_SPI_VERSION_4,
 242         "DES Software Provider",
 243         CRYPTO_SW_PROVIDER,
 244         {&modlinkage},
 245         NULL,
 246         &des_crypto_ops,
 247         sizeof (des_mech_info_tab)/sizeof (crypto_mech_info_t),
 248         des_mech_info_tab
 249 };
 250 
 251 static crypto_kcf_provider_handle_t des_prov_handle = NULL;
 252 
 253 int
 254 _init(void)
 255 {
 256         int ret;
 257 
 258         if ((ret = mod_install(&modlinkage)) != 0)
 259                 return (ret);
 260 
 261         /*
 262          * Register with KCF. If the registration fails, kcf will log an
 263          * error but do not uninstall the module, since the functionality
 264          * provided by misc/des should still be available.
 265          *
 266          */
 267         (void) crypto_register_provider(&des_prov_info, &des_prov_handle);
 268 
 269         return (0);
 270 }
 271 
 272 
 273 int
 274 _info(struct modinfo *modinfop)
 275 {
 276         return (mod_info(&modlinkage, modinfop));
 277 }
 278 
 279 /*
 280  * Copy 8 bytes
 281  */
 282 #define COPY8(src, dst) { \
 283         char *a = (char *)dst; \
 284         char *b = (char *)src; \
 285         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 286         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 287 }
 288 
 289 /*
 290  * Copy multiple of 8 bytes
 291  */
 292 #define DESCOPY(src, dst, len) { \
 293         char *a = (char *)dst; \
 294         char *b = (char *)src; \
 295         int i; \
 296         for (i = (size_t)len; i > 0; i -= 8) { \
 297                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 298                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 299         } \
 300 }
 301 
 302 /*
 303  * CBC mode encryption
 304  */
 305 /* ARGSUSED */
 306 int
 307 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
 308 {
 309         int err = 0;
 310         struct desparams dp;
 311 
 312         dp.des_mode = CBC;
 313         COPY8(ivec, dp.des_ivec);
 314         err = common_crypt(key, buf, len, mode, &dp);
 315         COPY8(dp.des_ivec, ivec);
 316         return (err);
 317 }
 318 
 319 
 320 /*
 321  * ECB mode encryption
 322  */
 323 /* ARGSUSED */
 324 int
 325 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
 326 {
 327         int err = 0;
 328         struct desparams dp;
 329 
 330         dp.des_mode = ECB;
 331         err = common_crypt(key, buf, len, mode, &dp);
 332         return (err);
 333 }
 334 
 335 
 336 
 337 /*
 338  * Common code to cbc_crypt() & ecb_crypt()
 339  */
 340 static int
 341 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
 342     struct desparams *desp)
 343 {
 344         int desdev;
 345 
 346         if ((len % 8) != 0 || len > DES_MAXDATA)
 347                 return (DESERR_BADPARAM);
 348 
 349         desp->des_dir =
 350             ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
 351 
 352         desdev = mode & DES_DEVMASK;
 353         COPY8(key, desp->des_key);
 354 
 355 #ifdef sun_hardware
 356         if (desdev == DES_HW) {
 357                 int res;
 358 
 359                 if (g_desfd < 0 &&
 360                     (g_desfd == -1 || (g_desfd = getdesfd()) < 0))
 361                                 goto software;  /* no hardware device */
 362 
 363                 /*
 364                  * hardware
 365                  */
 366                 desp->des_len = len;
 367                 if (len <= DES_QUICKLEN) {
 368                         DESCOPY(buf, desp->des_data, len);
 369                         res = ioctl(g_desfd, DESIOCQUICK, (char *)desp);
 370                         DESCOPY(desp->des_data, buf, len);
 371                 } else {
 372                         desp->des_buf = (uchar_t *)buf;
 373                         res = ioctl(g_desfd, DESIOCBLOCK, (char *)desp);
 374                 }
 375                 return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
 376         }
 377 software:
 378 #endif
 379         /*
 380          * software
 381          */
 382         if (!_des_crypt(buf, len, desp))
 383                 return (DESERR_HWERROR);
 384 
 385         return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
 386 }
 387 
 388 /*
 389  * Initialize key schedules for DES and DES3
 390  */
 391 static int
 392 init_keysched(crypto_key_t *key, void *newbie, des_strength_t strength)
 393 {
 394         uint8_t corrected_key[DES3_KEYSIZE];
 395 
 396         /*
 397          * Only keys by value are supported by this module.
 398          */
 399         switch (key->ck_format) {
 400         case CRYPTO_KEY_RAW:
 401                 if (strength == DES && key->ck_length != DES_MAXBITS)
 402                         return (CRYPTO_KEY_SIZE_RANGE);
 403                 if (strength == DES3 && key->ck_length != DES3_MAXBITS)
 404                         return (CRYPTO_KEY_SIZE_RANGE);
 405                 break;
 406         default:
 407                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
 408         }
 409 
 410         /*
 411          * Fix parity bits.
 412          * Initialize key schedule even if key is weak.
 413          */
 414         if (key->ck_data == NULL)
 415                 return (CRYPTO_ARGUMENTS_BAD);
 416 
 417         des_parity_fix(key->ck_data, strength, corrected_key);
 418         des_init_keysched(corrected_key, strength, newbie);
 419         return (CRYPTO_SUCCESS);
 420 }
 421 
 422 /*
 423  * KCF software provider control entry points.
 424  */
 425 /* ARGSUSED */
 426 static void
 427 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
 428 {
 429         *status = CRYPTO_PROVIDER_READY;
 430 }
 431 
 432 /*
 433  * KCF software provider encrypt entry points.
 434  */
 435 static int
 436 des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
 437     crypto_key_t *key, crypto_spi_ctx_template_t template,
 438     crypto_req_handle_t req)
 439 {
 440 
 441         des_strength_t strength;
 442         des_ctx_t *des_ctx = NULL;
 443         int rv;
 444         int kmflag;
 445 
 446         /*
 447          * Only keys by value are supported by this module.
 448          */
 449         if (key->ck_format != CRYPTO_KEY_RAW) {
 450                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
 451         }
 452 
 453         kmflag = crypto_kmflag(req);
 454         /* Check mechanism type and parameter length */
 455         switch (mechanism->cm_type) {
 456         case DES_ECB_MECH_INFO_TYPE:
 457                 des_ctx = ecb_alloc_ctx(kmflag);
 458                 /* FALLTHRU */
 459         case DES_CBC_MECH_INFO_TYPE:
 460                 if (mechanism->cm_param != NULL &&
 461                     mechanism->cm_param_len != DES_BLOCK_LEN)
 462                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 463                 if (key->ck_length != DES_MAXBITS)
 464                         return (CRYPTO_KEY_SIZE_RANGE);
 465                 strength = DES;
 466                 if (des_ctx == NULL)
 467                         des_ctx = cbc_alloc_ctx(kmflag);
 468                 break;
 469         case DES3_ECB_MECH_INFO_TYPE:
 470                 des_ctx = ecb_alloc_ctx(kmflag);
 471                 /* FALLTHRU */
 472         case DES3_CBC_MECH_INFO_TYPE:
 473                 if (mechanism->cm_param != NULL &&
 474                     mechanism->cm_param_len != DES_BLOCK_LEN)
 475                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 476                 if (key->ck_length != DES3_MAXBITS)
 477                         return (CRYPTO_KEY_SIZE_RANGE);
 478                 strength = DES3;
 479                 if (des_ctx == NULL)
 480                         des_ctx = cbc_alloc_ctx(kmflag);
 481                 break;
 482         default:
 483                 return (CRYPTO_MECHANISM_INVALID);
 484         }
 485 
 486         if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
 487             strength, kmflag)) != CRYPTO_SUCCESS) {
 488                 crypto_free_mode_ctx(des_ctx);
 489                 return (rv);
 490         }
 491 
 492         ctx->cc_provider_private = des_ctx;
 493 
 494         return (CRYPTO_SUCCESS);
 495 }
 496 
 497 static void
 498 des_copy_block64(const uint8_t *in, uint64_t *out)
 499 {
 500         if (IS_P2ALIGNED(in, sizeof (uint64_t))) {
 501                 /* LINTED: pointer alignment */
 502                 out[0] = *(uint64_t *)&in[0];
 503         } else {
 504                 uint64_t tmp64;
 505 
 506 #ifdef _BIG_ENDIAN
 507                 tmp64 = (((uint64_t)in[0] << 56) |
 508                     ((uint64_t)in[1] << 48) |
 509                     ((uint64_t)in[2] << 40) |
 510                     ((uint64_t)in[3] << 32) |
 511                     ((uint64_t)in[4] << 24) |
 512                     ((uint64_t)in[5] << 16) |
 513                     ((uint64_t)in[6] << 8) |
 514                     (uint64_t)in[7]);
 515 #else
 516                 tmp64 = (((uint64_t)in[7] << 56) |
 517                     ((uint64_t)in[6] << 48) |
 518                     ((uint64_t)in[5] << 40) |
 519                     ((uint64_t)in[4] << 32) |
 520                     ((uint64_t)in[3] << 24) |
 521                     ((uint64_t)in[2] << 16) |
 522                     ((uint64_t)in[1] << 8) |
 523                     (uint64_t)in[0]);
 524 #endif /* _BIG_ENDIAN */
 525 
 526                 out[0] = tmp64;
 527         }
 528 }
 529 
 530 /* ARGSUSED */
 531 static int
 532 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 533     crypto_data_t *ciphertext, crypto_req_handle_t req)
 534 {
 535         int ret;
 536 
 537         des_ctx_t *des_ctx;
 538 
 539         /*
 540          * Plaintext must be a multiple of the block size.
 541          * This test only works for non-padded mechanisms
 542          * when blocksize is 2^N.
 543          */
 544         if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 545                 return (CRYPTO_DATA_LEN_RANGE);
 546 
 547         ASSERT(ctx->cc_provider_private != NULL);
 548         des_ctx = ctx->cc_provider_private;
 549 
 550         DES_ARG_INPLACE(plaintext, ciphertext);
 551 
 552         /*
 553          * We need to just return the length needed to store the output.
 554          * We should not destroy the context for the following case.
 555          */
 556         if (ciphertext->cd_length < plaintext->cd_length) {
 557                 ciphertext->cd_length = plaintext->cd_length;
 558                 return (CRYPTO_BUFFER_TOO_SMALL);
 559         }
 560 
 561         /*
 562          * Do an update on the specified input data.
 563          */
 564         ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
 565         ASSERT(des_ctx->dc_remainder_len == 0);
 566         (void) des_free_context(ctx);
 567 
 568         /* LINTED */
 569         return (ret);
 570 }
 571 
 572 /* ARGSUSED */
 573 static int
 574 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 575     crypto_data_t *plaintext, crypto_req_handle_t req)
 576 {
 577         int ret;
 578 
 579         des_ctx_t *des_ctx;
 580 
 581         /*
 582          * Ciphertext must be a multiple of the block size.
 583          * This test only works for non-padded mechanisms
 584          * when blocksize is 2^N.
 585          */
 586         if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 587                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 588 
 589         ASSERT(ctx->cc_provider_private != NULL);
 590         des_ctx = ctx->cc_provider_private;
 591 
 592         DES_ARG_INPLACE(ciphertext, plaintext);
 593 
 594         /*
 595          * We need to just return the length needed to store the output.
 596          * We should not destroy the context for the following case.
 597          */
 598         if (plaintext->cd_length < ciphertext->cd_length) {
 599                 plaintext->cd_length = ciphertext->cd_length;
 600                 return (CRYPTO_BUFFER_TOO_SMALL);
 601         }
 602 
 603         /*
 604          * Do an update on the specified input data.
 605          */
 606         ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
 607         ASSERT(des_ctx->dc_remainder_len == 0);
 608         (void) des_free_context(ctx);
 609 
 610         /* LINTED */
 611         return (ret);
 612 }
 613 
 614 /* ARGSUSED */
 615 static int
 616 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 617     crypto_data_t *ciphertext, crypto_req_handle_t req)
 618 {
 619         off_t saved_offset;
 620         size_t saved_length, out_len;
 621         int ret = CRYPTO_SUCCESS;
 622 
 623         ASSERT(ctx->cc_provider_private != NULL);
 624 
 625         DES_ARG_INPLACE(plaintext, ciphertext);
 626 
 627         /* compute number of bytes that will hold the ciphertext */
 628         out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 629         out_len += plaintext->cd_length;
 630         out_len &= ~(DES_BLOCK_LEN - 1);
 631 
 632         /* return length needed to store the output */
 633         if (ciphertext->cd_length < out_len) {
 634                 ciphertext->cd_length = out_len;
 635                 return (CRYPTO_BUFFER_TOO_SMALL);
 636         }
 637 
 638         saved_offset = ciphertext->cd_offset;
 639         saved_length = ciphertext->cd_length;
 640 
 641         /*
 642          * Do the DES update on the specified input data.
 643          */
 644         switch (plaintext->cd_format) {
 645         case CRYPTO_DATA_RAW:
 646                 ret = crypto_update_iov(ctx->cc_provider_private,
 647                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 648                     des_copy_block64);
 649                 break;
 650         case CRYPTO_DATA_UIO:
 651                 ret = crypto_update_uio(ctx->cc_provider_private,
 652                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 653                     des_copy_block64);
 654                 break;
 655         case CRYPTO_DATA_MBLK:
 656                 ret = crypto_update_mp(ctx->cc_provider_private,
 657                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 658                     des_copy_block64);
 659                 break;
 660         default:
 661                 ret = CRYPTO_ARGUMENTS_BAD;
 662         }
 663 
 664         if (ret == CRYPTO_SUCCESS) {
 665                 if (plaintext != ciphertext)
 666                         ciphertext->cd_length =
 667                             ciphertext->cd_offset - saved_offset;
 668         } else {
 669                 ciphertext->cd_length = saved_length;
 670         }
 671         ciphertext->cd_offset = saved_offset;
 672 
 673         return (ret);
 674 }
 675 
 676 /* ARGSUSED */
 677 static int
 678 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 679     crypto_data_t *plaintext, crypto_req_handle_t req)
 680 {
 681         off_t saved_offset;
 682         size_t saved_length, out_len;
 683         int ret = CRYPTO_SUCCESS;
 684 
 685         ASSERT(ctx->cc_provider_private != NULL);
 686 
 687         DES_ARG_INPLACE(ciphertext, plaintext);
 688 
 689         /* compute number of bytes that will hold the plaintext */
 690         out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
 691         out_len += ciphertext->cd_length;
 692         out_len &= ~(DES_BLOCK_LEN - 1);
 693 
 694         /* return length needed to store the output */
 695         if (plaintext->cd_length < out_len) {
 696                 plaintext->cd_length = out_len;
 697                 return (CRYPTO_BUFFER_TOO_SMALL);
 698         }
 699 
 700         saved_offset = plaintext->cd_offset;
 701         saved_length = plaintext->cd_length;
 702 
 703         /*
 704          * Do the DES update on the specified input data.
 705          */
 706         switch (ciphertext->cd_format) {
 707         case CRYPTO_DATA_RAW:
 708                 ret = crypto_update_iov(ctx->cc_provider_private,
 709                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 710                     des_copy_block64);
 711                 break;
 712         case CRYPTO_DATA_UIO:
 713                 ret = crypto_update_uio(ctx->cc_provider_private,
 714                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 715                     des_copy_block64);
 716                 break;
 717         case CRYPTO_DATA_MBLK:
 718                 ret = crypto_update_mp(ctx->cc_provider_private,
 719                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 720                     des_copy_block64);
 721                 break;
 722         default:
 723                 ret = CRYPTO_ARGUMENTS_BAD;
 724         }
 725 
 726         if (ret == CRYPTO_SUCCESS) {
 727                 if (ciphertext != plaintext)
 728                         plaintext->cd_length =
 729                             plaintext->cd_offset - saved_offset;
 730         } else {
 731                 plaintext->cd_length = saved_length;
 732         }
 733         plaintext->cd_offset = saved_offset;
 734 
 735         return (ret);
 736 }
 737 
 738 /* ARGSUSED */
 739 static int
 740 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
 741     crypto_req_handle_t req)
 742 {
 743         des_ctx_t *des_ctx;
 744 
 745         ASSERT(ctx->cc_provider_private != NULL);
 746         des_ctx = ctx->cc_provider_private;
 747 
 748         /*
 749          * There must be no unprocessed plaintext.
 750          * This happens if the length of the last data is
 751          * not a multiple of the DES block length.
 752          */
 753         if (des_ctx->dc_remainder_len > 0)
 754                 return (CRYPTO_DATA_LEN_RANGE);
 755 
 756         (void) des_free_context(ctx);
 757         ciphertext->cd_length = 0;
 758 
 759         return (CRYPTO_SUCCESS);
 760 }
 761 
 762 /* ARGSUSED */
 763 static int
 764 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
 765     crypto_req_handle_t req)
 766 {
 767         des_ctx_t *des_ctx;
 768 
 769         ASSERT(ctx->cc_provider_private != NULL);
 770         des_ctx = ctx->cc_provider_private;
 771 
 772         /*
 773          * There must be no unprocessed ciphertext.
 774          * This happens if the length of the last ciphertext is
 775          * not a multiple of the DES block length.
 776          */
 777         if (des_ctx->dc_remainder_len > 0)
 778                 return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
 779 
 780         (void) des_free_context(ctx);
 781         plaintext->cd_length = 0;
 782 
 783         return (CRYPTO_SUCCESS);
 784 }
 785 
 786 /* ARGSUSED */
 787 static int
 788 des_encrypt_atomic(crypto_provider_handle_t provider,
 789     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 790     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
 791     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 792 {
 793         int ret;
 794 
 795         des_ctx_t des_ctx;              /* on the stack */
 796         des_strength_t strength;
 797         off_t saved_offset;
 798         size_t saved_length;
 799 
 800         DES_ARG_INPLACE(plaintext, ciphertext);
 801 
 802         /*
 803          * Plaintext must be a multiple of the block size.
 804          * This test only works for non-padded mechanisms
 805          * when blocksize is 2^N.
 806          */
 807         if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 808                 return (CRYPTO_DATA_LEN_RANGE);
 809 
 810         /* return length needed to store the output */
 811         if (ciphertext->cd_length < plaintext->cd_length) {
 812                 ciphertext->cd_length = plaintext->cd_length;
 813                 return (CRYPTO_BUFFER_TOO_SMALL);
 814         }
 815 
 816         /* Check mechanism type and parameter length */
 817         switch (mechanism->cm_type) {
 818         case DES_ECB_MECH_INFO_TYPE:
 819         case DES_CBC_MECH_INFO_TYPE:
 820                 if (mechanism->cm_param_len > 0 &&
 821                     mechanism->cm_param_len != DES_BLOCK_LEN)
 822                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 823                 if (key->ck_length != DES_MINBITS)
 824                         return (CRYPTO_KEY_SIZE_RANGE);
 825                 strength = DES;
 826                 break;
 827         case DES3_ECB_MECH_INFO_TYPE:
 828         case DES3_CBC_MECH_INFO_TYPE:
 829                 if (mechanism->cm_param_len > 0 &&
 830                     mechanism->cm_param_len != DES_BLOCK_LEN)
 831                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 832                 if (key->ck_length != DES3_MAXBITS)
 833                         return (CRYPTO_KEY_SIZE_RANGE);
 834                 strength = DES3;
 835                 break;
 836         default:
 837                 return (CRYPTO_MECHANISM_INVALID);
 838         }
 839 
 840         bzero(&des_ctx, sizeof (des_ctx_t));
 841 
 842         if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
 843             strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
 844                 return (ret);
 845         }
 846 
 847         saved_offset = ciphertext->cd_offset;
 848         saved_length = ciphertext->cd_length;
 849 
 850         /*
 851          * Do the update on the specified input data.
 852          */
 853         switch (plaintext->cd_format) {
 854         case CRYPTO_DATA_RAW:
 855                 ret = crypto_update_iov(&des_ctx, plaintext, ciphertext,
 856                     des_encrypt_contiguous_blocks, des_copy_block64);
 857                 break;
 858         case CRYPTO_DATA_UIO:
 859                 ret = crypto_update_uio(&des_ctx, plaintext, ciphertext,
 860                     des_encrypt_contiguous_blocks, des_copy_block64);
 861                 break;
 862         case CRYPTO_DATA_MBLK:
 863                 ret = crypto_update_mp(&des_ctx, plaintext, ciphertext,
 864                     des_encrypt_contiguous_blocks, des_copy_block64);
 865                 break;
 866         default:
 867                 ret = CRYPTO_ARGUMENTS_BAD;
 868         }
 869 
 870         if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
 871                 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 872                 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 873         }
 874 
 875         if (ret == CRYPTO_SUCCESS) {
 876                 ASSERT(des_ctx.dc_remainder_len == 0);
 877                 if (plaintext != ciphertext)
 878                         ciphertext->cd_length =
 879                             ciphertext->cd_offset - saved_offset;
 880         } else {
 881                 ciphertext->cd_length = saved_length;
 882         }
 883         ciphertext->cd_offset = saved_offset;
 884 
 885         /* LINTED */
 886         return (ret);
 887 }
 888 
 889 /* ARGSUSED */
 890 static int
 891 des_decrypt_atomic(crypto_provider_handle_t provider,
 892     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
 893     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
 894     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
 895 {
 896         int ret;
 897 
 898         des_ctx_t des_ctx;      /* on the stack */
 899         des_strength_t strength;
 900         off_t saved_offset;
 901         size_t saved_length;
 902 
 903         DES_ARG_INPLACE(ciphertext, plaintext);
 904 
 905         /*
 906          * Ciphertext must be a multiple of the block size.
 907          * This test only works for non-padded mechanisms
 908          * when blocksize is 2^N.
 909          */
 910         if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
 911                 return (CRYPTO_DATA_LEN_RANGE);
 912 
 913         /* return length needed to store the output */
 914         if (plaintext->cd_length < ciphertext->cd_length) {
 915                 plaintext->cd_length = ciphertext->cd_length;
 916                 return (CRYPTO_BUFFER_TOO_SMALL);
 917         }
 918 
 919         /* Check mechanism type and parameter length */
 920         switch (mechanism->cm_type) {
 921         case DES_ECB_MECH_INFO_TYPE:
 922         case DES_CBC_MECH_INFO_TYPE:
 923                 if (mechanism->cm_param_len > 0 &&
 924                     mechanism->cm_param_len != DES_BLOCK_LEN)
 925                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 926                 if (key->ck_length != DES_MINBITS)
 927                         return (CRYPTO_KEY_SIZE_RANGE);
 928                 strength = DES;
 929                 break;
 930         case DES3_ECB_MECH_INFO_TYPE:
 931         case DES3_CBC_MECH_INFO_TYPE:
 932                 if (mechanism->cm_param_len > 0 &&
 933                     mechanism->cm_param_len != DES_BLOCK_LEN)
 934                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 935                 if (key->ck_length != DES3_MAXBITS)
 936                         return (CRYPTO_KEY_SIZE_RANGE);
 937                 strength = DES3;
 938                 break;
 939         default:
 940                 return (CRYPTO_MECHANISM_INVALID);
 941         }
 942 
 943         bzero(&des_ctx, sizeof (des_ctx_t));
 944 
 945         if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
 946             strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
 947                 return (ret);
 948         }
 949 
 950         saved_offset = plaintext->cd_offset;
 951         saved_length = plaintext->cd_length;
 952 
 953         /*
 954          * Do the update on the specified input data.
 955          */
 956         switch (ciphertext->cd_format) {
 957         case CRYPTO_DATA_RAW:
 958                 ret = crypto_update_iov(&des_ctx, ciphertext, plaintext,
 959                     des_decrypt_contiguous_blocks, des_copy_block64);
 960                 break;
 961         case CRYPTO_DATA_UIO:
 962                 ret = crypto_update_uio(&des_ctx, ciphertext, plaintext,
 963                     des_decrypt_contiguous_blocks, des_copy_block64);
 964                 break;
 965         case CRYPTO_DATA_MBLK:
 966                 ret = crypto_update_mp(&des_ctx, ciphertext, plaintext,
 967                     des_decrypt_contiguous_blocks, des_copy_block64);
 968                 break;
 969         default:
 970                 ret = CRYPTO_ARGUMENTS_BAD;
 971         }
 972 
 973         if (des_ctx.dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
 974                 bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 975                 kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
 976         }
 977 
 978         if (ret == CRYPTO_SUCCESS) {
 979                 ASSERT(des_ctx.dc_remainder_len == 0);
 980                 if (ciphertext != plaintext)
 981                         plaintext->cd_length =
 982                             plaintext->cd_offset - saved_offset;
 983         } else {
 984                 plaintext->cd_length = saved_length;
 985         }
 986         plaintext->cd_offset = saved_offset;
 987 
 988         /* LINTED */
 989         return (ret);
 990 }
 991 
 992 /*
 993  * KCF software provider context template entry points.
 994  */
 995 /* ARGSUSED */
 996 static int
 997 des_create_ctx_template(crypto_provider_handle_t provider,
 998     crypto_mechanism_t *mechanism, crypto_key_t *key,
 999     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1000 {
1001 
1002         des_strength_t strength;
1003         void *keysched;
1004         size_t size;
1005         int rv;
1006 
1007         switch (mechanism->cm_type) {
1008         case DES_ECB_MECH_INFO_TYPE:
1009                 strength = DES;
1010                 break;
1011         case DES_CBC_MECH_INFO_TYPE:
1012                 strength = DES;
1013                 break;
1014         case DES3_ECB_MECH_INFO_TYPE:
1015                 strength = DES3;
1016                 break;
1017         case DES3_CBC_MECH_INFO_TYPE:
1018                 strength = DES3;
1019                 break;
1020         default:
1021                 return (CRYPTO_MECHANISM_INVALID);
1022         }
1023 
1024         if ((keysched = des_alloc_keysched(&size, strength,
1025             crypto_kmflag(req))) == NULL) {
1026                 return (CRYPTO_HOST_MEMORY);
1027         }
1028 
1029         /*
1030          * Initialize key schedule.  Key length information is stored
1031          * in the key.
1032          */
1033         if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1034                 bzero(keysched, size);
1035                 kmem_free(keysched, size);
1036                 return (rv);
1037         }
1038 
1039         *tmpl = keysched;
1040         *tmpl_size = size;
1041 
1042         return (CRYPTO_SUCCESS);
1043 }
1044 
1045 /* ARGSUSED */
1046 static int
1047 des_free_context(crypto_ctx_t *ctx)
1048 {
1049         des_ctx_t *des_ctx = ctx->cc_provider_private;
1050 
1051         if (des_ctx != NULL) {
1052                 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1053                         ASSERT(des_ctx->dc_keysched_len != 0);
1054                         bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1055                         kmem_free(des_ctx->dc_keysched,
1056                             des_ctx->dc_keysched_len);
1057                 }
1058                 crypto_free_mode_ctx(des_ctx);
1059                 ctx->cc_provider_private = NULL;
1060         }
1061 
1062         return (CRYPTO_SUCCESS);
1063 }
1064 
1065 /*
1066  * Pass it to des_keycheck() which will
1067  * fix it (parity bits), and check if the fixed key is weak.
1068  */
1069 /* ARGSUSED */
1070 static int
1071 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1072     crypto_key_t *key)
1073 {
1074         int expectedkeylen;
1075         des_strength_t strength;
1076         uint8_t keydata[DES3_MAX_KEY_LEN];
1077 
1078         if ((mech == NULL) || (key == NULL))
1079                 return (CRYPTO_ARGUMENTS_BAD);
1080 
1081         switch (mech->cm_type) {
1082         case DES_ECB_MECH_INFO_TYPE:
1083         case DES_CBC_MECH_INFO_TYPE:
1084                 expectedkeylen = DES_MINBITS;
1085                 strength = DES;
1086                 break;
1087         case DES3_ECB_MECH_INFO_TYPE:
1088         case DES3_CBC_MECH_INFO_TYPE:
1089                 expectedkeylen = DES3_MAXBITS;
1090                 strength = DES3;
1091                 break;
1092         default:
1093                 return (CRYPTO_MECHANISM_INVALID);
1094         }
1095 
1096         if (key->ck_format != CRYPTO_KEY_RAW)
1097                 return (CRYPTO_KEY_TYPE_INCONSISTENT);
1098 
1099         if (key->ck_length != expectedkeylen)
1100                 return (CRYPTO_KEY_SIZE_RANGE);
1101 
1102         bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1103 
1104         if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1105                 return (CRYPTO_WEAK_KEY);
1106 
1107         return (CRYPTO_SUCCESS);
1108 }
1109 
1110 /* ARGSUSED */
1111 static int
1112 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1113     crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1114     int kmflag)
1115 {
1116         int rv = CRYPTO_SUCCESS;
1117 
1118         void *keysched;
1119         size_t size;
1120 
1121         if (template == NULL) {
1122                 if ((keysched = des_alloc_keysched(&size, strength,
1123                     kmflag)) == NULL)
1124                         return (CRYPTO_HOST_MEMORY);
1125                 /*
1126                  * Initialize key schedule.
1127                  * Key length is stored in the key.
1128                  */
1129                 if ((rv = init_keysched(key, keysched,
1130                     strength)) != CRYPTO_SUCCESS)
1131                         kmem_free(keysched, size);
1132 
1133                 des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE;
1134                 des_ctx->dc_keysched_len = size;
1135         } else {
1136                 keysched = template;
1137         }
1138         des_ctx->dc_keysched = keysched;
1139 
1140         if (strength == DES3) {
1141                 des_ctx->dc_flags |= DES3_STRENGTH;
1142         }
1143 
1144         switch (mechanism->cm_type) {
1145         case DES_CBC_MECH_INFO_TYPE:
1146         case DES3_CBC_MECH_INFO_TYPE:
1147                 rv = cbc_init_ctx((cbc_ctx_t *)des_ctx, mechanism->cm_param,
1148                     mechanism->cm_param_len, DES_BLOCK_LEN, des_copy_block64);
1149                 break;
1150         case DES_ECB_MECH_INFO_TYPE:
1151         case DES3_ECB_MECH_INFO_TYPE:
1152                 des_ctx->dc_flags |= ECB_MODE;
1153         }
1154 
1155         if (rv != CRYPTO_SUCCESS) {
1156                 if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) {
1157                         bzero(keysched, size);
1158                         kmem_free(keysched, size);
1159                 }
1160         }
1161 
1162         return (rv);
1163 }