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