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