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