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