xref: /illumos-gate/usr/src/uts/common/des/des_crypt.c (revision fbd1c0dae6f4a2ccc2ce0527c7f19d3dd5ea90b8)
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 2006 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 <des_impl.h>
51 #include <des_cbc_crypt.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 %I%"
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;
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 	/* Check mechanism type and parameter length */
477 	switch (mechanism->cm_type) {
478 	case DES_ECB_MECH_INFO_TYPE:
479 	case DES_CBC_MECH_INFO_TYPE:
480 		if (mechanism->cm_param != NULL &&
481 		    mechanism->cm_param_len != DES_BLOCK_LEN)
482 			return (CRYPTO_MECHANISM_PARAM_INVALID);
483 		if (key->ck_length != DES_MINBITS)
484 			return (CRYPTO_KEY_SIZE_RANGE);
485 		strength = DES;
486 		break;
487 	case DES3_ECB_MECH_INFO_TYPE:
488 	case DES3_CBC_MECH_INFO_TYPE:
489 		if (mechanism->cm_param != NULL &&
490 		    mechanism->cm_param_len != DES_BLOCK_LEN)
491 			return (CRYPTO_MECHANISM_PARAM_INVALID);
492 		if (key->ck_length != DES3_MINBITS)
493 			return (CRYPTO_KEY_SIZE_RANGE);
494 		strength = DES3;
495 		break;
496 	default:
497 		return (CRYPTO_MECHANISM_INVALID);
498 	}
499 
500 	/*
501 	 * Allocate a context.  Same context is used for DES and DES3.
502 	 */
503 	kmflag = crypto_kmflag(req);
504 	if ((des_ctx = kmem_zalloc(sizeof (des_ctx_t), kmflag)) == NULL)
505 		return (CRYPTO_HOST_MEMORY);
506 
507 	if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
508 	    strength, kmflag)) != CRYPTO_SUCCESS) {
509 		kmem_free(des_ctx, sizeof (des_ctx_t));
510 		return (rv);
511 	}
512 
513 	ctx->cc_provider_private = des_ctx;
514 
515 /* EXPORT DELETE END */
516 
517 	return (CRYPTO_SUCCESS);
518 }
519 
520 /*
521  * Helper DES encrypt update function for iov input data.
522  */
523 static int
524 des_cipher_update_iov(des_ctx_t *des_ctx, crypto_data_t *input,
525     crypto_data_t *output, int (*cipher)(des_ctx_t *, caddr_t, size_t,
526     crypto_data_t *))
527 {
528 	if (input->cd_miscdata != NULL) {
529 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
530 			/* LINTED: pointer alignment */
531 			des_ctx->dc_iv = *(uint64_t *)input->cd_miscdata;
532 		} else {
533 			uint64_t tmp64;
534 			uint8_t *tmp = (uint8_t *)input->cd_miscdata;
535 
536 #ifdef _BIG_ENDIAN
537 			tmp64 = (((uint64_t)tmp[0] << 56) |
538 			    ((uint64_t)tmp[1] << 48) |
539 			    ((uint64_t)tmp[2] << 40) |
540 			    ((uint64_t)tmp[3] << 32) |
541 			    ((uint64_t)tmp[4] << 24) |
542 			    ((uint64_t)tmp[5] << 16) |
543 			    ((uint64_t)tmp[6] << 8) |
544 			    (uint64_t)tmp[7]);
545 #else
546 			tmp64 = (((uint64_t)tmp[7] << 56) |
547 			    ((uint64_t)tmp[6] << 48) |
548 			    ((uint64_t)tmp[5] << 40) |
549 			    ((uint64_t)tmp[4] << 32) |
550 			    ((uint64_t)tmp[3] << 24) |
551 			    ((uint64_t)tmp[2] << 16) |
552 			    ((uint64_t)tmp[1] << 8) |
553 			    (uint64_t)tmp[0]);
554 #endif /* _BIG_ENDIAN */
555 
556 			des_ctx->dc_iv = tmp64;
557 		}
558 	}
559 
560 	if (input->cd_raw.iov_len < input->cd_length)
561 		return (CRYPTO_ARGUMENTS_BAD);
562 
563 	return ((cipher)(des_ctx, input->cd_raw.iov_base + input->cd_offset,
564 	    input->cd_length, (input == output) ? NULL : output));
565 }
566 
567 /*
568  * Helper DES encrypt update function for uio input data.
569  */
570 static int
571 des_cipher_update_uio(des_ctx_t *des_ctx, crypto_data_t *input,
572     crypto_data_t *output, int (*cipher)(des_ctx_t *, caddr_t, size_t,
573     crypto_data_t *))
574 {
575 	uio_t *uiop = input->cd_uio;
576 	off_t offset = input->cd_offset;
577 	size_t length = input->cd_length;
578 	uint_t vec_idx;
579 	size_t cur_len;
580 
581 	if (input->cd_miscdata != NULL) {
582 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
583 			/* LINTED: pointer alignment */
584 			des_ctx->dc_iv = *(uint64_t *)input->cd_miscdata;
585 		} else {
586 			uint64_t tmp64;
587 			uint8_t *tmp = (uint8_t *)input->cd_miscdata;
588 
589 #ifdef _BIG_ENDIAN
590 			tmp64 = (((uint64_t)tmp[0] << 56) |
591 			    ((uint64_t)tmp[1] << 48) |
592 			    ((uint64_t)tmp[2] << 40) |
593 			    ((uint64_t)tmp[3] << 32) |
594 			    ((uint64_t)tmp[4] << 24) |
595 			    ((uint64_t)tmp[5] << 16) |
596 			    ((uint64_t)tmp[6] << 8) |
597 			    (uint64_t)tmp[7]);
598 #else
599 			tmp64 = (((uint64_t)tmp[7] << 56) |
600 			    ((uint64_t)tmp[6] << 48) |
601 			    ((uint64_t)tmp[5] << 40) |
602 			    ((uint64_t)tmp[4] << 32) |
603 			    ((uint64_t)tmp[3] << 24) |
604 			    ((uint64_t)tmp[2] << 16) |
605 			    ((uint64_t)tmp[1] << 8) |
606 			    (uint64_t)tmp[0]);
607 #endif /* _BIG_ENDIAN */
608 
609 			des_ctx->dc_iv = tmp64;
610 		}
611 	}
612 
613 	if (input->cd_uio->uio_segflg != UIO_SYSSPACE) {
614 		return (CRYPTO_ARGUMENTS_BAD);
615 	}
616 
617 	/*
618 	 * Jump to the first iovec containing data to be
619 	 * processed.
620 	 */
621 	for (vec_idx = 0; vec_idx < uiop->uio_iovcnt &&
622 	    offset >= uiop->uio_iov[vec_idx].iov_len;
623 	    offset -= uiop->uio_iov[vec_idx++].iov_len);
624 	if (vec_idx == uiop->uio_iovcnt) {
625 		/*
626 		 * The caller specified an offset that is larger than the
627 		 * total size of the buffers it provided.
628 		 */
629 		return (CRYPTO_DATA_LEN_RANGE);
630 	}
631 
632 	/*
633 	 * Now process the iovecs.
634 	 */
635 	while (vec_idx < uiop->uio_iovcnt && length > 0) {
636 		cur_len = MIN(uiop->uio_iov[vec_idx].iov_len -
637 		    offset, length);
638 
639 		(cipher)(des_ctx, uiop->uio_iov[vec_idx].iov_base + offset,
640 		    cur_len, (input == output) ? NULL : output);
641 
642 		length -= cur_len;
643 		vec_idx++;
644 		offset = 0;
645 	}
646 
647 	if (vec_idx == uiop->uio_iovcnt && length > 0) {
648 		/*
649 		 * The end of the specified iovec's was reached but
650 		 * the length requested could not be processed, i.e.
651 		 * The caller requested to digest more data than it provided.
652 		 */
653 
654 		return (CRYPTO_DATA_LEN_RANGE);
655 	}
656 
657 	return (CRYPTO_SUCCESS);
658 }
659 
660 /*
661  * Helper DES encrypt update function for mblk input data.
662  */
663 static int
664 des_cipher_update_mp(des_ctx_t *des_ctx, crypto_data_t *input,
665     crypto_data_t *output, int (*cipher)(des_ctx_t *, caddr_t, size_t,
666     crypto_data_t *))
667 {
668 	off_t offset = input->cd_offset;
669 	size_t length = input->cd_length;
670 	mblk_t *mp;
671 	size_t cur_len;
672 
673 	if (input->cd_miscdata != NULL) {
674 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
675 			/* LINTED: pointer alignment */
676 			des_ctx->dc_iv = *(uint64_t *)input->cd_miscdata;
677 		} else {
678 			uint64_t tmp64;
679 			uint8_t *tmp = (uint8_t *)input->cd_miscdata;
680 
681 #ifdef _BIG_ENDIAN
682 			tmp64 = (((uint64_t)tmp[0] << 56) |
683 			    ((uint64_t)tmp[1] << 48) |
684 			    ((uint64_t)tmp[2] << 40) |
685 			    ((uint64_t)tmp[3] << 32) |
686 			    ((uint64_t)tmp[4] << 24) |
687 			    ((uint64_t)tmp[5] << 16) |
688 			    ((uint64_t)tmp[6] << 8) |
689 			    (uint64_t)tmp[7]);
690 #else
691 			tmp64 = (((uint64_t)tmp[7] << 56) |
692 			    ((uint64_t)tmp[6] << 48) |
693 			    ((uint64_t)tmp[5] << 40) |
694 			    ((uint64_t)tmp[4] << 32) |
695 			    ((uint64_t)tmp[3] << 24) |
696 			    ((uint64_t)tmp[2] << 16) |
697 			    ((uint64_t)tmp[1] << 8) |
698 			    (uint64_t)tmp[0]);
699 #endif /* _BIG_ENDIAN */
700 
701 			des_ctx->dc_iv = tmp64;
702 		}
703 	}
704 
705 	/*
706 	 * Jump to the first mblk_t containing data to be processed.
707 	 */
708 	for (mp = input->cd_mp; mp != NULL && offset >= MBLKL(mp);
709 	    offset -= MBLKL(mp), mp = mp->b_cont);
710 	if (mp == NULL) {
711 		/*
712 		 * The caller specified an offset that is larger than the
713 		 * total size of the buffers it provided.
714 		 */
715 		return (CRYPTO_DATA_LEN_RANGE);
716 	}
717 
718 	/*
719 	 * Now do the processing on the mblk chain.
720 	 */
721 	while (mp != NULL && length > 0) {
722 		cur_len = MIN(MBLKL(mp) - offset, length);
723 		(cipher)(des_ctx, (char *)(mp->b_rptr + offset), cur_len,
724 		    (input == output) ? NULL : output);
725 
726 		length -= cur_len;
727 		offset = 0;
728 		mp = mp->b_cont;
729 	}
730 
731 	if (mp == NULL && length > 0) {
732 		/*
733 		 * The end of the mblk was reached but the length requested
734 		 * could not be processed, i.e. The caller requested
735 		 * to digest more data than it provided.
736 		 */
737 		return (CRYPTO_DATA_LEN_RANGE);
738 	}
739 
740 	return (CRYPTO_SUCCESS);
741 }
742 
743 /* ARGSUSED */
744 static int
745 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
746     crypto_data_t *ciphertext, crypto_req_handle_t req)
747 {
748 	int ret;
749 
750 /* EXPORT DELETE START */
751 	des_ctx_t *des_ctx;
752 
753 	/*
754 	 * Plaintext must be a multiple of the block size.
755 	 * This test only works for non-padded mechanisms
756 	 * when blocksize is 2^N.
757 	 */
758 	if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
759 		return (CRYPTO_DATA_LEN_RANGE);
760 
761 	ASSERT(ctx->cc_provider_private != NULL);
762 	des_ctx = ctx->cc_provider_private;
763 
764 	DES_ARG_INPLACE(plaintext, ciphertext);
765 
766 	/*
767 	 * We need to just return the length needed to store the output.
768 	 * We should not destroy the context for the following case.
769 	 */
770 	if (ciphertext->cd_length < plaintext->cd_length) {
771 		ciphertext->cd_length = plaintext->cd_length;
772 		return (CRYPTO_BUFFER_TOO_SMALL);
773 	}
774 
775 	/*
776 	 * Do an update on the specified input data.
777 	 */
778 	ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
779 	ASSERT(des_ctx->dc_remainder_len == 0);
780 	(void) des_free_context(ctx);
781 
782 /* EXPORT DELETE END */
783 
784 	/* LINTED */
785 	return (ret);
786 }
787 
788 /* ARGSUSED */
789 static int
790 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
791     crypto_data_t *plaintext, crypto_req_handle_t req)
792 {
793 	int ret;
794 
795 /* EXPORT DELETE START */
796 	des_ctx_t *des_ctx;
797 
798 	/*
799 	 * Ciphertext must be a multiple of the block size.
800 	 * This test only works for non-padded mechanisms
801 	 * when blocksize is 2^N.
802 	 */
803 	if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
804 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
805 
806 	ASSERT(ctx->cc_provider_private != NULL);
807 	des_ctx = ctx->cc_provider_private;
808 
809 	DES_ARG_INPLACE(ciphertext, plaintext);
810 
811 	/*
812 	 * We need to just return the length needed to store the output.
813 	 * We should not destroy the context for the following case.
814 	 */
815 	if (plaintext->cd_length < ciphertext->cd_length) {
816 		plaintext->cd_length = ciphertext->cd_length;
817 		return (CRYPTO_BUFFER_TOO_SMALL);
818 	}
819 
820 	/*
821 	 * Do an update on the specified input data.
822 	 */
823 	ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
824 	ASSERT(des_ctx->dc_remainder_len == 0);
825 	(void) des_free_context(ctx);
826 
827 /* EXPORT DELETE END */
828 
829 	/* LINTED */
830 	return (ret);
831 }
832 
833 /* ARGSUSED */
834 static int
835 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
836     crypto_data_t *ciphertext, crypto_req_handle_t req)
837 {
838 	off_t saved_offset;
839 	size_t saved_length, out_len;
840 	int ret = CRYPTO_SUCCESS;
841 
842 /* EXPORT DELETE START */
843 
844 	ASSERT(ctx->cc_provider_private != NULL);
845 
846 	DES_ARG_INPLACE(plaintext, ciphertext);
847 
848 	/* compute number of bytes that will hold the ciphertext */
849 	out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
850 	out_len += plaintext->cd_length;
851 	out_len &= ~(DES_BLOCK_LEN - 1);
852 
853 	/* return length needed to store the output */
854 	if (ciphertext->cd_length < out_len) {
855 		ciphertext->cd_length = out_len;
856 		return (CRYPTO_BUFFER_TOO_SMALL);
857 	}
858 
859 	saved_offset = ciphertext->cd_offset;
860 	saved_length = ciphertext->cd_length;
861 
862 	/*
863 	 * Do the DES update on the specified input data.
864 	 */
865 	switch (plaintext->cd_format) {
866 	case CRYPTO_DATA_RAW:
867 		ret = des_cipher_update_iov(ctx->cc_provider_private,
868 		    plaintext, ciphertext, des_encrypt_contiguous_blocks);
869 		break;
870 	case CRYPTO_DATA_UIO:
871 		ret = des_cipher_update_uio(ctx->cc_provider_private,
872 		    plaintext, ciphertext, des_encrypt_contiguous_blocks);
873 		break;
874 	case CRYPTO_DATA_MBLK:
875 		ret = des_cipher_update_mp(ctx->cc_provider_private,
876 		    plaintext, ciphertext, des_encrypt_contiguous_blocks);
877 		break;
878 	default:
879 		ret = CRYPTO_ARGUMENTS_BAD;
880 	}
881 
882 	if (ret == CRYPTO_SUCCESS) {
883 		if (plaintext != ciphertext)
884 			ciphertext->cd_length =
885 			    ciphertext->cd_offset - saved_offset;
886 	} else {
887 		ciphertext->cd_length = saved_length;
888 	}
889 	ciphertext->cd_offset = saved_offset;
890 
891 /* EXPORT DELETE END */
892 
893 	return (ret);
894 }
895 
896 /* ARGSUSED */
897 static int
898 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
899     crypto_data_t *plaintext, crypto_req_handle_t req)
900 {
901 	off_t saved_offset;
902 	size_t saved_length, out_len;
903 	int ret = CRYPTO_SUCCESS;
904 
905 /* EXPORT DELETE START */
906 
907 	ASSERT(ctx->cc_provider_private != NULL);
908 
909 	DES_ARG_INPLACE(ciphertext, plaintext);
910 
911 	/* compute number of bytes that will hold the plaintext */
912 	out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
913 	out_len += ciphertext->cd_length;
914 	out_len &= ~(DES_BLOCK_LEN - 1);
915 
916 	/* return length needed to store the output */
917 	if (plaintext->cd_length < out_len) {
918 		plaintext->cd_length = out_len;
919 		return (CRYPTO_BUFFER_TOO_SMALL);
920 	}
921 
922 	saved_offset = plaintext->cd_offset;
923 	saved_length = plaintext->cd_length;
924 
925 	/*
926 	 * Do the DES update on the specified input data.
927 	 */
928 	switch (ciphertext->cd_format) {
929 	case CRYPTO_DATA_RAW:
930 		ret = des_cipher_update_iov(ctx->cc_provider_private,
931 		    ciphertext, plaintext, des_decrypt_contiguous_blocks);
932 		break;
933 	case CRYPTO_DATA_UIO:
934 		ret = des_cipher_update_uio(ctx->cc_provider_private,
935 		    ciphertext, plaintext, des_decrypt_contiguous_blocks);
936 		break;
937 	case CRYPTO_DATA_MBLK:
938 		ret = des_cipher_update_mp(ctx->cc_provider_private,
939 		    ciphertext, plaintext, des_decrypt_contiguous_blocks);
940 		break;
941 	default:
942 		ret = CRYPTO_ARGUMENTS_BAD;
943 	}
944 
945 	if (ret == CRYPTO_SUCCESS) {
946 		if (ciphertext != plaintext)
947 			plaintext->cd_length =
948 			    plaintext->cd_offset - saved_offset;
949 	} else {
950 		plaintext->cd_length = saved_length;
951 	}
952 	plaintext->cd_offset = saved_offset;
953 
954 /* EXPORT DELETE END */
955 
956 	return (ret);
957 }
958 
959 /* ARGSUSED */
960 static int
961 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
962     crypto_req_handle_t req)
963 {
964 
965 /* EXPORT DELETE START */
966 
967 	des_ctx_t *des_ctx;
968 
969 	ASSERT(ctx->cc_provider_private != NULL);
970 	des_ctx = ctx->cc_provider_private;
971 
972 	/*
973 	 * There must be no unprocessed plaintext.
974 	 * This happens if the length of the last data is
975 	 * not a multiple of the DES block length.
976 	 */
977 	if (des_ctx->dc_remainder_len > 0)
978 		return (CRYPTO_DATA_LEN_RANGE);
979 
980 	(void) des_free_context(ctx);
981 	ciphertext->cd_length = 0;
982 
983 /* EXPORT DELETE END */
984 
985 	return (CRYPTO_SUCCESS);
986 }
987 
988 /* ARGSUSED */
989 static int
990 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
991     crypto_req_handle_t req)
992 {
993 
994 /* EXPORT DELETE START */
995 
996 	des_ctx_t *des_ctx;
997 
998 	ASSERT(ctx->cc_provider_private != NULL);
999 	des_ctx = ctx->cc_provider_private;
1000 
1001 	/*
1002 	 * There must be no unprocessed ciphertext.
1003 	 * This happens if the length of the last ciphertext is
1004 	 * not a multiple of the DES block length.
1005 	 */
1006 	if (des_ctx->dc_remainder_len > 0)
1007 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
1008 
1009 	(void) des_free_context(ctx);
1010 	plaintext->cd_length = 0;
1011 
1012 /* EXPORT DELETE END */
1013 
1014 	return (CRYPTO_SUCCESS);
1015 }
1016 
1017 /* ARGSUSED */
1018 static int
1019 des_encrypt_atomic(crypto_provider_handle_t provider,
1020     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1021     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
1022     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1023 {
1024 	int ret;
1025 
1026 /* EXPORT DELETE START */
1027 
1028 	des_ctx_t des_ctx;		/* on the stack */
1029 	des_strength_t strength;
1030 	off_t saved_offset;
1031 	size_t saved_length;
1032 
1033 	DES_ARG_INPLACE(plaintext, ciphertext);
1034 
1035 	/*
1036 	 * Plaintext must be a multiple of the block size.
1037 	 * This test only works for non-padded mechanisms
1038 	 * when blocksize is 2^N.
1039 	 */
1040 	if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
1041 		return (CRYPTO_DATA_LEN_RANGE);
1042 
1043 	/* return length needed to store the output */
1044 	if (ciphertext->cd_length < plaintext->cd_length) {
1045 		ciphertext->cd_length = plaintext->cd_length;
1046 		return (CRYPTO_BUFFER_TOO_SMALL);
1047 	}
1048 
1049 	/* Check mechanism type and parameter length */
1050 	switch (mechanism->cm_type) {
1051 	case DES_ECB_MECH_INFO_TYPE:
1052 	case DES_CBC_MECH_INFO_TYPE:
1053 		if (mechanism->cm_param_len > 0 &&
1054 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1055 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1056 		if (key->ck_length != DES_MINBITS)
1057 			return (CRYPTO_KEY_SIZE_RANGE);
1058 		strength = DES;
1059 		break;
1060 	case DES3_ECB_MECH_INFO_TYPE:
1061 	case DES3_CBC_MECH_INFO_TYPE:
1062 		if (mechanism->cm_param_len > 0 &&
1063 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1064 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1065 		if (key->ck_length != DES3_MINBITS)
1066 			return (CRYPTO_KEY_SIZE_RANGE);
1067 		strength = DES3;
1068 		break;
1069 	default:
1070 		return (CRYPTO_MECHANISM_INVALID);
1071 	}
1072 
1073 	bzero(&des_ctx, sizeof (des_ctx_t));
1074 
1075 	if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
1076 	    strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
1077 		return (ret);
1078 	}
1079 
1080 	saved_offset = ciphertext->cd_offset;
1081 	saved_length = ciphertext->cd_length;
1082 
1083 	/*
1084 	 * Do the update on the specified input data.
1085 	 */
1086 	switch (plaintext->cd_format) {
1087 	case CRYPTO_DATA_RAW:
1088 		ret = des_cipher_update_iov(&des_ctx, plaintext, ciphertext,
1089 		    des_encrypt_contiguous_blocks);
1090 		break;
1091 	case CRYPTO_DATA_UIO:
1092 		ret = des_cipher_update_uio(&des_ctx, plaintext, ciphertext,
1093 		    des_encrypt_contiguous_blocks);
1094 		break;
1095 	case CRYPTO_DATA_MBLK:
1096 		ret = des_cipher_update_mp(&des_ctx, plaintext, ciphertext,
1097 		    des_encrypt_contiguous_blocks);
1098 		break;
1099 	default:
1100 		ret = CRYPTO_ARGUMENTS_BAD;
1101 	}
1102 
1103 	if (des_ctx.dc_flags & DES_PROVIDER_OWNS_KEY_SCHEDULE) {
1104 		bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1105 		kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1106 	}
1107 
1108 	if (ret == CRYPTO_SUCCESS) {
1109 		ASSERT(des_ctx.dc_remainder_len == 0);
1110 		if (plaintext != ciphertext)
1111 			ciphertext->cd_length =
1112 			    ciphertext->cd_offset - saved_offset;
1113 	} else {
1114 		ciphertext->cd_length = saved_length;
1115 	}
1116 	ciphertext->cd_offset = saved_offset;
1117 
1118 /* EXPORT DELETE END */
1119 
1120 	/* LINTED */
1121 	return (ret);
1122 }
1123 
1124 /* ARGSUSED */
1125 static int
1126 des_decrypt_atomic(crypto_provider_handle_t provider,
1127     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1128     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
1129     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1130 {
1131 	int ret;
1132 
1133 /* EXPORT DELETE START */
1134 
1135 	des_ctx_t des_ctx;	/* on the stack */
1136 	des_strength_t strength;
1137 	off_t saved_offset;
1138 	size_t saved_length;
1139 
1140 	DES_ARG_INPLACE(ciphertext, plaintext);
1141 
1142 	/*
1143 	 * Ciphertext must be a multiple of the block size.
1144 	 * This test only works for non-padded mechanisms
1145 	 * when blocksize is 2^N.
1146 	 */
1147 	if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
1148 		return (CRYPTO_DATA_LEN_RANGE);
1149 
1150 	/* return length needed to store the output */
1151 	if (plaintext->cd_length < ciphertext->cd_length) {
1152 		plaintext->cd_length = ciphertext->cd_length;
1153 		return (CRYPTO_BUFFER_TOO_SMALL);
1154 	}
1155 
1156 	/* Check mechanism type and parameter length */
1157 	switch (mechanism->cm_type) {
1158 	case DES_ECB_MECH_INFO_TYPE:
1159 	case DES_CBC_MECH_INFO_TYPE:
1160 		if (mechanism->cm_param_len > 0 &&
1161 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1162 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1163 		if (key->ck_length != DES_MINBITS)
1164 			return (CRYPTO_KEY_SIZE_RANGE);
1165 		strength = DES;
1166 		break;
1167 	case DES3_ECB_MECH_INFO_TYPE:
1168 	case DES3_CBC_MECH_INFO_TYPE:
1169 		if (mechanism->cm_param_len > 0 &&
1170 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1171 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1172 		if (key->ck_length != DES3_MINBITS)
1173 			return (CRYPTO_KEY_SIZE_RANGE);
1174 		strength = DES3;
1175 		break;
1176 	default:
1177 		return (CRYPTO_MECHANISM_INVALID);
1178 	}
1179 
1180 	bzero(&des_ctx, sizeof (des_ctx_t));
1181 
1182 	if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
1183 	    strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
1184 		return (ret);
1185 	}
1186 
1187 	saved_offset = plaintext->cd_offset;
1188 	saved_length = plaintext->cd_length;
1189 
1190 	/*
1191 	 * Do the update on the specified input data.
1192 	 */
1193 	switch (ciphertext->cd_format) {
1194 	case CRYPTO_DATA_RAW:
1195 		ret = des_cipher_update_iov(&des_ctx, ciphertext, plaintext,
1196 		    des_decrypt_contiguous_blocks);
1197 		break;
1198 	case CRYPTO_DATA_UIO:
1199 		ret = des_cipher_update_uio(&des_ctx, ciphertext, plaintext,
1200 		    des_decrypt_contiguous_blocks);
1201 		break;
1202 	case CRYPTO_DATA_MBLK:
1203 		ret = des_cipher_update_mp(&des_ctx, ciphertext, plaintext,
1204 		    des_decrypt_contiguous_blocks);
1205 		break;
1206 	default:
1207 		ret = CRYPTO_ARGUMENTS_BAD;
1208 	}
1209 
1210 	if (des_ctx.dc_flags & DES_PROVIDER_OWNS_KEY_SCHEDULE) {
1211 		bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1212 		kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1213 	}
1214 
1215 	if (ret == CRYPTO_SUCCESS) {
1216 		ASSERT(des_ctx.dc_remainder_len == 0);
1217 		if (ciphertext != plaintext)
1218 			plaintext->cd_length =
1219 			    plaintext->cd_offset - saved_offset;
1220 	} else {
1221 		plaintext->cd_length = saved_length;
1222 	}
1223 	plaintext->cd_offset = saved_offset;
1224 
1225 /* EXPORT DELETE END */
1226 
1227 	/* LINTED */
1228 	return (ret);
1229 }
1230 
1231 /*
1232  * KCF software provider context template entry points.
1233  */
1234 /* ARGSUSED */
1235 static int
1236 des_create_ctx_template(crypto_provider_handle_t provider,
1237     crypto_mechanism_t *mechanism, crypto_key_t *key,
1238     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1239 {
1240 
1241 /* EXPORT DELETE START */
1242 
1243 	des_strength_t strength;
1244 	void *keysched;
1245 	size_t size;
1246 	int rv;
1247 
1248 	switch (mechanism->cm_type) {
1249 	case DES_ECB_MECH_INFO_TYPE:
1250 		strength = DES;
1251 		break;
1252 	case DES_CBC_MECH_INFO_TYPE:
1253 		strength = DES;
1254 		break;
1255 	case DES3_ECB_MECH_INFO_TYPE:
1256 		strength = DES3;
1257 		break;
1258 	case DES3_CBC_MECH_INFO_TYPE:
1259 		strength = DES3;
1260 		break;
1261 	default:
1262 		return (CRYPTO_MECHANISM_INVALID);
1263 	}
1264 
1265 	if ((keysched = des_alloc_keysched(&size, strength,
1266 	    crypto_kmflag(req))) == NULL) {
1267 		return (CRYPTO_HOST_MEMORY);
1268 	}
1269 
1270 	/*
1271 	 * Initialize key schedule.  Key length information is stored
1272 	 * in the key.
1273 	 */
1274 	if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1275 		bzero(keysched, size);
1276 		kmem_free(keysched, size);
1277 		return (rv);
1278 	}
1279 
1280 	*tmpl = keysched;
1281 	*tmpl_size = size;
1282 
1283 /* EXPORT DELETE END */
1284 
1285 	return (CRYPTO_SUCCESS);
1286 }
1287 
1288 /* ARGSUSED */
1289 static int
1290 des_free_context(crypto_ctx_t *ctx)
1291 {
1292 
1293 /* EXPORT DELETE START */
1294 
1295 	des_ctx_t *des_ctx = ctx->cc_provider_private;
1296 
1297 	if (des_ctx != NULL) {
1298 		if (des_ctx->dc_flags & DES_PROVIDER_OWNS_KEY_SCHEDULE) {
1299 			ASSERT(des_ctx->dc_keysched_len != 0);
1300 			bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1301 			kmem_free(des_ctx->dc_keysched,
1302 			    des_ctx->dc_keysched_len);
1303 		}
1304 		kmem_free(des_ctx, sizeof (des_ctx_t));
1305 		ctx->cc_provider_private = NULL;
1306 	}
1307 
1308 /* EXPORT DELETE END */
1309 
1310 	return (CRYPTO_SUCCESS);
1311 }
1312 
1313 /*
1314  * Pass it to des_keycheck() which will
1315  * fix it (parity bits), and check if the fixed key is weak.
1316  */
1317 /* ARGSUSED */
1318 static int
1319 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1320     crypto_key_t *key)
1321 {
1322 
1323 /* EXPORT DELETE START */
1324 
1325 	int expectedkeylen;
1326 	des_strength_t strength;
1327 	uint8_t keydata[DES3_MAX_KEY_LEN];
1328 
1329 	if ((mech == NULL) || (key == NULL))
1330 		return (CRYPTO_ARGUMENTS_BAD);
1331 
1332 	switch (mech->cm_type) {
1333 	case DES_ECB_MECH_INFO_TYPE:
1334 	case DES_CBC_MECH_INFO_TYPE:
1335 		expectedkeylen = DES_MINBITS;
1336 		strength = DES;
1337 		break;
1338 	case DES3_ECB_MECH_INFO_TYPE:
1339 	case DES3_CBC_MECH_INFO_TYPE:
1340 		expectedkeylen = DES3_MINBITS;
1341 		strength = DES3;
1342 		break;
1343 	default:
1344 		return (CRYPTO_MECHANISM_INVALID);
1345 	}
1346 
1347 	if (key->ck_format != CRYPTO_KEY_RAW)
1348 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
1349 
1350 	if (key->ck_length != expectedkeylen)
1351 		return (CRYPTO_KEY_SIZE_RANGE);
1352 
1353 	bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1354 
1355 	if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1356 		return (CRYPTO_WEAK_KEY);
1357 
1358 /* EXPORT DELETE END */
1359 
1360 	return (CRYPTO_SUCCESS);
1361 }
1362 
1363 /* ARGSUSED */
1364 static int
1365 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1366     crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1367     int kmflag)
1368 {
1369 	int rv = CRYPTO_SUCCESS;
1370 
1371 /* EXPORT DELETE START */
1372 
1373 	void *keysched;
1374 	size_t size;
1375 
1376 	if (template == NULL) {
1377 		if ((keysched = des_alloc_keysched(&size, strength,
1378 		    kmflag)) == NULL)
1379 			return (CRYPTO_HOST_MEMORY);
1380 		/*
1381 		 * Initialize key schedule.
1382 		 * Key length is stored in the key.
1383 		 */
1384 		if ((rv = init_keysched(key, keysched,
1385 		    strength)) != CRYPTO_SUCCESS)
1386 			kmem_free(keysched, size);
1387 
1388 		des_ctx->dc_flags = DES_PROVIDER_OWNS_KEY_SCHEDULE;
1389 		des_ctx->dc_keysched_len = size;
1390 	} else {
1391 		keysched = template;
1392 	}
1393 
1394 	if (strength == DES3) {
1395 		des_ctx->dc_flags |= DES3_STRENGTH;
1396 	}
1397 
1398 	if (mechanism->cm_type == DES_CBC_MECH_INFO_TYPE ||
1399 	    mechanism->cm_type == DES3_CBC_MECH_INFO_TYPE) {
1400 		/*
1401 		 * Copy IV into DES context.
1402 		 *
1403 		 * If cm_param == NULL then the IV comes from the
1404 		 * cd_miscdata field in the crypto_data structure.
1405 		 */
1406 		if (mechanism->cm_param != NULL) {
1407 			ASSERT(mechanism->cm_param_len == DES_BLOCK_LEN);
1408 			if (IS_P2ALIGNED(mechanism->cm_param,
1409 			    sizeof (uint64_t))) {
1410 				/* LINTED: pointer alignment */
1411 				des_ctx->dc_iv =
1412 				    *(uint64_t *)mechanism->cm_param;
1413 			} else {
1414 				uint64_t tmp64;
1415 				uint8_t *tmp = (uint8_t *)mechanism->cm_param;
1416 
1417 #ifdef _BIG_ENDIAN
1418 				tmp64 = (((uint64_t)tmp[0] << 56) |
1419 				    ((uint64_t)tmp[1] << 48) |
1420 				    ((uint64_t)tmp[2] << 40) |
1421 				    ((uint64_t)tmp[3] << 32) |
1422 				    ((uint64_t)tmp[4] << 24) |
1423 				    ((uint64_t)tmp[5] << 16) |
1424 				    ((uint64_t)tmp[6] << 8) |
1425 				    (uint64_t)tmp[7]);
1426 #else
1427 				tmp64 = (((uint64_t)tmp[7] << 56) |
1428 				    ((uint64_t)tmp[6] << 48) |
1429 				    ((uint64_t)tmp[5] << 40) |
1430 				    ((uint64_t)tmp[4] << 32) |
1431 				    ((uint64_t)tmp[3] << 24) |
1432 				    ((uint64_t)tmp[2] << 16) |
1433 				    ((uint64_t)tmp[1] << 8) |
1434 				    (uint64_t)tmp[0]);
1435 #endif /* _BIG_ENDIAN */
1436 
1437 				des_ctx->dc_iv = tmp64;
1438 			}
1439 		}
1440 
1441 		des_ctx->dc_lastp = (uint8_t *)&des_ctx->dc_iv;
1442 		des_ctx->dc_flags |= DES_CBC_MODE;
1443 	}
1444 	des_ctx->dc_keysched = keysched;
1445 
1446 /* EXPORT DELETE END */
1447 
1448 	return (rv);
1449 }
1450