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 #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  */
 122 static crypto_mech_info_t des_mech_info_tab[] = {
 123         /* DES_ECB */
 124         {SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
 125             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 126             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 127             DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
 128         /* DES_CBC */
 129         {SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
 130             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 131             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 132             DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
 133         /* DES3_ECB */
 134         {SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
 135             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 136             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 137             DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
 138         /* DES3_CBC */
 139         {SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
 140             CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
 141             CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
 142             DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
 143 };
 144 
 145 /* operations are in-place if the output buffer is NULL */
 146 #define DES_ARG_INPLACE(input, output)                          \
 147         if ((output) == NULL)                                   \
 148                 (output) = (input);
 149 
 150 static void des_provider_status(crypto_provider_handle_t, uint_t *);
 151 
 152 static crypto_control_ops_t des_control_ops = {
 153         des_provider_status
 154 };
 155 
 156 static int
 157 des_common_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
 158     crypto_spi_ctx_template_t, crypto_req_handle_t);
 159 static int des_common_init_ctx(des_ctx_t *, crypto_spi_ctx_template_t *,
 160     crypto_mechanism_t *, crypto_key_t *, des_strength_t, int);
 161 static int des_encrypt_final(crypto_ctx_t *, crypto_data_t *,
 162     crypto_req_handle_t);
 163 static int des_decrypt_final(crypto_ctx_t *, crypto_data_t *,
 164     crypto_req_handle_t);
 165 
 166 static int des_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
 167     crypto_req_handle_t);
 168 static int des_encrypt_update(crypto_ctx_t *, crypto_data_t *,
 169     crypto_data_t *, crypto_req_handle_t);
 170 static int des_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
 171     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
 172     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
 173 
 174 static int des_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
 175     crypto_req_handle_t);
 176 static int des_decrypt_update(crypto_ctx_t *, crypto_data_t *,
 177     crypto_data_t *, crypto_req_handle_t);
 178 static int des_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
 179     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
 180     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
 181 
 182 static crypto_cipher_ops_t des_cipher_ops = {
 183         des_common_init,
 184         des_encrypt,
 185         des_encrypt_update,
 186         des_encrypt_final,
 187         des_encrypt_atomic,
 188         des_common_init,
 189         des_decrypt,
 190         des_decrypt_update,
 191         des_decrypt_final,
 192         des_decrypt_atomic
 193 };
 194 
 195 static int des_create_ctx_template(crypto_provider_handle_t,
 196     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
 197     size_t *, crypto_req_handle_t);
 198 static int des_free_context(crypto_ctx_t *);
 199 
 200 static crypto_ctx_ops_t des_ctx_ops = {
 201         des_create_ctx_template,
 202         des_free_context
 203 };
 204 
 205 static int des_key_check(crypto_provider_handle_t, crypto_mechanism_t *,
 206     crypto_key_t *);
 207 
 208 static crypto_key_ops_t des_key_ops = {
 209         NULL,
 210         NULL,
 211         NULL,
 212         NULL,
 213         NULL,
 214         des_key_check
 215 };
 216 
 217 static crypto_ops_t des_crypto_ops = {
 218         &des_control_ops,
 219         NULL,
 220         &des_cipher_ops,
 221         NULL,
 222         NULL,
 223         NULL,
 224         NULL,
 225         NULL,
 226         NULL,
 227         NULL,
 228         NULL,
 229         &des_key_ops,
 230         NULL,
 231         &des_ctx_ops,
 232         NULL,
 233         NULL,
 234         NULL
 235 };
 236 
 237 static crypto_provider_info_t des_prov_info = {
 238         CRYPTO_SPI_VERSION_4,
 239         "DES Software Provider",
 240         CRYPTO_SW_PROVIDER,
 241         {&modlinkage},
 242         NULL,
 243         &des_crypto_ops,
 244         sizeof (des_mech_info_tab)/sizeof (crypto_mech_info_t),
 245         des_mech_info_tab
 246 };
 247 
 248 static crypto_kcf_provider_handle_t des_prov_handle = NULL;
 249 
 250 int
 251 _init(void)
 252 {
 253         int ret;
 254 
 255         if ((ret = mod_install(&modlinkage)) != 0)
 256                 return (ret);
 257 
 258         /*
 259          * Register with KCF. If the registration fails, kcf will log an
 260          * error but do not uninstall the module, since the functionality
 261          * provided by misc/des should still be available.
 262          *
 263          */
 264         (void) crypto_register_provider(&des_prov_info, &des_prov_handle);
 265 
 266         return (0);
 267 }
 268 
 269 
 270 int
 271 _info(struct modinfo *modinfop)
 272 {
 273         return (mod_info(&modlinkage, modinfop));
 274 }
 275 
 276 /*
 277  * Copy 8 bytes
 278  */
 279 #define COPY8(src, dst) { \
 280         char *a = (char *)dst; \
 281         char *b = (char *)src; \
 282         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 283         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
 284 }
 285 
 286 /*
 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) {
 354                 int res;
 355 
 356                 if (g_desfd < 0 &&
 357                     (g_desfd == -1 || (g_desfd = getdesfd()) < 0))
 358                                 goto software;  /* no hardware device */
 359 
 360                 /*
 361                  * hardware
 362                  */
 363                 desp->des_len = len;
 364                 if (len <= DES_QUICKLEN) {
 365                         DESCOPY(buf, desp->des_data, len);
 366                         res = ioctl(g_desfd, DESIOCQUICK, (char *)desp);
 367                         DESCOPY(desp->des_data, buf, len);
 368                 } else {
 369                         desp->des_buf = (uchar_t *)buf;
 370                         res = ioctl(g_desfd, DESIOCBLOCK, (char *)desp);
 371                 }
 372                 return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
 373         }
 374 software:
 375 #endif
 376         /*
 377          * software
 378          */
 379         if (!_des_crypt(buf, len, desp))
 380                 return (DESERR_HWERROR);
 381 
 382         return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
 383 }
 384 
 385 /*
 386  * Initialize key schedules for DES and DES3
 387  */
 388 static int
 389 init_keysched(crypto_key_t *key, void *newbie, des_strength_t strength)
 390 {
 391         uint8_t corrected_key[DES3_KEYSIZE];
 392 
 393         /*
 394          * Only keys by value are supported by this module.
 395          */
 396         switch (key->ck_format) {
 397         case CRYPTO_KEY_RAW:
 398                 if (strength == DES && key->ck_length != DES_MAXBITS)
 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 &&
 458                     mechanism->cm_param_len != DES_BLOCK_LEN)
 459                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 460                 if (key->ck_length != DES_MAXBITS)
 461                         return (CRYPTO_KEY_SIZE_RANGE);
 462                 strength = DES;
 463                 if (des_ctx == NULL)
 464                         des_ctx = cbc_alloc_ctx(kmflag);
 465                 break;
 466         case DES3_ECB_MECH_INFO_TYPE:
 467                 des_ctx = ecb_alloc_ctx(kmflag);
 468                 /* FALLTHRU */
 469         case DES3_CBC_MECH_INFO_TYPE:
 470                 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) |
 511                     (uint64_t)in[7]);
 512 #else
 513                 tmp64 = (((uint64_t)in[7] << 56) |
 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.
 640          */
 641         switch (plaintext->cd_format) {
 642         case CRYPTO_DATA_RAW:
 643                 ret = crypto_update_iov(ctx->cc_provider_private,
 644                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 645                     des_copy_block64);
 646                 break;
 647         case CRYPTO_DATA_UIO:
 648                 ret = crypto_update_uio(ctx->cc_provider_private,
 649                     plaintext, ciphertext, des_encrypt_contiguous_blocks,
 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.
 702          */
 703         switch (ciphertext->cd_format) {
 704         case CRYPTO_DATA_RAW:
 705                 ret = crypto_update_iov(ctx->cc_provider_private,
 706                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 707                     des_copy_block64);
 708                 break;
 709         case CRYPTO_DATA_UIO:
 710                 ret = crypto_update_uio(ctx->cc_provider_private,
 711                     ciphertext, plaintext, des_decrypt_contiguous_blocks,
 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         }
 812 
 813         /* Check mechanism type and parameter length */
 814         switch (mechanism->cm_type) {
 815         case DES_ECB_MECH_INFO_TYPE:
 816         case DES_CBC_MECH_INFO_TYPE:
 817                 if (mechanism->cm_param_len > 0 &&
 818                     mechanism->cm_param_len != DES_BLOCK_LEN)
 819                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 820                 if (key->ck_length != DES_MINBITS)
 821                         return (CRYPTO_KEY_SIZE_RANGE);
 822                 strength = DES;
 823                 break;
 824         case DES3_ECB_MECH_INFO_TYPE:
 825         case DES3_CBC_MECH_INFO_TYPE:
 826                 if (mechanism->cm_param_len > 0 &&
 827                     mechanism->cm_param_len != DES_BLOCK_LEN)
 828                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 829                 if (key->ck_length != DES3_MAXBITS)
 830                         return (CRYPTO_KEY_SIZE_RANGE);
 831                 strength = DES3;
 832                 break;
 833         default:
 834                 return (CRYPTO_MECHANISM_INVALID);
 835         }
 836 
 837         bzero(&des_ctx, sizeof (des_ctx_t));
 838 
 839         if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
 840             strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
 841                 return (ret);
 842         }
 843 
 844         saved_offset = ciphertext->cd_offset;
 845         saved_length = ciphertext->cd_length;
 846 
 847         /*
 848          * Do the update on the specified input data.
 849          */
 850         switch (plaintext->cd_format) {
 851         case CRYPTO_DATA_RAW:
 852                 ret = crypto_update_iov(&des_ctx, plaintext, ciphertext,
 853                     des_encrypt_contiguous_blocks, des_copy_block64);
 854                 break;
 855         case CRYPTO_DATA_UIO:
 856                 ret = crypto_update_uio(&des_ctx, plaintext, ciphertext,
 857                     des_encrypt_contiguous_blocks, des_copy_block64);
 858                 break;
 859         case CRYPTO_DATA_MBLK:
 860                 ret = crypto_update_mp(&des_ctx, plaintext, ciphertext,
 861                     des_encrypt_contiguous_blocks, des_copy_block64);
 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         }
 915 
 916         /* Check mechanism type and parameter length */
 917         switch (mechanism->cm_type) {
 918         case DES_ECB_MECH_INFO_TYPE:
 919         case DES_CBC_MECH_INFO_TYPE:
 920                 if (mechanism->cm_param_len > 0 &&
 921                     mechanism->cm_param_len != DES_BLOCK_LEN)
 922                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 923                 if (key->ck_length != DES_MINBITS)
 924                         return (CRYPTO_KEY_SIZE_RANGE);
 925                 strength = DES;
 926                 break;
 927         case DES3_ECB_MECH_INFO_TYPE:
 928         case DES3_CBC_MECH_INFO_TYPE:
 929                 if (mechanism->cm_param_len > 0 &&
 930                     mechanism->cm_param_len != DES_BLOCK_LEN)
 931                         return (CRYPTO_MECHANISM_PARAM_INVALID);
 932                 if (key->ck_length != DES3_MAXBITS)
 933                         return (CRYPTO_KEY_SIZE_RANGE);
 934                 strength = DES3;
 935                 break;
 936         default:
 937                 return (CRYPTO_MECHANISM_INVALID);
 938         }
 939 
 940         bzero(&des_ctx, sizeof (des_ctx_t));
 941 
 942         if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
 943             strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
 944                 return (ret);
 945         }
 946 
 947         saved_offset = plaintext->cd_offset;
 948         saved_length = plaintext->cd_length;
 949 
 950         /*
 951          * Do the update on the specified input data.
 952          */
 953         switch (ciphertext->cd_format) {
 954         case CRYPTO_DATA_RAW:
 955                 ret = crypto_update_iov(&des_ctx, ciphertext, plaintext,
 956                     des_decrypt_contiguous_blocks, des_copy_block64);
 957                 break;
 958         case CRYPTO_DATA_UIO:
 959                 ret = crypto_update_uio(&des_ctx, ciphertext, plaintext,
 960                     des_decrypt_contiguous_blocks, des_copy_block64);
 961                 break;
 962         case CRYPTO_DATA_MBLK:
 963                 ret = crypto_update_mp(&des_ctx, ciphertext, plaintext,
 964                     des_decrypt_contiguous_blocks, des_copy_block64);
 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         }
1135         des_ctx->dc_keysched = keysched;
1136 
1137         if (strength == DES3) {
1138                 des_ctx->dc_flags |= DES3_STRENGTH;
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 }