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