xref: /illumos-gate/usr/src/uts/common/des/des_crypt.c (revision 4de2612967d06c4fdbf524a62556a1e8118a006f)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 /*
30  * Portions of this source code were derived from Berkeley 4.3 BSD
31  * under license from the Regents of the University of California.
32  */
33 
34 #pragma ident	"%Z%%M%	%I%	%E% SMI"
35 
36 /*
37  * des_crypt.c, DES encryption library routines
38  */
39 
40 #include <sys/errno.h>
41 #include <sys/modctl.h>
42 
43 #include <sys/systm.h>
44 #include <sys/cmn_err.h>
45 #include <sys/ddi.h>
46 #include <sys/crypto/common.h>
47 #include <sys/crypto/spi.h>
48 #include <sys/sysmacros.h>
49 #include <sys/strsun.h>
50 #include <sys/note.h>
51 #include <des_impl.h>
52 #include <des_cbc_crypt.h>
53 
54 /* EXPORT DELETE START */
55 #include <sys/types.h>
56 #include <rpc/des_crypt.h>
57 #include <des/des.h>
58 
59 #ifdef sun_hardware
60 #include <sys/ioctl.h>
61 #ifdef _KERNEL
62 #include <sys/conf.h>
63 static int g_desfd = -1;
64 #define	getdesfd()	(cdevsw[11].d_open(0, 0) ? -1 : 0)
65 #define	ioctl(a, b, c)	(cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0)
66 #else
67 #define	getdesfd()	(open("/dev/des", 0, 0))
68 #endif	/* _KERNEL */
69 #endif	/* sun */
70 
71 static int common_crypt(char *key, char *buf, size_t len,
72     unsigned int mode, struct desparams *desp);
73 
74 extern int _des_crypt(char *buf, size_t len, struct desparams *desp);
75 
76 /* EXPORT DELETE END */
77 
78 extern struct mod_ops mod_cryptoops;
79 
80 /*
81  * Module linkage information for the kernel.
82  */
83 static struct modlmisc modlmisc = {
84 	&mod_miscops,
85 	"des encryption",
86 };
87 
88 static struct modlcrypto modlcrypto = {
89 	&mod_cryptoops,
90 	"DES Kernel SW Provider %I%"
91 };
92 
93 static struct modlinkage modlinkage = {
94 	MODREV_1,
95 	&modlmisc,
96 	&modlcrypto,
97 	NULL
98 };
99 
100 /*
101  * CSPI information (entry points, provider info, etc.)
102  */
103 typedef enum des_mech_type {
104 	DES_ECB_MECH_INFO_TYPE,		/* SUN_CKM_DES_ECB */
105 	DES_CBC_MECH_INFO_TYPE,		/* SUN_CKM_DES_CBC */
106 	DES_CFB_MECH_INFO_TYPE,		/* SUN_CKM_DES_CFB */
107 	DES3_ECB_MECH_INFO_TYPE,	/* SUN_CKM_DES3_ECB */
108 	DES3_CBC_MECH_INFO_TYPE,	/* SUN_CKM_DES3_CBC */
109 	DES3_CFB_MECH_INFO_TYPE		/* SUN_CKM_DES3_CFB */
110 } des_mech_type_t;
111 
112 /* EXPORT DELETE START */
113 
114 #define	DES_MIN_KEY_LEN		DES_MINBYTES
115 #define	DES_MAX_KEY_LEN		DES_MAXBYTES
116 #define	DES3_MIN_KEY_LEN	DES3_MINBYTES
117 #define	DES3_MAX_KEY_LEN	DES3_MAXBYTES
118 
119 /* EXPORT DELETE END */
120 
121 #ifndef DES_MIN_KEY_LEN
122 #define	DES_MIN_KEY_LEN		0
123 #endif
124 
125 #ifndef DES_MAX_KEY_LEN
126 #define	DES_MAX_KEY_LEN		0
127 #endif
128 
129 #ifndef DES3_MIN_KEY_LEN
130 #define	DES3_MIN_KEY_LEN	0
131 #endif
132 
133 #ifndef DES3_MAX_KEY_LEN
134 #define	DES3_MAX_KEY_LEN	0
135 #endif
136 
137 /*
138  * Mechanism info structure passed to KCF during registration.
139  */
140 static crypto_mech_info_t des_mech_info_tab[] = {
141 	/* DES_ECB */
142 	{SUN_CKM_DES_ECB, DES_ECB_MECH_INFO_TYPE,
143 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
144 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
145 	    DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
146 	/* DES_CBC */
147 	{SUN_CKM_DES_CBC, DES_CBC_MECH_INFO_TYPE,
148 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
149 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
150 	    DES_MIN_KEY_LEN, DES_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
151 	/* DES3_ECB */
152 	{SUN_CKM_DES3_ECB, DES3_ECB_MECH_INFO_TYPE,
153 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
154 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
155 	    DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES},
156 	/* DES3_CBC */
157 	{SUN_CKM_DES3_CBC, DES3_CBC_MECH_INFO_TYPE,
158 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
159 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC,
160 	    DES3_MIN_KEY_LEN, DES3_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BYTES}
161 };
162 
163 /* operations are in-place if the output buffer is NULL */
164 #define	DES_ARG_INPLACE(input, output)				\
165 	if ((output) == NULL)					\
166 		(output) = (input);
167 
168 static void des_provider_status(crypto_provider_handle_t, uint_t *);
169 
170 static crypto_control_ops_t des_control_ops = {
171 	des_provider_status
172 };
173 
174 static int
175 des_common_init(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *,
176     crypto_spi_ctx_template_t, crypto_req_handle_t);
177 static int des_common_init_ctx(des_ctx_t *, crypto_spi_ctx_template_t *,
178     crypto_mechanism_t *, crypto_key_t *, des_strength_t, int);
179 static int des_encrypt_final(crypto_ctx_t *, crypto_data_t *,
180     crypto_req_handle_t);
181 static int des_decrypt_final(crypto_ctx_t *, crypto_data_t *,
182     crypto_req_handle_t);
183 
184 static int des_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
185     crypto_req_handle_t);
186 static int des_encrypt_update(crypto_ctx_t *, crypto_data_t *,
187     crypto_data_t *, crypto_req_handle_t);
188 static int des_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
189     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
190     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
191 
192 static int des_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
193     crypto_req_handle_t);
194 static int des_decrypt_update(crypto_ctx_t *, crypto_data_t *,
195     crypto_data_t *, crypto_req_handle_t);
196 static int des_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
197     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
198     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
199 
200 static crypto_cipher_ops_t des_cipher_ops = {
201 	des_common_init,
202 	des_encrypt,
203 	des_encrypt_update,
204 	des_encrypt_final,
205 	des_encrypt_atomic,
206 	des_common_init,
207 	des_decrypt,
208 	des_decrypt_update,
209 	des_decrypt_final,
210 	des_decrypt_atomic
211 };
212 
213 static int des_create_ctx_template(crypto_provider_handle_t,
214     crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *,
215     size_t *, crypto_req_handle_t);
216 static int des_free_context(crypto_ctx_t *);
217 
218 static crypto_ctx_ops_t des_ctx_ops = {
219 	des_create_ctx_template,
220 	des_free_context
221 };
222 
223 static int des_key_check(crypto_provider_handle_t, crypto_mechanism_t *,
224     crypto_key_t *);
225 
226 static crypto_key_ops_t des_key_ops = {
227 	NULL,
228 	NULL,
229 	NULL,
230 	NULL,
231 	NULL,
232 	des_key_check
233 };
234 
235 static crypto_ops_t des_crypto_ops = {
236 	&des_control_ops,
237 	NULL,
238 	&des_cipher_ops,
239 	NULL,
240 	NULL,
241 	NULL,
242 	NULL,
243 	NULL,
244 	NULL,
245 	NULL,
246 	NULL,
247 	&des_key_ops,
248 	NULL,
249 	&des_ctx_ops
250 };
251 
252 static crypto_provider_info_t des_prov_info = {
253 	CRYPTO_SPI_VERSION_1,
254 	"DES Software Provider",
255 	CRYPTO_SW_PROVIDER,
256 	{&modlinkage},
257 	NULL,
258 	&des_crypto_ops,
259 	sizeof (des_mech_info_tab)/sizeof (crypto_mech_info_t),
260 	des_mech_info_tab
261 };
262 
263 static crypto_kcf_provider_handle_t des_prov_handle = NULL;
264 
265 int
266 _init(void)
267 {
268 	int ret;
269 
270 	if ((ret = mod_install(&modlinkage)) != 0)
271 		return (ret);
272 
273 	/*
274 	 * Register with KCF. If the registration fails, log an
275 	 * error but do not uninstall the module, since the functionality
276 	 * provided by misc/des should still be available.
277 	 */
278 	if ((ret = crypto_register_provider(&des_prov_info,
279 	    &des_prov_handle)) != CRYPTO_SUCCESS) {
280 		cmn_err(CE_WARN, "des _init: crypto_register_provider() "
281 		    "failed (0x%x)", ret);
282 	}
283 
284 	return (0);
285 }
286 
287 
288 int
289 _info(struct modinfo *modinfop)
290 {
291 	return (mod_info(&modlinkage, modinfop));
292 }
293 
294 /*
295  * Copy 8 bytes
296  */
297 #define	COPY8(src, dst) { \
298 	char *a = (char *)dst; \
299 	char *b = (char *)src; \
300 	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
301 	*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
302 }
303 
304 /*
305  * Copy multiple of 8 bytes
306  */
307 #define	DESCOPY(src, dst, len) { \
308 	char *a = (char *)dst; \
309 	char *b = (char *)src; \
310 	int i; \
311 	for (i = (size_t)len; i > 0; i -= 8) { \
312 		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
313 		*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
314 	} \
315 }
316 
317 /*
318  * CBC mode encryption
319  */
320 /* ARGSUSED */
321 int
322 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
323 {
324 	int err = 0;
325 /* EXPORT DELETE START */
326 	struct desparams dp;
327 
328 	dp.des_mode = CBC;
329 	COPY8(ivec, dp.des_ivec);
330 	err = common_crypt(key, buf, len, mode, &dp);
331 	COPY8(dp.des_ivec, ivec);
332 /* EXPORT DELETE END */
333 	return (err);
334 }
335 
336 
337 /*
338  * ECB mode encryption
339  */
340 /* ARGSUSED */
341 int
342 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
343 {
344 	int err = 0;
345 /* EXPORT DELETE START */
346 	struct desparams dp;
347 
348 	dp.des_mode = ECB;
349 	err = common_crypt(key, buf, len, mode, &dp);
350 /* EXPORT DELETE END */
351 	return (err);
352 }
353 
354 
355 
356 /* EXPORT DELETE START */
357 /*
358  * Common code to cbc_crypt() & ecb_crypt()
359  */
360 static int
361 common_crypt(char *key, char *buf, size_t len, unsigned int mode,
362     struct desparams *desp)
363 {
364 	int desdev;
365 
366 	if ((len % 8) != 0 || len > DES_MAXDATA)
367 		return (DESERR_BADPARAM);
368 
369 	desp->des_dir =
370 	    ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
371 
372 	desdev = mode & DES_DEVMASK;
373 	COPY8(key, desp->des_key);
374 
375 #ifdef sun_hardware
376 	if (desdev == DES_HW) {
377 		int res;
378 
379 		if (g_desfd < 0 &&
380 		    (g_desfd == -1 || (g_desfd = getdesfd()) < 0))
381 				goto software;	/* no hardware device */
382 
383 		/*
384 		 * hardware
385 		 */
386 		desp->des_len = len;
387 		if (len <= DES_QUICKLEN) {
388 			DESCOPY(buf, desp->des_data, len);
389 			res = ioctl(g_desfd, DESIOCQUICK, (char *)desp);
390 			DESCOPY(desp->des_data, buf, len);
391 		} else {
392 			desp->des_buf = (uchar_t *)buf;
393 			res = ioctl(g_desfd, DESIOCBLOCK, (char *)desp);
394 		}
395 		return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
396 	}
397 software:
398 #endif
399 	/*
400 	 * software
401 	 */
402 	if (!_des_crypt(buf, len, desp))
403 		return (DESERR_HWERROR);
404 
405 	return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
406 }
407 
408 /*
409  * Initialize key schedules for DES and DES3
410  */
411 static int
412 init_keysched(crypto_key_t *key, void *newbie, des_strength_t strength)
413 {
414 	uint8_t corrected_key[DES3_KEYSIZE];
415 
416 	/*
417 	 * Only keys by value are supported by this module.
418 	 */
419 	switch (key->ck_format) {
420 	case CRYPTO_KEY_RAW:
421 		if (strength == DES && key->ck_length != DES_MINBITS)
422 			return (CRYPTO_KEY_SIZE_RANGE);
423 		if (strength == DES3 && key->ck_length != DES3_MINBITS)
424 			return (CRYPTO_KEY_SIZE_RANGE);
425 		break;
426 	default:
427 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
428 	}
429 
430 	/*
431 	 * Fix parity bits.
432 	 * Initialize key schedule even if key is weak.
433 	 */
434 	(void) des_keycheck(key->ck_data, strength, corrected_key);
435 
436 	des_init_keysched(corrected_key, strength, newbie);
437 	return (CRYPTO_SUCCESS);
438 }
439 
440 /* EXPORT DELETE END */
441 
442 /*
443  * KCF software provider control entry points.
444  */
445 /* ARGSUSED */
446 static void
447 des_provider_status(crypto_provider_handle_t provider, uint_t *status)
448 {
449 	*status = CRYPTO_PROVIDER_READY;
450 }
451 
452 /*
453  * KCF software provider encrypt entry points.
454  */
455 static int
456 des_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
457     crypto_key_t *key, crypto_spi_ctx_template_t template,
458     crypto_req_handle_t req)
459 {
460 
461 /* EXPORT DELETE START */
462 
463 	des_strength_t strength;
464 	des_ctx_t *des_ctx;
465 	int rv;
466 	int kmflag;
467 
468 	/*
469 	 * Only keys by value are supported by this module.
470 	 */
471 	if (key->ck_format != CRYPTO_KEY_RAW) {
472 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
473 	}
474 
475 	/* Check mechanism type and parameter length */
476 	switch (mechanism->cm_type) {
477 	case DES_ECB_MECH_INFO_TYPE:
478 	case DES_CBC_MECH_INFO_TYPE:
479 		if (mechanism->cm_param != NULL &&
480 		    mechanism->cm_param_len != DES_BLOCK_LEN)
481 			return (CRYPTO_MECHANISM_PARAM_INVALID);
482 		if (key->ck_length != DES_MINBITS)
483 			return (CRYPTO_KEY_SIZE_RANGE);
484 		strength = DES;
485 		break;
486 	case DES3_ECB_MECH_INFO_TYPE:
487 	case DES3_CBC_MECH_INFO_TYPE:
488 		if (mechanism->cm_param != NULL &&
489 		    mechanism->cm_param_len != DES_BLOCK_LEN)
490 			return (CRYPTO_MECHANISM_PARAM_INVALID);
491 		if (key->ck_length != DES3_MINBITS)
492 			return (CRYPTO_KEY_SIZE_RANGE);
493 		strength = DES3;
494 		break;
495 	default:
496 		return (CRYPTO_MECHANISM_INVALID);
497 	}
498 
499 	/*
500 	 * Allocate a context.  Same context is used for DES and DES3.
501 	 */
502 	kmflag = crypto_kmflag(req);
503 	if ((des_ctx = kmem_zalloc(sizeof (des_ctx_t), kmflag)) == NULL)
504 		return (CRYPTO_HOST_MEMORY);
505 
506 	if ((rv = des_common_init_ctx(des_ctx, template, mechanism, key,
507 	    strength, kmflag)) != CRYPTO_SUCCESS) {
508 		kmem_free(des_ctx, sizeof (des_ctx_t));
509 		return (rv);
510 	}
511 
512 	ctx->cc_provider_private = des_ctx;
513 
514 /* EXPORT DELETE END */
515 
516 	return (CRYPTO_SUCCESS);
517 }
518 
519 /*
520  * Helper DES encrypt update function for iov input data.
521  */
522 static int
523 des_cipher_update_iov(des_ctx_t *des_ctx, crypto_data_t *input,
524     crypto_data_t *output, int (*cipher)(des_ctx_t *, caddr_t, size_t,
525     crypto_data_t *))
526 {
527 	if (input->cd_miscdata != NULL) {
528 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
529 			/* LINTED: pointer alignment */
530 			des_ctx->dc_iv = *(uint64_t *)input->cd_miscdata;
531 		} else {
532 			uint64_t tmp64;
533 			uint8_t *tmp = (uint8_t *)input->cd_miscdata;
534 
535 #ifdef _BIG_ENDIAN
536 			tmp64 = (((uint64_t)tmp[0] << 56) |
537 			    ((uint64_t)tmp[1] << 48) |
538 			    ((uint64_t)tmp[2] << 40) |
539 			    ((uint64_t)tmp[3] << 32) |
540 			    ((uint64_t)tmp[4] << 24) |
541 			    ((uint64_t)tmp[5] << 16) |
542 			    ((uint64_t)tmp[6] << 8) |
543 			    (uint64_t)tmp[7]);
544 #else
545 			tmp64 = (((uint64_t)tmp[7] << 56) |
546 			    ((uint64_t)tmp[6] << 48) |
547 			    ((uint64_t)tmp[5] << 40) |
548 			    ((uint64_t)tmp[4] << 32) |
549 			    ((uint64_t)tmp[3] << 24) |
550 			    ((uint64_t)tmp[2] << 16) |
551 			    ((uint64_t)tmp[1] << 8) |
552 			    (uint64_t)tmp[0]);
553 #endif /* _BIG_ENDIAN */
554 
555 			des_ctx->dc_iv = tmp64;
556 		}
557 	}
558 
559 	if (input->cd_raw.iov_len < input->cd_length)
560 		return (CRYPTO_ARGUMENTS_BAD);
561 
562 	return ((cipher)(des_ctx, input->cd_raw.iov_base + input->cd_offset,
563 	    input->cd_length, (input == output) ? NULL : output));
564 }
565 
566 /*
567  * Helper DES encrypt update function for uio input data.
568  */
569 static int
570 des_cipher_update_uio(des_ctx_t *des_ctx, crypto_data_t *input,
571     crypto_data_t *output, int (*cipher)(des_ctx_t *, caddr_t, size_t,
572     crypto_data_t *))
573 {
574 	uio_t *uiop = input->cd_uio;
575 	off_t offset = input->cd_offset;
576 	size_t length = input->cd_length;
577 	uint_t vec_idx;
578 	size_t cur_len;
579 
580 	if (input->cd_miscdata != NULL) {
581 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
582 			/* LINTED: pointer alignment */
583 			des_ctx->dc_iv = *(uint64_t *)input->cd_miscdata;
584 		} else {
585 			uint64_t tmp64;
586 			uint8_t *tmp = (uint8_t *)input->cd_miscdata;
587 
588 #ifdef _BIG_ENDIAN
589 			tmp64 = (((uint64_t)tmp[0] << 56) |
590 			    ((uint64_t)tmp[1] << 48) |
591 			    ((uint64_t)tmp[2] << 40) |
592 			    ((uint64_t)tmp[3] << 32) |
593 			    ((uint64_t)tmp[4] << 24) |
594 			    ((uint64_t)tmp[5] << 16) |
595 			    ((uint64_t)tmp[6] << 8) |
596 			    (uint64_t)tmp[7]);
597 #else
598 			tmp64 = (((uint64_t)tmp[7] << 56) |
599 			    ((uint64_t)tmp[6] << 48) |
600 			    ((uint64_t)tmp[5] << 40) |
601 			    ((uint64_t)tmp[4] << 32) |
602 			    ((uint64_t)tmp[3] << 24) |
603 			    ((uint64_t)tmp[2] << 16) |
604 			    ((uint64_t)tmp[1] << 8) |
605 			    (uint64_t)tmp[0]);
606 #endif /* _BIG_ENDIAN */
607 
608 			des_ctx->dc_iv = tmp64;
609 		}
610 	}
611 
612 	if (input->cd_uio->uio_segflg != UIO_SYSSPACE) {
613 		return (CRYPTO_ARGUMENTS_BAD);
614 	}
615 
616 	/*
617 	 * Jump to the first iovec containing data to be
618 	 * processed.
619 	 */
620 	for (vec_idx = 0; vec_idx < uiop->uio_iovcnt &&
621 	    offset >= uiop->uio_iov[vec_idx].iov_len;
622 	    offset -= uiop->uio_iov[vec_idx++].iov_len);
623 	if (vec_idx == uiop->uio_iovcnt) {
624 		/*
625 		 * The caller specified an offset that is larger than the
626 		 * total size of the buffers it provided.
627 		 */
628 		return (CRYPTO_DATA_LEN_RANGE);
629 	}
630 
631 	/*
632 	 * Now process the iovecs.
633 	 */
634 	while (vec_idx < uiop->uio_iovcnt && length > 0) {
635 		cur_len = MIN(uiop->uio_iov[vec_idx].iov_len -
636 		    offset, length);
637 
638 		(cipher)(des_ctx, uiop->uio_iov[vec_idx].iov_base + offset,
639 		    cur_len, (input == output) ? NULL : output);
640 
641 		length -= cur_len;
642 		vec_idx++;
643 		offset = 0;
644 	}
645 
646 	if (vec_idx == uiop->uio_iovcnt && length > 0) {
647 		/*
648 		 * The end of the specified iovec's was reached but
649 		 * the length requested could not be processed, i.e.
650 		 * The caller requested to digest more data than it provided.
651 		 */
652 
653 		return (CRYPTO_DATA_LEN_RANGE);
654 	}
655 
656 	return (CRYPTO_SUCCESS);
657 }
658 
659 /*
660  * Helper DES encrypt update function for mblk input data.
661  */
662 static int
663 des_cipher_update_mp(des_ctx_t *des_ctx, crypto_data_t *input,
664     crypto_data_t *output, int (*cipher)(des_ctx_t *, caddr_t, size_t,
665     crypto_data_t *))
666 {
667 	off_t offset = input->cd_offset;
668 	size_t length = input->cd_length;
669 	mblk_t *mp;
670 	size_t cur_len;
671 
672 	if (input->cd_miscdata != NULL) {
673 		if (IS_P2ALIGNED(input->cd_miscdata, sizeof (uint64_t))) {
674 			/* LINTED: pointer alignment */
675 			des_ctx->dc_iv = *(uint64_t *)input->cd_miscdata;
676 		} else {
677 			uint64_t tmp64;
678 			uint8_t *tmp = (uint8_t *)input->cd_miscdata;
679 
680 #ifdef _BIG_ENDIAN
681 			tmp64 = (((uint64_t)tmp[0] << 56) |
682 			    ((uint64_t)tmp[1] << 48) |
683 			    ((uint64_t)tmp[2] << 40) |
684 			    ((uint64_t)tmp[3] << 32) |
685 			    ((uint64_t)tmp[4] << 24) |
686 			    ((uint64_t)tmp[5] << 16) |
687 			    ((uint64_t)tmp[6] << 8) |
688 			    (uint64_t)tmp[7]);
689 #else
690 			tmp64 = (((uint64_t)tmp[7] << 56) |
691 			    ((uint64_t)tmp[6] << 48) |
692 			    ((uint64_t)tmp[5] << 40) |
693 			    ((uint64_t)tmp[4] << 32) |
694 			    ((uint64_t)tmp[3] << 24) |
695 			    ((uint64_t)tmp[2] << 16) |
696 			    ((uint64_t)tmp[1] << 8) |
697 			    (uint64_t)tmp[0]);
698 #endif /* _BIG_ENDIAN */
699 
700 			des_ctx->dc_iv = tmp64;
701 		}
702 	}
703 
704 	/*
705 	 * Jump to the first mblk_t containing data to be processed.
706 	 */
707 	for (mp = input->cd_mp; mp != NULL && offset >= MBLKL(mp);
708 	    offset -= MBLKL(mp), mp = mp->b_cont);
709 	if (mp == NULL) {
710 		/*
711 		 * The caller specified an offset that is larger than the
712 		 * total size of the buffers it provided.
713 		 */
714 		return (CRYPTO_DATA_LEN_RANGE);
715 	}
716 
717 	/*
718 	 * Now do the processing on the mblk chain.
719 	 */
720 	while (mp != NULL && length > 0) {
721 		cur_len = MIN(MBLKL(mp) - offset, length);
722 		(cipher)(des_ctx, (char *)(mp->b_rptr + offset), cur_len,
723 		    (input == output) ? NULL : output);
724 
725 		length -= cur_len;
726 		offset = 0;
727 		mp = mp->b_cont;
728 	}
729 
730 	if (mp == NULL && length > 0) {
731 		/*
732 		 * The end of the mblk was reached but the length requested
733 		 * could not be processed, i.e. The caller requested
734 		 * to digest more data than it provided.
735 		 */
736 		return (CRYPTO_DATA_LEN_RANGE);
737 	}
738 
739 	return (CRYPTO_SUCCESS);
740 }
741 
742 /* ARGSUSED */
743 static int
744 des_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
745     crypto_data_t *ciphertext, crypto_req_handle_t req)
746 {
747 	int ret;
748 
749 /* EXPORT DELETE START */
750 	des_ctx_t *des_ctx;
751 
752 	/*
753 	 * Plaintext must be a multiple of the block size.
754 	 * This test only works for non-padded mechanisms
755 	 * when blocksize is 2^N.
756 	 */
757 	if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
758 		return (CRYPTO_DATA_LEN_RANGE);
759 
760 	ASSERT(ctx->cc_provider_private != NULL);
761 	des_ctx = ctx->cc_provider_private;
762 
763 	DES_ARG_INPLACE(plaintext, ciphertext);
764 
765 	/*
766 	 * We need to just return the length needed to store the output.
767 	 * We should not destroy the context for the following case.
768 	 */
769 	if (ciphertext->cd_length < plaintext->cd_length) {
770 		ciphertext->cd_length = plaintext->cd_length;
771 		return (CRYPTO_BUFFER_TOO_SMALL);
772 	}
773 
774 	/*
775 	 * Do an update on the specified input data.
776 	 */
777 	ret = des_encrypt_update(ctx, plaintext, ciphertext, req);
778 	ASSERT(des_ctx->dc_remainder_len == 0);
779 	(void) des_free_context(ctx);
780 
781 /* EXPORT DELETE END */
782 
783 	/* LINTED */
784 	return (ret);
785 }
786 
787 /* ARGSUSED */
788 static int
789 des_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
790     crypto_data_t *plaintext, crypto_req_handle_t req)
791 {
792 	int ret;
793 
794 /* EXPORT DELETE START */
795 	des_ctx_t *des_ctx;
796 
797 	/*
798 	 * Ciphertext must be a multiple of the block size.
799 	 * This test only works for non-padded mechanisms
800 	 * when blocksize is 2^N.
801 	 */
802 	if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
803 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
804 
805 	ASSERT(ctx->cc_provider_private != NULL);
806 	des_ctx = ctx->cc_provider_private;
807 
808 	DES_ARG_INPLACE(ciphertext, plaintext);
809 
810 	/*
811 	 * We need to just return the length needed to store the output.
812 	 * We should not destroy the context for the following case.
813 	 */
814 	if (plaintext->cd_length < ciphertext->cd_length) {
815 		plaintext->cd_length = ciphertext->cd_length;
816 		return (CRYPTO_BUFFER_TOO_SMALL);
817 	}
818 
819 	/*
820 	 * Do an update on the specified input data.
821 	 */
822 	ret = des_decrypt_update(ctx, ciphertext, plaintext, req);
823 	ASSERT(des_ctx->dc_remainder_len == 0);
824 	(void) des_free_context(ctx);
825 
826 /* EXPORT DELETE END */
827 
828 	/* LINTED */
829 	return (ret);
830 }
831 
832 /* ARGSUSED */
833 static int
834 des_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
835     crypto_data_t *ciphertext, crypto_req_handle_t req)
836 {
837 	off_t saved_offset;
838 	size_t saved_length, out_len;
839 	int ret = CRYPTO_SUCCESS;
840 
841 /* EXPORT DELETE START */
842 
843 	ASSERT(ctx->cc_provider_private != NULL);
844 
845 	DES_ARG_INPLACE(plaintext, ciphertext);
846 
847 	/* compute number of bytes that will hold the ciphertext */
848 	out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
849 	out_len += plaintext->cd_length;
850 	out_len &= ~(DES_BLOCK_LEN - 1);
851 
852 	/* return length needed to store the output */
853 	if (ciphertext->cd_length < out_len) {
854 		ciphertext->cd_length = out_len;
855 		return (CRYPTO_BUFFER_TOO_SMALL);
856 	}
857 
858 	saved_offset = ciphertext->cd_offset;
859 	saved_length = ciphertext->cd_length;
860 
861 	/*
862 	 * Do the DES update on the specified input data.
863 	 */
864 	switch (plaintext->cd_format) {
865 	case CRYPTO_DATA_RAW:
866 		ret = des_cipher_update_iov(ctx->cc_provider_private,
867 		    plaintext, ciphertext, des_encrypt_contiguous_blocks);
868 		break;
869 	case CRYPTO_DATA_UIO:
870 		ret = des_cipher_update_uio(ctx->cc_provider_private,
871 		    plaintext, ciphertext, des_encrypt_contiguous_blocks);
872 		break;
873 	case CRYPTO_DATA_MBLK:
874 		ret = des_cipher_update_mp(ctx->cc_provider_private,
875 		    plaintext, ciphertext, des_encrypt_contiguous_blocks);
876 		break;
877 	default:
878 		ret = CRYPTO_ARGUMENTS_BAD;
879 	}
880 
881 	if (ret == CRYPTO_SUCCESS) {
882 		if (plaintext != ciphertext)
883 			ciphertext->cd_length =
884 			    ciphertext->cd_offset - saved_offset;
885 	} else {
886 		ciphertext->cd_length = saved_length;
887 	}
888 	ciphertext->cd_offset = saved_offset;
889 
890 /* EXPORT DELETE END */
891 
892 	return (ret);
893 }
894 
895 /* ARGSUSED */
896 static int
897 des_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
898     crypto_data_t *plaintext, crypto_req_handle_t req)
899 {
900 	off_t saved_offset;
901 	size_t saved_length, out_len;
902 	int ret = CRYPTO_SUCCESS;
903 
904 /* EXPORT DELETE START */
905 
906 	ASSERT(ctx->cc_provider_private != NULL);
907 
908 	DES_ARG_INPLACE(ciphertext, plaintext);
909 
910 	/* compute number of bytes that will hold the plaintext */
911 	out_len = ((des_ctx_t *)ctx->cc_provider_private)->dc_remainder_len;
912 	out_len += ciphertext->cd_length;
913 	out_len &= ~(DES_BLOCK_LEN - 1);
914 
915 	/* return length needed to store the output */
916 	if (plaintext->cd_length < out_len) {
917 		plaintext->cd_length = out_len;
918 		return (CRYPTO_BUFFER_TOO_SMALL);
919 	}
920 
921 	saved_offset = plaintext->cd_offset;
922 	saved_length = plaintext->cd_length;
923 
924 	/*
925 	 * Do the DES update on the specified input data.
926 	 */
927 	switch (ciphertext->cd_format) {
928 	case CRYPTO_DATA_RAW:
929 		ret = des_cipher_update_iov(ctx->cc_provider_private,
930 		    ciphertext, plaintext, des_decrypt_contiguous_blocks);
931 		break;
932 	case CRYPTO_DATA_UIO:
933 		ret = des_cipher_update_uio(ctx->cc_provider_private,
934 		    ciphertext, plaintext, des_decrypt_contiguous_blocks);
935 		break;
936 	case CRYPTO_DATA_MBLK:
937 		ret = des_cipher_update_mp(ctx->cc_provider_private,
938 		    ciphertext, plaintext, des_decrypt_contiguous_blocks);
939 		break;
940 	default:
941 		ret = CRYPTO_ARGUMENTS_BAD;
942 	}
943 
944 	if (ret == CRYPTO_SUCCESS) {
945 		if (ciphertext != plaintext)
946 			plaintext->cd_length =
947 			    plaintext->cd_offset - saved_offset;
948 	} else {
949 		plaintext->cd_length = saved_length;
950 	}
951 	plaintext->cd_offset = saved_offset;
952 
953 /* EXPORT DELETE END */
954 
955 	return (ret);
956 }
957 
958 /* ARGSUSED */
959 static int
960 des_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
961     crypto_req_handle_t req)
962 {
963 
964 /* EXPORT DELETE START */
965 
966 	des_ctx_t *des_ctx;
967 
968 	ASSERT(ctx->cc_provider_private != NULL);
969 	des_ctx = ctx->cc_provider_private;
970 
971 	/*
972 	 * There must be no unprocessed plaintext.
973 	 * This happens if the length of the last data is
974 	 * not a multiple of the DES block length.
975 	 */
976 	if (des_ctx->dc_remainder_len > 0)
977 		return (CRYPTO_DATA_LEN_RANGE);
978 
979 	(void) des_free_context(ctx);
980 	ciphertext->cd_length = 0;
981 
982 /* EXPORT DELETE END */
983 
984 	return (CRYPTO_SUCCESS);
985 }
986 
987 /* ARGSUSED */
988 static int
989 des_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *plaintext,
990     crypto_req_handle_t req)
991 {
992 
993 /* EXPORT DELETE START */
994 
995 	des_ctx_t *des_ctx;
996 
997 	ASSERT(ctx->cc_provider_private != NULL);
998 	des_ctx = ctx->cc_provider_private;
999 
1000 	/*
1001 	 * There must be no unprocessed ciphertext.
1002 	 * This happens if the length of the last ciphertext is
1003 	 * not a multiple of the DES block length.
1004 	 */
1005 	if (des_ctx->dc_remainder_len > 0)
1006 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
1007 
1008 	(void) des_free_context(ctx);
1009 	plaintext->cd_length = 0;
1010 
1011 /* EXPORT DELETE END */
1012 
1013 	return (CRYPTO_SUCCESS);
1014 }
1015 
1016 /* ARGSUSED */
1017 static int
1018 des_encrypt_atomic(crypto_provider_handle_t provider,
1019     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1020     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
1021     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1022 {
1023 	int ret;
1024 
1025 /* EXPORT DELETE START */
1026 
1027 	des_ctx_t des_ctx;		/* on the stack */
1028 	des_strength_t strength;
1029 	off_t saved_offset;
1030 	size_t saved_length;
1031 
1032 	DES_ARG_INPLACE(plaintext, ciphertext);
1033 
1034 	/*
1035 	 * Plaintext must be a multiple of the block size.
1036 	 * This test only works for non-padded mechanisms
1037 	 * when blocksize is 2^N.
1038 	 */
1039 	if ((plaintext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
1040 		return (CRYPTO_DATA_LEN_RANGE);
1041 
1042 	/* return length needed to store the output */
1043 	if (ciphertext->cd_length < plaintext->cd_length) {
1044 		ciphertext->cd_length = plaintext->cd_length;
1045 		return (CRYPTO_BUFFER_TOO_SMALL);
1046 	}
1047 
1048 	/* Check mechanism type and parameter length */
1049 	switch (mechanism->cm_type) {
1050 	case DES_ECB_MECH_INFO_TYPE:
1051 	case DES_CBC_MECH_INFO_TYPE:
1052 		if (mechanism->cm_param_len > 0 &&
1053 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1054 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1055 		if (key->ck_length != DES_MINBITS)
1056 			return (CRYPTO_KEY_SIZE_RANGE);
1057 		strength = DES;
1058 		break;
1059 	case DES3_ECB_MECH_INFO_TYPE:
1060 	case DES3_CBC_MECH_INFO_TYPE:
1061 		if (mechanism->cm_param_len > 0 &&
1062 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1063 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1064 		if (key->ck_length != DES3_MINBITS)
1065 			return (CRYPTO_KEY_SIZE_RANGE);
1066 		strength = DES3;
1067 		break;
1068 	default:
1069 		return (CRYPTO_MECHANISM_INVALID);
1070 	}
1071 
1072 	bzero(&des_ctx, sizeof (des_ctx_t));
1073 
1074 	if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
1075 	    strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
1076 		return (ret);
1077 	}
1078 
1079 	saved_offset = ciphertext->cd_offset;
1080 	saved_length = ciphertext->cd_length;
1081 
1082 	/*
1083 	 * Do the update on the specified input data.
1084 	 */
1085 	switch (plaintext->cd_format) {
1086 	case CRYPTO_DATA_RAW:
1087 		ret = des_cipher_update_iov(&des_ctx, plaintext, ciphertext,
1088 		    des_encrypt_contiguous_blocks);
1089 		break;
1090 	case CRYPTO_DATA_UIO:
1091 		ret = des_cipher_update_uio(&des_ctx, plaintext, ciphertext,
1092 		    des_encrypt_contiguous_blocks);
1093 		break;
1094 	case CRYPTO_DATA_MBLK:
1095 		ret = des_cipher_update_mp(&des_ctx, plaintext, ciphertext,
1096 		    des_encrypt_contiguous_blocks);
1097 		break;
1098 	default:
1099 		ret = CRYPTO_ARGUMENTS_BAD;
1100 	}
1101 
1102 	if (des_ctx.dc_flags & DES_PROVIDER_OWNS_KEY_SCHEDULE) {
1103 		bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1104 		kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1105 	}
1106 
1107 	if (ret == CRYPTO_SUCCESS) {
1108 		ASSERT(des_ctx.dc_remainder_len == 0);
1109 		if (plaintext != ciphertext)
1110 			ciphertext->cd_length =
1111 			    ciphertext->cd_offset - saved_offset;
1112 	} else {
1113 		ciphertext->cd_length = saved_length;
1114 	}
1115 	ciphertext->cd_offset = saved_offset;
1116 
1117 /* EXPORT DELETE END */
1118 
1119 	/* LINTED */
1120 	return (ret);
1121 }
1122 
1123 /* ARGSUSED */
1124 static int
1125 des_decrypt_atomic(crypto_provider_handle_t provider,
1126     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
1127     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
1128     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
1129 {
1130 	int ret;
1131 
1132 /* EXPORT DELETE START */
1133 
1134 	des_ctx_t des_ctx;	/* on the stack */
1135 	des_strength_t strength;
1136 	off_t saved_offset;
1137 	size_t saved_length;
1138 
1139 	DES_ARG_INPLACE(ciphertext, plaintext);
1140 
1141 	/*
1142 	 * Ciphertext must be a multiple of the block size.
1143 	 * This test only works for non-padded mechanisms
1144 	 * when blocksize is 2^N.
1145 	 */
1146 	if ((ciphertext->cd_length & (DES_BLOCK_LEN - 1)) != 0)
1147 		return (CRYPTO_DATA_LEN_RANGE);
1148 
1149 	/* return length needed to store the output */
1150 	if (plaintext->cd_length < ciphertext->cd_length) {
1151 		plaintext->cd_length = ciphertext->cd_length;
1152 		return (CRYPTO_BUFFER_TOO_SMALL);
1153 	}
1154 
1155 	/* Check mechanism type and parameter length */
1156 	switch (mechanism->cm_type) {
1157 	case DES_ECB_MECH_INFO_TYPE:
1158 	case DES_CBC_MECH_INFO_TYPE:
1159 		if (mechanism->cm_param_len > 0 &&
1160 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1161 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1162 		if (key->ck_length != DES_MINBITS)
1163 			return (CRYPTO_KEY_SIZE_RANGE);
1164 		strength = DES;
1165 		break;
1166 	case DES3_ECB_MECH_INFO_TYPE:
1167 	case DES3_CBC_MECH_INFO_TYPE:
1168 		if (mechanism->cm_param_len > 0 &&
1169 		    mechanism->cm_param_len != DES_BLOCK_LEN)
1170 			return (CRYPTO_MECHANISM_PARAM_INVALID);
1171 		if (key->ck_length != DES3_MINBITS)
1172 			return (CRYPTO_KEY_SIZE_RANGE);
1173 		strength = DES3;
1174 		break;
1175 	default:
1176 		return (CRYPTO_MECHANISM_INVALID);
1177 	}
1178 
1179 	bzero(&des_ctx, sizeof (des_ctx_t));
1180 
1181 	if ((ret = des_common_init_ctx(&des_ctx, template, mechanism, key,
1182 	    strength, crypto_kmflag(req))) != CRYPTO_SUCCESS) {
1183 		return (ret);
1184 	}
1185 
1186 	saved_offset = plaintext->cd_offset;
1187 	saved_length = plaintext->cd_length;
1188 
1189 	/*
1190 	 * Do the update on the specified input data.
1191 	 */
1192 	switch (ciphertext->cd_format) {
1193 	case CRYPTO_DATA_RAW:
1194 		ret = des_cipher_update_iov(&des_ctx, ciphertext, plaintext,
1195 		    des_decrypt_contiguous_blocks);
1196 		break;
1197 	case CRYPTO_DATA_UIO:
1198 		ret = des_cipher_update_uio(&des_ctx, ciphertext, plaintext,
1199 		    des_decrypt_contiguous_blocks);
1200 		break;
1201 	case CRYPTO_DATA_MBLK:
1202 		ret = des_cipher_update_mp(&des_ctx, ciphertext, plaintext,
1203 		    des_decrypt_contiguous_blocks);
1204 		break;
1205 	default:
1206 		ret = CRYPTO_ARGUMENTS_BAD;
1207 	}
1208 
1209 	if (des_ctx.dc_flags & DES_PROVIDER_OWNS_KEY_SCHEDULE) {
1210 		bzero(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1211 		kmem_free(des_ctx.dc_keysched, des_ctx.dc_keysched_len);
1212 	}
1213 
1214 	if (ret == CRYPTO_SUCCESS) {
1215 		ASSERT(des_ctx.dc_remainder_len == 0);
1216 		if (ciphertext != plaintext)
1217 			plaintext->cd_length =
1218 			    plaintext->cd_offset - saved_offset;
1219 	} else {
1220 		plaintext->cd_length = saved_length;
1221 	}
1222 	plaintext->cd_offset = saved_offset;
1223 
1224 /* EXPORT DELETE END */
1225 
1226 	/* LINTED */
1227 	return (ret);
1228 }
1229 
1230 /*
1231  * KCF software provider context template entry points.
1232  */
1233 /* ARGSUSED */
1234 static int
1235 des_create_ctx_template(crypto_provider_handle_t provider,
1236     crypto_mechanism_t *mechanism, crypto_key_t *key,
1237     crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req)
1238 {
1239 
1240 /* EXPORT DELETE START */
1241 
1242 	des_strength_t strength;
1243 	void *keysched;
1244 	size_t size;
1245 	int rv;
1246 
1247 	switch (mechanism->cm_type) {
1248 	case DES_ECB_MECH_INFO_TYPE:
1249 		strength = DES;
1250 		break;
1251 	case DES_CBC_MECH_INFO_TYPE:
1252 		strength = DES;
1253 		break;
1254 	case DES3_ECB_MECH_INFO_TYPE:
1255 		strength = DES3;
1256 		break;
1257 	case DES3_CBC_MECH_INFO_TYPE:
1258 		strength = DES3;
1259 		break;
1260 	default:
1261 		return (CRYPTO_MECHANISM_INVALID);
1262 	}
1263 
1264 	if ((keysched = des_alloc_keysched(&size, strength,
1265 	    crypto_kmflag(req))) == NULL) {
1266 		return (CRYPTO_HOST_MEMORY);
1267 	}
1268 
1269 	/*
1270 	 * Initialize key schedule.  Key length information is stored
1271 	 * in the key.
1272 	 */
1273 	if ((rv = init_keysched(key, keysched, strength)) != CRYPTO_SUCCESS) {
1274 		bzero(keysched, size);
1275 		kmem_free(keysched, size);
1276 		return (rv);
1277 	}
1278 
1279 	*tmpl = keysched;
1280 	*tmpl_size = size;
1281 
1282 /* EXPORT DELETE END */
1283 
1284 	return (CRYPTO_SUCCESS);
1285 }
1286 
1287 /* ARGSUSED */
1288 static int
1289 des_free_context(crypto_ctx_t *ctx)
1290 {
1291 
1292 /* EXPORT DELETE START */
1293 
1294 	des_ctx_t *des_ctx = ctx->cc_provider_private;
1295 
1296 	if (des_ctx != NULL) {
1297 		if (des_ctx->dc_flags & DES_PROVIDER_OWNS_KEY_SCHEDULE) {
1298 			ASSERT(des_ctx->dc_keysched_len != 0);
1299 			bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len);
1300 			kmem_free(des_ctx->dc_keysched,
1301 			    des_ctx->dc_keysched_len);
1302 		}
1303 		kmem_free(des_ctx, sizeof (des_ctx_t));
1304 		ctx->cc_provider_private = NULL;
1305 	}
1306 
1307 /* EXPORT DELETE END */
1308 
1309 	return (CRYPTO_SUCCESS);
1310 }
1311 
1312 /*
1313  * Pass it to des_keycheck() which will
1314  * fix it (parity bits), and check if the fixed key is weak.
1315  */
1316 /* ARGSUSED */
1317 static int
1318 des_key_check(crypto_provider_handle_t pd, crypto_mechanism_t *mech,
1319     crypto_key_t *key)
1320 {
1321 
1322 /* EXPORT DELETE START */
1323 
1324 	int expectedkeylen;
1325 	des_strength_t strength;
1326 	uint8_t keydata[DES3_MAX_KEY_LEN];
1327 
1328 	if ((mech == NULL) || (key == NULL))
1329 		return (CRYPTO_ARGUMENTS_BAD);
1330 
1331 	switch (mech->cm_type) {
1332 	case DES_ECB_MECH_INFO_TYPE:
1333 	case DES_CBC_MECH_INFO_TYPE:
1334 		expectedkeylen = DES_MINBITS;
1335 		strength = DES;
1336 		break;
1337 	case DES3_ECB_MECH_INFO_TYPE:
1338 	case DES3_CBC_MECH_INFO_TYPE:
1339 		expectedkeylen = DES3_MINBITS;
1340 		strength = DES3;
1341 		break;
1342 	default:
1343 		return (CRYPTO_MECHANISM_INVALID);
1344 	}
1345 
1346 	if (key->ck_format != CRYPTO_KEY_RAW)
1347 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
1348 
1349 	if (key->ck_length != expectedkeylen)
1350 		return (CRYPTO_KEY_SIZE_RANGE);
1351 
1352 	bcopy(key->ck_data, keydata, CRYPTO_BITS2BYTES(expectedkeylen));
1353 
1354 	if (des_keycheck(keydata, strength, key->ck_data) == B_FALSE)
1355 		return (CRYPTO_WEAK_KEY);
1356 
1357 /* EXPORT DELETE END */
1358 
1359 	return (CRYPTO_SUCCESS);
1360 }
1361 
1362 /* ARGSUSED */
1363 static int
1364 des_common_init_ctx(des_ctx_t *des_ctx, crypto_spi_ctx_template_t *template,
1365     crypto_mechanism_t *mechanism, crypto_key_t *key, des_strength_t strength,
1366     int kmflag)
1367 {
1368 	int rv = CRYPTO_SUCCESS;
1369 
1370 /* EXPORT DELETE START */
1371 
1372 	void *keysched;
1373 	size_t size;
1374 
1375 	if (template == NULL) {
1376 		if ((keysched = des_alloc_keysched(&size, strength,
1377 		    kmflag)) == NULL)
1378 			return (CRYPTO_HOST_MEMORY);
1379 		/*
1380 		 * Initialize key schedule.
1381 		 * Key length is stored in the key.
1382 		 */
1383 		if ((rv = init_keysched(key, keysched,
1384 		    strength)) != CRYPTO_SUCCESS)
1385 			kmem_free(keysched, size);
1386 
1387 		des_ctx->dc_flags = DES_PROVIDER_OWNS_KEY_SCHEDULE;
1388 		des_ctx->dc_keysched_len = size;
1389 	} else {
1390 		keysched = template;
1391 	}
1392 
1393 	if (strength == DES3) {
1394 		des_ctx->dc_flags |= DES3_STRENGTH;
1395 	}
1396 
1397 	if (mechanism->cm_type == DES_CBC_MECH_INFO_TYPE ||
1398 	    mechanism->cm_type == DES3_CBC_MECH_INFO_TYPE) {
1399 		/*
1400 		 * Copy IV into DES context.
1401 		 *
1402 		 * If cm_param == NULL then the IV comes from the
1403 		 * cd_miscdata field in the crypto_data structure.
1404 		 */
1405 		if (mechanism->cm_param != NULL) {
1406 			ASSERT(mechanism->cm_param_len == DES_BLOCK_LEN);
1407 			if (IS_P2ALIGNED(mechanism->cm_param,
1408 			    sizeof (uint64_t))) {
1409 				/* LINTED: pointer alignment */
1410 				des_ctx->dc_iv =
1411 				    *(uint64_t *)mechanism->cm_param;
1412 			} else {
1413 				uint64_t tmp64;
1414 				uint8_t *tmp = (uint8_t *)mechanism->cm_param;
1415 
1416 #ifdef _BIG_ENDIAN
1417 				tmp64 = (((uint64_t)tmp[0] << 56) |
1418 				    ((uint64_t)tmp[1] << 48) |
1419 				    ((uint64_t)tmp[2] << 40) |
1420 				    ((uint64_t)tmp[3] << 32) |
1421 				    ((uint64_t)tmp[4] << 24) |
1422 				    ((uint64_t)tmp[5] << 16) |
1423 				    ((uint64_t)tmp[6] << 8) |
1424 				    (uint64_t)tmp[7]);
1425 #else
1426 				tmp64 = (((uint64_t)tmp[7] << 56) |
1427 				    ((uint64_t)tmp[6] << 48) |
1428 				    ((uint64_t)tmp[5] << 40) |
1429 				    ((uint64_t)tmp[4] << 32) |
1430 				    ((uint64_t)tmp[3] << 24) |
1431 				    ((uint64_t)tmp[2] << 16) |
1432 				    ((uint64_t)tmp[1] << 8) |
1433 				    (uint64_t)tmp[0]);
1434 #endif /* _BIG_ENDIAN */
1435 
1436 				des_ctx->dc_iv = tmp64;
1437 			}
1438 		}
1439 
1440 		des_ctx->dc_lastp = (uint8_t *)&des_ctx->dc_iv;
1441 		des_ctx->dc_flags |= DES_CBC_MODE;
1442 	}
1443 	des_ctx->dc_keysched = keysched;
1444 
1445 /* EXPORT DELETE END */
1446 
1447 	return (rv);
1448 }
1449