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