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